Page MenuHomeFreeBSD

D3563.id8641.diff
No OneTemporary

D3563.id8641.diff

Index: sys/netinet6/frag6.c
===================================================================
--- sys/netinet6/frag6.c
+++ sys/netinet6/frag6.c
@@ -47,6 +47,7 @@
#include <net/if.h>
#include <net/if_var.h>
#include <net/route.h>
+#include <net/netisr.h>
#include <net/vnet.h>
#include <netinet/in.h>
@@ -204,21 +205,42 @@
IP6STAT_INC(ip6s_fragments);
in6_ifstat_inc(dstifp, ifs6_reass_reqd);
- /* offset now points to data portion */
- offset += sizeof(struct ip6_frag);
-
/*
* RFC 6946: Handle "atomic" fragments (offset and m bit set to 0)
* upfront, unrelated to any reassembly. Just skip the fragment header.
*/
if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
+ nxt = ip6f->ip6f_nxt;
+
+ if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0) {
+ IP6STAT_INC(ip6s_fragdropped);
+ in6_ifstat_inc(dstifp, ifs6_reass_fail);
+ m_freem(m);
+ return IPPROTO_DONE;
+ }
+
+ m->m_pkthdr.len -= sizeof(struct ip6_frag);
+
+ /*
+ * Store NXT to the original.
+ */
+ {
+ char *prvnxtp = ip6_get_prevhdr(m, offset); /* XXX */
+ *prvnxtp = nxt;
+ }
+ ip6 = mtod(m, struct ip6_hdr *);
+ ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) -
+ sizeof(struct ip6_frag));
+
/* XXX-BZ we want dedicated counters for this. */
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
- *offp = offset;
- return (ip6f->ip6f_nxt);
+ goto dispatch;
}
+ /* offset now points to data portion */
+ offset += sizeof(struct ip6_frag);
+
IP6Q_LOCK();
/*
@@ -577,18 +599,20 @@
m->m_pkthdr.len = plen;
}
+ IP6Q_UNLOCK();
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
+ dispatch:
+ m->m_pkthdr.PH_loc.thirtytwo[0] = nxt;
+ m->m_pkthdr.PH_loc.thirtytwo[1] = offset;
+
/*
- * Tell launch routine the next header
+ * Queue/dispatch for reprocessing.
*/
+ netisr_dispatch(NETISR_IPV6_DIRECT, m);
- *mp = m;
- *offp = offset;
-
- IP6Q_UNLOCK();
- return nxt;
+ return IPPROTO_DONE;
dropfrag:
IP6Q_UNLOCK();
Index: sys/netinet6/ip6_input.c
===================================================================
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -144,6 +144,24 @@
#endif
};
+#ifdef RSS
+/*
+ * Directly dispatched frames are currently assumed
+ * to have a flowid already calculated.
+ *
+ * It should likely have something that assert it
+ * actually has valid flow details.
+ */
+static struct netisr_handler ip6_direct_nh = {
+ .nh_name = "ip6_direct",
+ .nh_handler = ip6_direct_input,
+ .nh_proto = NETISR_IPV6_DIRECT,
+ .nh_m2cpuid = rss_soft_m2cpuid_v6,
+ .nh_policy = NETISR_POLICY_CPU,
+ .nh_dispatch = NETISR_DISPATCH_HYBRID,
+};
+#endif
+
VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch);
#define V_in6_tmpaddrtimer_ch VNET(in6_tmpaddrtimer_ch)
@@ -222,6 +240,9 @@
}
netisr_register(&ip6_nh);
+#ifdef RSS
+ netisr_register(&ip6_direct_nh);
+#endif
}
/*
@@ -403,6 +424,61 @@
return (1);
}
+#ifdef RSS
+/*
+ * IPv6 direct input routine.
+ *
+ * This is called when reinjecting completed fragments where
+ * all of the previous checking and book-keeping has been done.
+ */
+void
+ip6_direct_input(struct mbuf *m)
+{
+ int nest;
+ int off, nxt;
+
+ nxt = m->m_pkthdr.PH_loc.thirtytwo[0];
+ off = m->m_pkthdr.PH_loc.thirtytwo[1];
+
+ nest = 0;
+
+ while (nxt != IPPROTO_DONE) {
+ if (V_ip6_hdrnestlimit && (++nest > V_ip6_hdrnestlimit)) {
+ IP6STAT_INC(ip6s_toomanyhdr);
+ goto bad;
+ }
+
+ /*
+ * protection against faulty packet - there should be
+ * more sanity checks in header chain processing.
+ */
+ if (m->m_pkthdr.len < off) {
+ IP6STAT_INC(ip6s_tooshort);
+ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
+ goto bad;
+ }
+
+#ifdef IPSEC
+ /*
+ * enforce IPsec policy checking if we are seeing last header.
+ * note that we do not visit this with protocols with pcb layer
+ * code - like udp/tcp/raw ip.
+ */
+ if (ip6_ipsec_input(m, nxt))
+ goto bad;
+#endif /* IPSEC */
+
+ if (nxt == IPPROTO_FRAGMENT)
+ goto bad;
+
+ nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
+ }
+ return;
+bad:
+ m_freem(m);
+}
+#endif
+
void
ip6_input(struct mbuf *m)
{
@@ -713,6 +789,13 @@
nxt = ip6->ip6_nxt;
/*
+ * Use mbuf flags to propagate Router Alert option to
+ * ICMPv6 layer, as hop-by-hop options have been stripped.
+ */
+ if (rtalert != ~0)
+ m->m_flags |= M_RTALERT_MLD;
+
+ /*
* Check that the amount of data in the buffers
* is as at least much as the IPv6 header would have us expect.
* Trim mbufs if longer than we expect.
@@ -809,13 +892,6 @@
goto bad;
#endif /* IPSEC */
- /*
- * Use mbuf flags to propagate Router Alert option to
- * ICMPv6 layer, as hop-by-hop options have been stripped.
- */
- if (nxt == IPPROTO_ICMPV6 && rtalert != ~0)
- m->m_flags |= M_RTALERT_MLD;
-
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
}
return;
Index: sys/netinet6/ip6_var.h
===================================================================
--- sys/netinet6/ip6_var.h
+++ sys/netinet6/ip6_var.h
@@ -353,6 +353,7 @@
int ip6proto_unregister(short);
void ip6_input(struct mbuf *);
+void ip6_direct_input(struct mbuf *);
void ip6_freepcbopts(struct ip6_pktopts *);
int ip6_unknown_opt(u_int8_t *, struct mbuf *, int);

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 6, 2:23 AM (5 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36062358
Default Alt Text
D3563.id8641.diff (5 KB)

Event Timeline