git: ff3a85d32411 - main - [lltable] Add per-family lltable getters.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Dec 2021 21:30:32 UTC
The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=ff3a85d32411cdd7894f932b1d3d7ce01ec7a648 commit ff3a85d32411cdd7894f932b1d3d7ce01ec7a648 Author: Alexander V. Chernikov <melifaro@FreeBSD.org> AuthorDate: 2021-12-26 12:39:26 +0000 Commit: Alexander V. Chernikov <melifaro@FreeBSD.org> CommitDate: 2021-12-29 20:57:15 +0000 [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 --- sys/net/if_llatbl.c | 26 ++++++++++++++++++-------- sys/net/if_llatbl.h | 4 ++++ sys/netinet/in.c | 11 +++++++++++ sys/netinet6/in6.c | 11 +++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index e4dfc45705a8..10d555b1bd86 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -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 */ @@ -823,14 +839,8 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) return EINVAL; } - /* XXX linked list may be too expensive */ - 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(); + llt = lltable_get(ifp, dst->sa_family); + if (llt == NULL) return (ESRCH); diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 7ad9d59a1a0e..dfb5e13a9436 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -222,6 +222,10 @@ void lltable_prefix_free(int, struct sockaddr *, struct sockaddr *, u_int); 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 *); /* helper functions */ diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 914ca57dee38..a504f54a026e 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1704,6 +1704,17 @@ in_lltattach(struct ifnet *ifp) 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 * in_domifattach(struct ifnet *ifp) { diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index feee4f3f64a5..3c03c2996d9b 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2483,6 +2483,17 @@ in6_lltattach(struct ifnet *ifp) 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 * in6_domifattach(struct ifnet *ifp) {