git: 0ea561762ba5 - stable/13 - Use lltable calculated header when sending lle holdchain after successful lle resolution.

Alexander V. Chernikov melifaro at FreeBSD.org
Tue Sep 7 21:12:52 UTC 2021


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 at FreeBSD.org>
AuthorDate: 2021-08-02 23:16:48 +0000
Commit:     Alexander V. Chernikov <melifaro at 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();


More information about the dev-commits-src-branches mailing list