* Unify lle table dump/prefix removal code.
* Rename lla_XXX -> lltable_XXX_lle to reduce number of name prefixes used by lltable code.
This commit is contained in:
parent
5d14e4cd76
commit
ce313fdd71
@ -72,8 +72,33 @@ struct rwlock lltable_rwlock;
|
||||
RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
|
||||
|
||||
/*
|
||||
* Dump arp state for a specific address family.
|
||||
* Dump lle state for a specific address family.
|
||||
*/
|
||||
static int
|
||||
lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
|
||||
{
|
||||
struct llentry *lle;
|
||||
int i, error;
|
||||
|
||||
LLTABLE_LOCK_ASSERT();
|
||||
|
||||
if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
|
||||
return (0);
|
||||
error = 0;
|
||||
|
||||
IF_AFDATA_CFG_RLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
|
||||
error = llt->llt_dump_entry(llt, lle, wr);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
IF_AFDATA_CFG_RUNLOCK(llt->llt_ifp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
|
||||
{
|
||||
@ -83,7 +108,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
|
||||
LLTABLE_RLOCK();
|
||||
SLIST_FOREACH(llt, &V_lltables, llt_link) {
|
||||
if (llt->llt_af == af) {
|
||||
error = llt->llt_dump(llt, wr);
|
||||
error = lltable_dump_af(llt, wr);
|
||||
if (error != 0)
|
||||
goto done;
|
||||
}
|
||||
@ -186,12 +211,12 @@ llentry_alloc(struct ifnet *ifp, struct lltable *lt,
|
||||
struct llentry *la;
|
||||
|
||||
IF_AFDATA_RLOCK(ifp);
|
||||
la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
|
||||
la = lt->llt_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
if ((la == NULL) &&
|
||||
(ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
la = lla_create(lt, 0, (struct sockaddr *)dst);
|
||||
la = lt->llt_create(lt, 0, (struct sockaddr *)dst);
|
||||
if (la != NULL) {
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_link(lt, la);
|
||||
@ -229,10 +254,7 @@ lltable_free(struct lltable *llt)
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
LLE_WLOCK(lle);
|
||||
if (callout_stop(&lle->la_timer)) {
|
||||
LLE_REMREF(lle);
|
||||
lle->la_flags &= ~LLE_CALLOUTREF;
|
||||
}
|
||||
llt->llt_stop_timers(lle);
|
||||
LIST_INSERT_HEAD(&dchain, lle, lle_chain);
|
||||
}
|
||||
}
|
||||
@ -246,6 +268,33 @@ lltable_free(struct lltable *llt)
|
||||
free(llt, M_LLTABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
lltable_prefix_free_af(struct lltable *llt, const struct sockaddr *prefix,
|
||||
const struct sockaddr *mask, u_int flags)
|
||||
{
|
||||
struct llentries dchain;
|
||||
struct llentry *lle, *next;
|
||||
int i;
|
||||
|
||||
LIST_INIT(&dchain);
|
||||
IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
if (llt->llt_match_prefix(prefix, mask, flags, lle)) {
|
||||
LLE_WLOCK(lle);
|
||||
llt->llt_stop_timers(lle);
|
||||
LIST_INSERT_HEAD(&dchain, lle, lle_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
|
||||
llentries_unlink(&dchain);
|
||||
IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
|
||||
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
|
||||
llentry_free(lle);
|
||||
IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
lltable_drain(int af)
|
||||
@ -285,7 +334,7 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask,
|
||||
if (llt->llt_af != af)
|
||||
continue;
|
||||
|
||||
llt->llt_prefix_free(llt, prefix, mask, flags);
|
||||
lltable_prefix_free_af(llt, prefix, mask, flags);
|
||||
}
|
||||
LLTABLE_RUNLOCK();
|
||||
}
|
||||
@ -356,7 +405,7 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
|
||||
case RTM_ADD:
|
||||
/* Add static LLE */
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
lle = lla_create(llt, 0, dst);
|
||||
lle = llt->llt_create(llt, 0, dst);
|
||||
if (lle == NULL) {
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
return (ENOMEM);
|
||||
@ -403,7 +452,7 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
|
||||
|
||||
case RTM_DELETE:
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
error = lla_delete(llt, 0, dst);
|
||||
error = (llt->llt_delete(llt, 0, dst));
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
return (error == 0 ? 0 : ENOENT);
|
||||
|
||||
|
@ -153,10 +153,12 @@ typedef struct llentry *(llt_create_t)(struct lltable *, u_int flags,
|
||||
const struct sockaddr *l3addr);
|
||||
typedef int (llt_delete_t)(struct lltable *, u_int flags,
|
||||
const struct sockaddr *l3addr);
|
||||
typedef void (llt_prefix_free_t)(struct lltable *,
|
||||
const struct sockaddr *prefix, const struct sockaddr *mask, u_int flags);
|
||||
typedef int (llt_dump_t)(struct lltable *, struct sysctl_req *);
|
||||
typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *,
|
||||
struct sysctl_req *);
|
||||
typedef uint32_t (llt_hash_t)(const struct llentry *);
|
||||
typedef int (llt_match_prefix_t)(const struct sockaddr *,
|
||||
const struct sockaddr *, u_int, struct llentry *);
|
||||
typedef void (llt_stop_timers_t)(struct llentry *lle);
|
||||
|
||||
struct lltable {
|
||||
SLIST_ENTRY(lltable) llt_link;
|
||||
@ -167,9 +169,10 @@ struct lltable {
|
||||
llt_lookup_t *llt_lookup;
|
||||
llt_create_t *llt_create;
|
||||
llt_delete_t *llt_delete;
|
||||
llt_prefix_free_t *llt_prefix_free;
|
||||
llt_dump_t *llt_dump;
|
||||
llt_dump_entry_t *llt_dump_entry;
|
||||
llt_hash_t *llt_hash;
|
||||
llt_match_prefix_t *llt_match_prefix;
|
||||
llt_stop_timers_t *llt_stop_timers;
|
||||
};
|
||||
|
||||
MALLOC_DECLARE(M_LLTABLE);
|
||||
@ -216,21 +219,24 @@ struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
|
||||
* Generic link layer address lookup function.
|
||||
*/
|
||||
static __inline struct llentry *
|
||||
lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
|
||||
lltable_lookup_lle(struct lltable *llt, u_int flags,
|
||||
const struct sockaddr *l3addr)
|
||||
{
|
||||
|
||||
return llt->llt_lookup(llt, flags, l3addr);
|
||||
}
|
||||
|
||||
static __inline struct llentry *
|
||||
lla_create(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
|
||||
lltable_create_lle(struct lltable *llt, u_int flags,
|
||||
const struct sockaddr *l3addr)
|
||||
{
|
||||
|
||||
return llt->llt_create(llt, flags, l3addr);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
lla_delete(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
|
||||
lltable_delete_lle(struct lltable *llt, u_int flags,
|
||||
const struct sockaddr *l3addr)
|
||||
{
|
||||
|
||||
return llt->llt_delete(llt, flags, l3addr);
|
||||
|
@ -699,7 +699,8 @@ fib6_storelladdr(struct ifnet *ifp, struct in6_addr *dst, int mm_flags,
|
||||
* the entry should have been created in nd6_store_lladdr
|
||||
*/
|
||||
IF_AFDATA_RUN_RLOCK(ifp);
|
||||
ln = lla_lookup(LLTABLE6(ifp), LLE_UNLOCKED, (struct sockaddr *)&dst_sa);
|
||||
ln = lltable_lookup_lle(LLTABLE6(ifp), LLE_UNLOCKED,
|
||||
(struct sockaddr *)&dst_sa);
|
||||
|
||||
/*
|
||||
* Perform fast path for the following cases:
|
||||
|
@ -164,7 +164,8 @@ arp_ifscrub(struct ifnet *ifp, uint32_t addr)
|
||||
addr4.sin_family = AF_INET;
|
||||
addr4.sin_addr.s_addr = addr;
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
lla_delete(LLTABLE(ifp), LLE_IFADDR, (struct sockaddr *)&addr4);
|
||||
lltable_delete_lle(LLTABLE(ifp), LLE_IFADDR,
|
||||
(struct sockaddr *)&addr4);
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
}
|
||||
#endif
|
||||
@ -258,6 +259,11 @@ arptimer(void *arg)
|
||||
lle->la_flags &= ~LLE_CALLOUTREF;
|
||||
}
|
||||
|
||||
/* Unlink entry */
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_unlink(lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
|
||||
pkts_dropped = llentry_free(lle);
|
||||
ARPSTAT_ADD(dropped, pkts_dropped);
|
||||
|
||||
@ -373,7 +379,7 @@ arpresolve_fast(struct ifnet *ifp, struct in_addr dst, u_int mflags,
|
||||
sa_dst = (const struct sockaddr *)&sin;
|
||||
|
||||
IF_AFDATA_RUN_RLOCK(ifp);
|
||||
la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, sa_dst);
|
||||
la = lltable_lookup_lle(LLTABLE(ifp), LLE_UNLOCKED, sa_dst);
|
||||
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
|
||||
/* Entry found, let's copy lle info */
|
||||
bcopy(&la->ll_addr, dst_addr, ifp->if_addrlen);
|
||||
@ -458,7 +464,7 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
|
||||
}
|
||||
|
||||
IF_AFDATA_RUN_RLOCK(ifp);
|
||||
la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, dst);
|
||||
la = lltable_lookup_lle(LLTABLE(ifp), LLE_UNLOCKED, dst);
|
||||
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
|
||||
/* Entry found, let's copy lle info */
|
||||
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
|
||||
@ -487,12 +493,12 @@ arpresolve_slow(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
||||
*lle = NULL;
|
||||
|
||||
IF_AFDATA_RLOCK(ifp);
|
||||
la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
|
||||
la = lltable_lookup_lle(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
|
||||
create = 1;
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
la = lla_create(LLTABLE(ifp), 0, dst);
|
||||
la = lltable_create_lle(LLTABLE(ifp), 0, dst);
|
||||
if (la != NULL) {
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_link(LLTABLE(ifp), la);
|
||||
@ -858,9 +864,11 @@ in_arpinput(struct mbuf *m)
|
||||
flags = LLE_EXCLUSIVE;
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
if (create != 0) {
|
||||
la = lla_create(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
|
||||
la = lltable_create_lle(LLTABLE(ifp), 0,
|
||||
(struct sockaddr *)&sin);
|
||||
} else
|
||||
la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin);
|
||||
la = lltable_lookup_lle(LLTABLE(ifp), flags,
|
||||
(struct sockaddr *)&sin);
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
if (la != NULL) {
|
||||
/* the following is not an error when doing bridging */
|
||||
@ -989,7 +997,8 @@ in_arpinput(struct mbuf *m)
|
||||
|
||||
sin.sin_addr = itaddr;
|
||||
IF_AFDATA_RLOCK(ifp);
|
||||
lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
|
||||
lle = lltable_lookup_lle(LLTABLE(ifp), 0,
|
||||
(struct sockaddr *)&sin);
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
|
||||
if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
|
||||
@ -1093,7 +1102,7 @@ arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
|
||||
* that L2 entry as permanent
|
||||
*/
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
lle = lla_create(LLTABLE(ifp), LLE_IFADDR | LLE_STATIC,
|
||||
lle = lltable_create_lle(LLTABLE(ifp), LLE_IFADDR | LLE_STATIC,
|
||||
(struct sockaddr *)IA_SIN(ifa));
|
||||
if (lle != NULL) {
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
|
@ -1035,52 +1035,38 @@ in_lltable_new(const struct sockaddr *l3addr, u_int flags)
|
||||
return (&lle->base);
|
||||
}
|
||||
|
||||
static void
|
||||
in_lltable_stop_timers(struct llentry *lle)
|
||||
{
|
||||
|
||||
LLE_WLOCK_ASSERT(lle);
|
||||
if (callout_stop(&lle->la_timer)) {
|
||||
LLE_REMREF(lle);
|
||||
lle->la_flags &= ~LLE_CALLOUTREF;
|
||||
}
|
||||
}
|
||||
|
||||
#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
|
||||
(((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
|
||||
|
||||
static void
|
||||
in_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
|
||||
const struct sockaddr *mask, u_int flags)
|
||||
static int
|
||||
in_lltable_match_prefix(const struct sockaddr *prefix,
|
||||
const struct sockaddr *mask, u_int flags, struct llentry *lle)
|
||||
{
|
||||
const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
|
||||
const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
|
||||
struct llentry *lle, *next;
|
||||
struct llentries dchain;
|
||||
int i;
|
||||
size_t pkts_dropped;
|
||||
|
||||
LIST_INIT(&dchain);
|
||||
IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
/*
|
||||
* (flags & LLE_STATIC) means deleting all entries
|
||||
* including static ARP entries.
|
||||
*/
|
||||
if (IN_ARE_MASKED_ADDR_EQUAL(satosin(L3_ADDR(lle)),
|
||||
pfx, msk) && ((flags & LLE_STATIC) ||
|
||||
!(lle->la_flags & LLE_STATIC))) {
|
||||
LLE_WLOCK(lle);
|
||||
if (callout_stop(&lle->la_timer)) {
|
||||
LLE_REMREF(lle);
|
||||
lle->la_flags &= ~LLE_CALLOUTREF;
|
||||
}
|
||||
LIST_INSERT_HEAD(&dchain, lle, lle_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Unlink chain */
|
||||
IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
|
||||
llentries_unlink(&dchain);
|
||||
IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
|
||||
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
|
||||
pkts_dropped = llentry_free(lle);
|
||||
ARPSTAT_ADD(dropped, pkts_dropped);
|
||||
}
|
||||
IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
|
||||
/*
|
||||
* (flags & LLE_STATIC) means deleting all entries
|
||||
* including static ARP entries.
|
||||
*/
|
||||
if (IN_ARE_MASKED_ADDR_EQUAL(satosin(L3_ADDR(lle)), pfx, msk) &&
|
||||
((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
|
||||
{
|
||||
@ -1265,29 +1251,22 @@ in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3add
|
||||
}
|
||||
|
||||
static int
|
||||
in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
struct sysctl_req *wr)
|
||||
{
|
||||
#define SIN(lle) ((struct sockaddr_in *) L3_ADDR(lle))
|
||||
struct ifnet *ifp = llt->llt_ifp;
|
||||
struct llentry *lle;
|
||||
/* XXX stack use */
|
||||
struct {
|
||||
struct rt_msghdr rtm;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_dl sdl;
|
||||
} arpc;
|
||||
int error, i;
|
||||
|
||||
LLTABLE_LOCK_ASSERT();
|
||||
|
||||
error = 0;
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
|
||||
struct sockaddr_dl *sdl;
|
||||
struct sockaddr_dl *sdl;
|
||||
int error;
|
||||
|
||||
/* Skip if jailed and not a valid IP of the prison. */
|
||||
if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
|
||||
continue;
|
||||
return (0);
|
||||
/*
|
||||
* produce a msg made of:
|
||||
* struct rt_msghdr;
|
||||
@ -1302,7 +1281,7 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
arpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
|
||||
arpc.sin.sin_family = AF_INET;
|
||||
arpc.sin.sin_len = sizeof(arpc.sin);
|
||||
arpc.sin.sin_addr.s_addr = SIN(lle)->sin_addr.s_addr;
|
||||
arpc.sin.sin_addr.s_addr = lle->r_l3addr.addr4.s_addr;
|
||||
|
||||
/* publish */
|
||||
if (lle->la_flags & LLE_PUB)
|
||||
@ -1328,12 +1307,8 @@ in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
arpc.rtm.rtm_flags |= RTF_STATIC;
|
||||
arpc.rtm.rtm_index = ifp->if_index;
|
||||
error = SYSCTL_OUT(wr, &arpc, sizeof(arpc));
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
#undef SIN
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
void *
|
||||
@ -1346,12 +1321,13 @@ in_domifattach(struct ifnet *ifp)
|
||||
|
||||
llt = lltable_init(ifp, AF_INET);
|
||||
if (llt != NULL) {
|
||||
llt->llt_prefix_free = in_lltable_prefix_free;
|
||||
llt->llt_lookup = in_lltable_lookup;
|
||||
llt->llt_create = in_lltable_create;
|
||||
llt->llt_delete = in_lltable_delete;
|
||||
llt->llt_dump = in_lltable_dump;
|
||||
llt->llt_dump_entry = in_lltable_dump_entry;
|
||||
llt->llt_hash = in_lltable_hash;
|
||||
llt->llt_stop_timers = in_lltable_stop_timers;
|
||||
llt->llt_match_prefix = in_lltable_match_prefix;
|
||||
}
|
||||
ii->ii_llt = llt;
|
||||
|
||||
|
@ -459,7 +459,7 @@ toe_nd6_resolve(struct ifnet *ifp, struct sockaddr *sa, uint8_t *lladdr)
|
||||
|
||||
restart:
|
||||
IF_AFDATA_RLOCK(ifp);
|
||||
lle = lla_lookup(LLTABLE6(ifp), flags, sa);
|
||||
lle = lltable_lookup_lle(LLTABLE6(ifp), flags, sa);
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
if (lle == NULL) {
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
|
@ -2088,43 +2088,29 @@ in6_lltable_new(const struct sockaddr *l3addr, u_int flags)
|
||||
}
|
||||
|
||||
static void
|
||||
in6_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
|
||||
const struct sockaddr *mask, u_int flags)
|
||||
in6_lltable_stop_timers(struct llentry *lle)
|
||||
{
|
||||
|
||||
LLE_WLOCK_ASSERT(lle);
|
||||
if (callout_stop(&lle->la_timer)) {
|
||||
LLE_REMREF(lle);
|
||||
lle->la_flags &= ~LLE_CALLOUTREF;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
in6_lltable_match_prefix(const struct sockaddr *prefix,
|
||||
const struct sockaddr *mask, u_int flags, struct llentry *lle)
|
||||
{
|
||||
const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
|
||||
const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
|
||||
struct llentries dchain;
|
||||
struct llentry *lle, *next;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* (flags & LLE_STATIC) means deleting all entries
|
||||
* including static ND6 entries.
|
||||
*/
|
||||
LIST_INIT(&dchain);
|
||||
IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
if (IN6_ARE_MASKED_ADDR_EQUAL(
|
||||
&satosin6(L3_ADDR(lle))->sin6_addr,
|
||||
&pfx->sin6_addr, &msk->sin6_addr) &&
|
||||
((flags & LLE_STATIC) ||
|
||||
!(lle->la_flags & LLE_STATIC))) {
|
||||
LLE_WLOCK(lle);
|
||||
if (callout_stop(&lle->la_timer)) {
|
||||
LLE_REMREF(lle);
|
||||
lle->la_flags &= ~LLE_CALLOUTREF;
|
||||
}
|
||||
LIST_INSERT_HEAD(&dchain, lle, lle_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
|
||||
llentries_unlink(&dchain);
|
||||
IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
|
||||
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
|
||||
llentry_free(lle);
|
||||
IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
|
||||
if (IN6_ARE_MASKED_ADDR_EQUAL(&satosin6(L3_ADDR(lle))->sin6_addr,
|
||||
&pfx->sin6_addr, &msk->sin6_addr) &&
|
||||
((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2296,10 +2282,10 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
|
||||
}
|
||||
|
||||
static int
|
||||
in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
struct sysctl_req *wr)
|
||||
{
|
||||
struct ifnet *ifp = llt->llt_ifp;
|
||||
struct llentry *lle;
|
||||
/* XXX stack use */
|
||||
struct {
|
||||
struct rt_msghdr rtm;
|
||||
@ -2312,24 +2298,15 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
#endif
|
||||
struct sockaddr_dl sdl;
|
||||
} ndpc;
|
||||
int i, error;
|
||||
|
||||
if (ifp->if_flags & IFF_LOOPBACK)
|
||||
return 0;
|
||||
|
||||
LLTABLE_LOCK_ASSERT();
|
||||
|
||||
error = 0;
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
|
||||
struct sockaddr_dl *sdl;
|
||||
struct sockaddr_dl *sdl;
|
||||
int error;
|
||||
|
||||
/* skip invalid entries */
|
||||
if ((lle->la_flags & LLE_VALID) == 0)
|
||||
continue;
|
||||
return (0);
|
||||
/* Skip if jailed and not a valid IP of the prison. */
|
||||
if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
|
||||
continue;
|
||||
return (0);
|
||||
/*
|
||||
* produce a msg made of:
|
||||
* struct rt_msghdr;
|
||||
@ -2366,11 +2343,8 @@ in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
|
||||
ndpc.rtm.rtm_flags |= RTF_STATIC;
|
||||
ndpc.rtm.rtm_index = ifp->if_index;
|
||||
error = SYSCTL_OUT(wr, &ndpc, sizeof(ndpc));
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
void *
|
||||
@ -2403,12 +2377,13 @@ in6_domifattach(struct ifnet *ifp)
|
||||
ext->scope6_id = scope6_ifattach(ifp);
|
||||
ext->lltable = lltable_init(ifp, AF_INET6);
|
||||
if (ext->lltable != NULL) {
|
||||
ext->lltable->llt_prefix_free = in6_lltable_prefix_free;
|
||||
ext->lltable->llt_lookup = in6_lltable_lookup;
|
||||
ext->lltable->llt_create = in6_lltable_create;
|
||||
ext->lltable->llt_delete = in6_lltable_delete;
|
||||
ext->lltable->llt_dump = in6_lltable_dump;
|
||||
ext->lltable->llt_dump_entry = in6_lltable_dump_entry;
|
||||
ext->lltable->llt_hash = in6_lltable_hash;
|
||||
ext->lltable->llt_stop_timers = in6_lltable_stop_timers;
|
||||
ext->lltable->llt_match_prefix = in6_lltable_match_prefix;
|
||||
}
|
||||
|
||||
ext->mld_ifinfo = mld_domifattach(ifp);
|
||||
|
@ -860,7 +860,8 @@ nd6_lookup(struct in6_addr *addr6, int flags, struct ifnet *ifp)
|
||||
*/
|
||||
|
||||
llflags = (flags & ND6_EXCLUSIVE) ? LLE_EXCLUSIVE : 0;
|
||||
ln = lla_lookup(LLTABLE6(ifp), llflags, (struct sockaddr *)&sin6);
|
||||
ln = lltable_lookup_lle(LLTABLE6(ifp), llflags,
|
||||
(struct sockaddr *)&sin6);
|
||||
|
||||
return (ln);
|
||||
}
|
||||
@ -882,7 +883,7 @@ nd6_create(struct in6_addr *addr6, int flags, struct ifnet *ifp)
|
||||
|
||||
IF_AFDATA_CFG_WLOCK_ASSERT(ifp);
|
||||
|
||||
ln = lla_create(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6);
|
||||
ln = lltable_create_lle(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6);
|
||||
if (ln != NULL) {
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
ln->ln_state = ND6_LLINFO_NOSTATE;
|
||||
@ -2269,7 +2270,7 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
|
||||
|
||||
ifp = ia->ia_ifa.ifa_ifp;
|
||||
IF_AFDATA_CFG_WLOCK(ifp);
|
||||
ln = lla_create(LLTABLE6(ifp), LLE_IFADDR,
|
||||
ln = lltable_create_lle(LLTABLE6(ifp), LLE_IFADDR,
|
||||
(struct sockaddr *)&ia->ia_addr);
|
||||
if (ln != NULL) {
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
@ -2366,7 +2367,7 @@ nd6_storelladdr(struct ifnet *ifp, struct mbuf *m,
|
||||
* the entry should have been created in nd6_store_lladdr
|
||||
*/
|
||||
IF_AFDATA_RLOCK(ifp);
|
||||
ln = lla_lookup(LLTABLE6(ifp), 0, dst);
|
||||
ln = lltable_lookup_lle(LLTABLE6(ifp), 0, dst);
|
||||
IF_AFDATA_RUNLOCK(ifp);
|
||||
if ((ln == NULL) || !(ln->la_flags & LLE_VALID)) {
|
||||
if (ln != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user