Date: Tue, 7 Sep 2021 21:12:47 GMT From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 0ea561762ba5 - stable/13 - Use lltable calculated header when sending lle holdchain after successful lle resolution. Message-ID: <202109072112.187LClQe023906@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=0ea561762ba5cf2cc904b9a29518b305c034d354 commit 0ea561762ba5cf2cc904b9a29518b305c034d354 Author: Alexander V. Chernikov <melifaro@FreeBSD.org> AuthorDate: 2021-08-02 23:16:48 +0000 Commit: Alexander V. Chernikov <melifaro@FreeBSD.org> CommitDate: 2021-09-07 21:02:58 +0000 Use lltable calculated header when sending lle holdchain after successful lle resolution. Subscribers: imp, ae, bz Differential Revision: https://reviews.freebsd.org/D31391 (cherry picked from commit 8482aa77481a1576df7a19dbeaccb91243fbb2a3) --- sys/netinet/if_ether.c | 55 ++++++++++++++++++++++++++++++++++++++------------ sys/netinet6/nd6.c | 30 +++++++++++++++++---------- sys/netinet6/nd6.h | 6 ++---- sys/netinet6/nd6_nbr.c | 9 +++------ 4 files changed, 66 insertions(+), 34 deletions(-) diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 3eb9d7210afb..2f92d623feeb 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1145,6 +1145,44 @@ drop: } #endif +static struct mbuf * +arp_grab_holdchain(struct llentry *la) +{ + struct mbuf *chain; + + LLE_WLOCK_ASSERT(la); + + chain = la->la_hold; + la->la_hold = NULL; + la->la_numheld = 0; + + return (chain); +} + +static void +arp_flush_holdchain(struct ifnet *ifp, struct llentry *la, struct mbuf *chain) +{ + struct mbuf *m_hold, *m_hold_next; + struct sockaddr_in sin; + + NET_EPOCH_ASSERT(); + + struct route ro = { + .ro_prepend = la->r_linkdata, + .ro_plen = la->r_hdrlen, + }; + + lltable_fill_sa_entry(la, (struct sockaddr *)&sin); + + for (m_hold = chain; m_hold != NULL; m_hold = m_hold_next) { + m_hold_next = m_hold->m_nextpkt; + m_hold->m_nextpkt = NULL; + /* Avoid confusing lower layers. */ + m_clrprotoflags(m_hold); + (*ifp->if_output)(ifp, m_hold, (struct sockaddr *)&sin, &ro); + } +} + /* * Checks received arp data against existing @la. * Updates lle state/performs notification if necessary. @@ -1153,8 +1191,6 @@ static void arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp, int bridged, struct llentry *la) { - struct sockaddr sa; - struct mbuf *m_hold, *m_hold_next; uint8_t linkhdr[LLE_MAX_LINKHDR]; size_t linkhdrsize; int lladdr_off; @@ -1227,18 +1263,11 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp * output routine. */ if (la->la_hold != NULL) { - m_hold = la->la_hold; - la->la_hold = NULL; - la->la_numheld = 0; - lltable_fill_sa_entry(la, &sa); + struct mbuf *chain; + + chain = arp_grab_holdchain(la); LLE_WUNLOCK(la); - for (; m_hold != NULL; m_hold = m_hold_next) { - m_hold_next = m_hold->m_nextpkt; - m_hold->m_nextpkt = NULL; - /* Avoid confusing lower layers. */ - m_clrprotoflags(m_hold); - (*ifp->if_output)(ifp, m_hold, &sa, NULL); - } + arp_flush_holdchain(ifp, la, chain); } else LLE_WUNLOCK(la); } diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 7ae77c5c6604..143629d44fdb 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1923,7 +1923,6 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, int llchange; int flags; uint16_t router = 0; - struct sockaddr_in6 sin6; struct mbuf *chain = NULL; u_char linkhdr[LLE_MAX_LINKHDR]; size_t linkhdrsize; @@ -2044,7 +2043,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); if (ln->la_hold != NULL) - nd6_grab_holdchain(ln, &chain, &sin6); + chain = nd6_grab_holdchain(ln); } /* Calculates new router status */ @@ -2062,7 +2061,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, LLE_RUNLOCK(ln); if (chain != NULL) - nd6_flush_holdchain(ifp, chain, &sin6); + nd6_flush_holdchain(ifp, ln, chain); /* * When the link-layer address of a router changes, select the @@ -2119,16 +2118,15 @@ nd6_slowtimo(void *arg) CURVNET_RESTORE(); } -void -nd6_grab_holdchain(struct llentry *ln, struct mbuf **chain, - struct sockaddr_in6 *sin6) +struct mbuf * +nd6_grab_holdchain(struct llentry *ln) { + struct mbuf *chain; LLE_WLOCK_ASSERT(ln); - *chain = ln->la_hold; + chain = ln->la_hold; ln->la_hold = NULL; - lltable_fill_sa_entry(ln, (struct sockaddr *)sin6); if (ln->ln_state == ND6_LLINFO_STALE) { /* @@ -2142,6 +2140,8 @@ nd6_grab_holdchain(struct llentry *ln, struct mbuf **chain, */ nd6_llinfo_setstate(ln, ND6_LLINFO_DELAY); } + + return (chain); } int @@ -2435,19 +2435,27 @@ nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst, } int -nd6_flush_holdchain(struct ifnet *ifp, struct mbuf *chain, - struct sockaddr_in6 *dst) +nd6_flush_holdchain(struct ifnet *ifp, struct llentry *lle, struct mbuf *chain) { struct mbuf *m, *m_head; + struct sockaddr_in6 dst6; int error = 0; + NET_EPOCH_ASSERT(); + + struct route_in6 ro = { + .ro_prepend = lle->r_linkdata, + .ro_plen = lle->r_hdrlen, + }; + + lltable_fill_sa_entry(lle, (struct sockaddr *)&dst6); m_head = chain; while (m_head) { m = m_head; m_head = m_head->m_nextpkt; m->m_nextpkt = NULL; - error = nd6_output_ifp(ifp, ifp, m, dst, NULL); + error = nd6_output_ifp(ifp, ifp, m, &dst6, (struct route *)&ro); } /* diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index a64c786efcc8..ee53acce840a 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -376,10 +376,8 @@ int nd6_resolve(struct ifnet *, int, struct mbuf *, int nd6_ioctl(u_long, caddr_t, struct ifnet *); void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, char *, int, int, int); -void nd6_grab_holdchain(struct llentry *, struct mbuf **, - struct sockaddr_in6 *); -int nd6_flush_holdchain(struct ifnet *, struct mbuf *, - struct sockaddr_in6 *); +struct mbuf *nd6_grab_holdchain(struct llentry *); +int nd6_flush_holdchain(struct ifnet *, struct llentry *, struct mbuf *); int nd6_add_ifa_lle(struct in6_ifaddr *); void nd6_rem_ifa_lle(struct in6_ifaddr *, int); int nd6_output_ifp(struct ifnet *, struct ifnet *, struct mbuf *, diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 42e901bdd2a4..0f18a38c37a1 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -623,7 +623,6 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) struct mbuf *chain; struct nd_neighbor_advert *nd_na; struct in6_addr daddr6, taddr6; - struct sockaddr_in6 sin6; union nd_opts ndopts; u_char linkhdr[LLE_MAX_LINKHDR]; char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; @@ -899,16 +898,14 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) * rt->rt_flags &= ~RTF_REJECT; */ ln->la_asked = 0; - if (ln->la_hold != NULL) { - memset(&sin6, 0, sizeof(sin6)); - nd6_grab_holdchain(ln, &chain, &sin6); - } + if (ln->la_hold != NULL) + chain = nd6_grab_holdchain(ln); freeit: if (ln != NULL) LLE_WUNLOCK(ln); if (chain != NULL) - nd6_flush_holdchain(ifp, chain, &sin6); + nd6_flush_holdchain(ifp, ln, chain); if (checklink) pfxlist_onlink_check();
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109072112.187LClQe023906>