[lltable] Add per-family lltable getters.

Introduce a new function, lltable_get(), to retrieve lltable pointer
 for the specified interface and family.
Use it to avoid all-iftable list traversal when adding or deleting
 ARP/ND records.

Differential Revision: https://reviews.freebsd.org/D33660
MFC after:	2 weeks
This commit is contained in:
Alexander V. Chernikov 2021-12-26 12:39:26 +00:00
parent 33812d60b9
commit ff3a85d324
4 changed files with 44 additions and 8 deletions

View File

@ -712,6 +712,22 @@ lltable_unlink(struct lltable *llt)
} }
/*
* Gets interface @ifp lltable for the specified @family
*/
struct lltable *
lltable_get(struct ifnet *ifp, int family)
{
switch (family) {
case AF_INET:
return (in_lltable_get(ifp));
case AF_INET6:
return (in6_lltable_get(ifp));
}
return (NULL);
}
/* /*
* External methods used by lltable consumers * External methods used by lltable consumers
*/ */
@ -823,14 +839,8 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
return EINVAL; return EINVAL;
} }
/* XXX linked list may be too expensive */ llt = lltable_get(ifp, dst->sa_family);
LLTABLE_LIST_RLOCK();
SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == dst->sa_family &&
llt->llt_ifp == ifp)
break;
}
LLTABLE_LIST_RUNLOCK();
if (llt == NULL) if (llt == NULL)
return (ESRCH); return (ESRCH);

View File

@ -222,6 +222,10 @@ void lltable_prefix_free(int, struct sockaddr *,
struct sockaddr *, u_int); struct sockaddr *, u_int);
int lltable_sysctl_dumparp(int, struct sysctl_req *); int lltable_sysctl_dumparp(int, struct sysctl_req *);
struct lltable *in_lltable_get(struct ifnet *ifp);
struct lltable *in6_lltable_get(struct ifnet *ifp);
struct lltable *lltable_get(struct ifnet *ifp, int family);
size_t llentry_free(struct llentry *); size_t llentry_free(struct llentry *);
/* helper functions */ /* helper functions */

View File

@ -1704,6 +1704,17 @@ in_lltattach(struct ifnet *ifp)
return (llt); return (llt);
} }
struct lltable *
in_lltable_get(struct ifnet *ifp)
{
struct lltable *llt = NULL;
void *afdata_ptr = ifp->if_afdata[AF_INET];
if (afdata_ptr != NULL)
llt = ((struct in_ifinfo *)afdata_ptr)->ii_llt;
return (llt);
}
void * void *
in_domifattach(struct ifnet *ifp) in_domifattach(struct ifnet *ifp)
{ {

View File

@ -2483,6 +2483,17 @@ in6_lltattach(struct ifnet *ifp)
return (llt); return (llt);
} }
struct lltable *
in6_lltable_get(struct ifnet *ifp)
{
struct lltable *llt = NULL;
void *afdata_ptr = ifp->if_afdata[AF_INET6];
if (afdata_ptr != NULL)
llt = ((struct in6_ifextra *)afdata_ptr)->lltable;
return (llt);
}
void * void *
in6_domifattach(struct ifnet *ifp) in6_domifattach(struct ifnet *ifp)
{ {