Page MenuHomeFreeBSD

D19622.id57839.diff
No OneTemporary

D19622.id57839.diff

Index: sys/netinet/ip_reass.c
===================================================================
--- sys/netinet/ip_reass.c
+++ sys/netinet/ip_reass.c
@@ -47,7 +47,10 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_var.h>
#include <net/rss_config.h>
#include <net/netisr.h>
#include <net/vnet.h>
@@ -181,6 +184,7 @@
struct ip *ip;
struct mbuf *p, *q, *nq, *t;
struct ipq *fp;
+ struct ifnet *srcifp;
struct ipqhead *head;
int i, hlen, next, tmpmax;
u_int8_t ecn, ecn0;
@@ -241,6 +245,11 @@
}
/*
+ * Store receive network interface pointer for later.
+ */
+ srcifp = m->m_pkthdr.rcvif;
+
+ /*
* Attempt reassembly; if it succeeds, proceed.
* ip_reass() will return a different mbuf.
*/
@@ -490,8 +499,11 @@
m->m_len += (ip->ip_hl << 2);
m->m_data -= (ip->ip_hl << 2);
/* some debugging cruft by sklower, below, will go away soon */
- if (m->m_flags & M_PKTHDR) /* XXX this should be done elsewhere */
+ if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
m_fixhdr(m);
+ /* set valid receive interface pointer */
+ m->m_pkthdr.rcvif = srcifp;
+ }
IPSTAT_INC(ips_reassembled);
IPQ_UNLOCK(hash);
@@ -607,7 +619,43 @@
}
}
+/*
+ * Drain off all datagram fragments belonging to
+ * the given network interface.
+ */
+static void
+ipreass_cleanup(void *arg __unused, struct ifnet *ifp)
+{
+ struct ipq *fp, *temp;
+ struct mbuf *m;
+ int i;
+
+ KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+
#ifdef VIMAGE
+ if (!vnet_is_running(ifp->if_vnet)) {
+ /* the IPv4 reassembly hash is destroyed */
+ return;
+ }
+#endif
+ CURVNET_SET_QUIET(ifp->if_vnet);
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ IPQ_LOCK(i);
+ /* Scan fragment list. */
+ TAILQ_FOREACH_SAFE(fp, &V_ipq[i].head, ipq_list, temp) {
+ for (m = fp->ipq_frags; m != NULL; m = m->m_nextpkt) {
+ /* clear no longer valid rcvif pointer */
+ if (m->m_pkthdr.rcvif == ifp)
+ m->m_pkthdr.rcvif = NULL;
+ }
+ }
+ IPQ_UNLOCK(i);
+ }
+ CURVNET_RESTORE();
+}
+EVENTHANDLER_DEFINE(ifnet_departure_event, ipreass_cleanup, NULL, 0);
+
+#ifdef VIMAGE
/*
* Destroy IP reassembly structures.
*/
Index: sys/netinet6/frag6.c
===================================================================
--- sys/netinet6/frag6.c
+++ sys/netinet6/frag6.c
@@ -223,6 +223,7 @@
sizeof(ip6f->ip6f_ident)) / sizeof(uint32_t)];
uint32_t hash, *hashkeyp;
struct ifnet *dstifp;
+ struct ifnet *srcifp;
u_int8_t ecn, ecn0;
#ifdef RSS
struct m_tag *mtag;
@@ -243,6 +244,11 @@
return (IPPROTO_DONE);
#endif
+ /*
+ * Store receive network interface pointer for later.
+ */
+ srcifp = m->m_pkthdr.rcvif;
+
dstifp = NULL;
/* find the destination interface of the packet. */
ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
@@ -432,6 +438,9 @@
frag6_deq(af6, hash);
free(af6, M_FTABLE);
+ /* set valid receive interface pointer */
+ merr->m_pkthdr.rcvif = srcifp;
+
/* adjust pointer. */
ip6err = mtod(merr, struct ip6_hdr *);
@@ -683,6 +692,8 @@
for (t = m; t; t = t->m_next)
plen += t->m_len;
m->m_pkthdr.len = plen;
+ /* set valid receive interface pointer */
+ m->m_pkthdr.rcvif = srcifp;
}
#ifdef RSS
@@ -749,7 +760,7 @@
* Return ICMP time exceeded error for the 1st fragment.
* Just free other fragments.
*/
- if (af6->ip6af_off == 0) {
+ if (af6->ip6af_off == 0 && m->m_pkthdr.rcvif != NULL) {
struct ip6_hdr *ip6;
/* adjust pointer */
@@ -941,6 +952,49 @@
VNET_LIST_RUNLOCK_NOSLEEP();
}
+/*
+ * Drain off all datagram fragments belonging to
+ * the given network interface.
+ */
+static void
+frag6_cleanup(void *arg __unused, struct ifnet *ifp)
+{
+ struct ip6q *q6, *q6n, *head;
+ struct ip6asfrag *af6;
+ struct mbuf *m;
+ int i;
+
+ KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+
+#ifdef VIMAGE
+ if (!vnet_is_running(ifp->if_vnet)) {
+ /* the IPv6 reassembly hash is destroyed */
+ return;
+ }
+#endif
+ CURVNET_SET_QUIET(ifp->if_vnet);
+ for (i = 0; i < IP6REASS_NHASH; i++) {
+ IP6Q_LOCK(i);
+ head = IP6Q_HEAD(i);
+ /* Scan fragment list. */
+ for (q6 = head->ip6q_next; q6 != head; q6 = q6n) {
+ q6n = q6->ip6q_next;
+
+ for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
+ af6 = af6->ip6af_down) {
+ m = IP6_REASS_MBUF(af6);
+
+ /* clear no longer valid rcvif pointer */
+ if (m->m_pkthdr.rcvif == ifp)
+ m->m_pkthdr.rcvif = NULL;
+ }
+ }
+ IP6Q_UNLOCK(i);
+ }
+ CURVNET_RESTORE();
+}
+EVENTHANDLER_DEFINE(ifnet_departure_event, frag6_cleanup, NULL, 0);
+
int
ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
{

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 13, 2:54 AM (10 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33919252
Default Alt Text
D19622.id57839.diff (4 KB)

Event Timeline