Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107153717
D31391.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D31391.diff
View Options
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1145,6 +1145,44 @@
}
#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 @@
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 @@
* 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.h b/sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -376,10 +376,8 @@
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.c b/sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1923,7 +1923,6 @@
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 @@
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 @@
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 @@
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_llinfo_setstate(ln, ND6_LLINFO_DELAY);
}
+
+ return (chain);
}
int
@@ -2435,19 +2435,27 @@
}
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_nbr.c b/sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -623,7 +623,6 @@
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 @@
* 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();
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 11, 10:54 PM (20 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15758624
Default Alt Text
D31391.diff (5 KB)
Attached To
Mode
D31391: [lltable] Use lltable calculated header when sending lle holdchain after successful lle resolution.
Attached
Detach File
Event Timeline
Log In to Comment