Use llt_prepare_static_entry method to prepare valid per-af static entry.

This commit is contained in:
Alexander V. Chernikov 2014-12-07 23:59:44 +00:00
parent 0368226e65
commit 73b52ad896
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/routing/; revision=275587
8 changed files with 65 additions and 24 deletions

View File

@ -440,7 +440,7 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
struct sockaddr *dst = (struct sockaddr *)info->rti_info[RTAX_DST];
struct ifnet *ifp;
struct lltable *llt;
struct llentry *lle;
struct llentry *lle, *lle_tmp;
u_int laflags = 0;
int error;
@ -469,36 +469,37 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
switch (rtm->rtm_type) {
case RTM_ADD:
/* Add static LLE */
IF_AFDATA_CFG_WLOCK(ifp);
lle = llt->llt_create(llt, 0, dst);
if (lle == NULL) {
IF_AFDATA_CFG_WUNLOCK(ifp);
if (lle == NULL)
return (ENOMEM);
}
IF_AFDATA_RUN_WLOCK(ifp);
/* Save initial info to provide to _prepare hook */
bcopy(LLADDR(dl), &lle->ll_addr, ifp->if_addrlen);
if ((rtm->rtm_flags & RTF_ANNOUNCE))
lle->la_flags |= LLE_PUB;
lle->la_flags |= LLE_VALID;
#ifdef INET6
/*
* ND6
*/
if (dst->sa_family == AF_INET6)
lle->ln_state = ND6_LLINFO_REACHABLE;
#endif
/*
* NB: arp and ndp always set (RTF_STATIC | RTF_HOST)
*/
lle->la_expire = rtm->rtm_rmx.rmx_expire;
if (rtm->rtm_rmx.rmx_expire == 0) {
lle->la_flags |= LLE_STATIC;
lle->r_flags |= RLLE_VALID;
lle->la_expire = 0;
} else
lle->la_expire = rtm->rtm_rmx.rmx_expire;
error = llt->llt_prepare_static_entry(llt, lle, info);
if (error != 0) {
LLE_FREE(lle);
return (error);
}
/* Let's try to link new lle to the list */
IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(lle);
/* Check if we already have this lle */
/* XXX: Use LLE_UNLOCKED */
lle_tmp = llt->llt_lookup(llt, LLE_EXCLUSIVE, dst);
if (lle_tmp != NULL) {
IF_AFDATA_CFG_WUNLOCK(ifp);
LLE_WUNLOCK(lle_tmp);
LLE_FREE_LOCKED(lle);
return (EEXIST);
}
IF_AFDATA_RUN_WLOCK(ifp);
llentry_link(llt, lle);
IF_AFDATA_RUN_WUNLOCK(ifp);
laflags = lle->la_flags;

View File

@ -162,6 +162,8 @@ typedef void (llt_clear_entry_t)(struct lltable *, struct llentry *);
typedef void (llt_free_tbl_t)(struct lltable *);
typedef void (llt_link_entry_t)(struct lltable *, struct llentry *);
typedef void (llt_unlink_entry_t)(struct llentry *);
typedef int (llt_prepare_sentry_t)(struct lltable *, struct llentry *,
struct rt_addrinfo *);
typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *);
typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
@ -183,6 +185,7 @@ struct lltable {
llt_foreach_entry_t *llt_foreach_entry;
llt_link_entry_t *llt_link_entry;
llt_unlink_entry_t *llt_unlink_entry;
llt_prepare_sentry_t *llt_prepare_static_entry;
llt_free_tbl_t *llt_free_tbl;
};

View File

@ -268,6 +268,20 @@ arptimer(void *arg)
CURVNET_RESTORE();
}
int
arp_lltable_prepare_static_entry(struct lltable *llt, struct llentry *lle,
struct rt_addrinfo *info)
{
lle->la_flags |= LLE_VALID;
lle->r_flags |= RLLE_VALID;
if (lle->la_expire == 0)
lle->la_flags |= LLE_STATIC;
return (0);
}
/*
* Calback for lltable.
*/

View File

@ -115,6 +115,7 @@ extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
struct lltable;
struct llentry;
struct ifaddr;
struct rt_addrinfo;
int arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, struct llentry **lle);
@ -126,6 +127,8 @@ void arp_ifinit(struct ifnet *, struct ifaddr *);
void arp_ifinit2(struct ifnet *, struct ifaddr *, u_char *);
void arp_ifscrub(struct ifnet *, uint32_t);
void arp_lltable_clear_entry(struct lltable *, struct llentry *);
int arp_lltable_prepare_static_entry(struct lltable *, struct llentry *,
struct rt_addrinfo *);
#endif
#endif

View File

@ -1314,6 +1314,7 @@ in_domifattach(struct ifnet *ifp)
llt->llt_hash = in_lltable_hash;
llt->llt_clear_entry = arp_lltable_clear_entry;
llt->llt_match_prefix = in_lltable_match_prefix;
llt->llt_prepare_static_entry = arp_lltable_prepare_static_entry;
lltable_link(llt);
ii = malloc(sizeof(struct in_ifinfo), M_IFADDR, M_WAITOK|M_ZERO);

View File

@ -2379,6 +2379,7 @@ in6_domifattach(struct ifnet *ifp)
llt->llt_hash = in6_lltable_hash;
llt->llt_clear_entry = nd6_lltable_clear_entry;
llt->llt_match_prefix = in6_lltable_match_prefix;
llt->llt_prepare_static_entry = nd6_lltable_prepare_static_entry;
lltable_link(llt);
ext->lltable = llt;

View File

@ -1095,6 +1095,22 @@ nd6_free(struct llentry *ln, int gc)
llt->llt_clear_entry(ln->lle_tbl, ln);
}
int
nd6_lltable_prepare_static_entry(struct lltable *llt, struct llentry *lle,
struct rt_addrinfo *info)
{
lle->la_flags |= LLE_VALID;
lle->r_flags |= RLLE_VALID;
lle->ln_state = ND6_LLINFO_REACHABLE;
if (lle->la_expire == 0)
lle->la_flags |= LLE_STATIC;
return (0);
}
/*
* Calback for lltable.
*/

View File

@ -421,6 +421,8 @@ void nd6_rem_ifa_lle(struct in6_ifaddr *);
int nd6_storelladdr(struct ifnet *, struct mbuf *,
const struct sockaddr *, u_char *, struct llentry **);
void nd6_lltable_clear_entry(struct lltable *, struct llentry *);
int nd6_lltable_prepare_static_entry(struct lltable *, struct llentry *,
struct rt_addrinfo *);
/* nd6_nbr.c */
void nd6_na_input(struct mbuf *, int, int);