Page MenuHomeFreeBSD

D3563.id8719.diff
No OneTemporary

D3563.id8719.diff

Index: sys/netinet6/frag6.c
===================================================================
--- sys/netinet6/frag6.c
+++ sys/netinet6/frag6.c
@@ -32,6 +32,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_rss.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -46,6 +48,7 @@
#include <net/if.h>
#include <net/if_var.h>
+#include <net/netisr.h>
#include <net/route.h>
#include <net/vnet.h>
@@ -577,9 +580,21 @@
m->m_pkthdr.len = plen;
}
+ IP6Q_UNLOCK();
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
+#ifdef RSS
+ m->m_pkthdr.PH_loc.thirtytwo[0] = nxt;
+ m->m_pkthdr.PH_loc.thirtytwo[1] = offset;
+
+ /*
+ * Queue/dispatch for reprocessing.
+ */
+ netisr_dispatch(NETISR_IPV6_DIRECT, m);
+ return IPPROTO_DONE;
+#endif
+
/*
* Tell launch routine the next header
*/
@@ -587,7 +602,6 @@
*mp = m;
*offp = offset;
- IP6Q_UNLOCK();
return nxt;
dropfrag:
Index: sys/netinet6/in6_rss.c
===================================================================
--- sys/netinet6/in6_rss.c
+++ sys/netinet6/in6_rss.c
@@ -172,6 +172,7 @@
uint32_t *hashtype)
{
const struct ip6_hdr *ip6;
+ const struct ip6_frag *ip6f;
const struct tcphdr *th;
const struct udphdr *uh;
uint32_t flowtype;
@@ -222,6 +223,26 @@
}
/*
+ * Ignore the fragment header if this is an "atomic" fragment
+ * (offset and m bit set to 0)
+ */
+ if (proto == IPPROTO_FRAGMENT) {
+ if (m->m_len < off + sizeof(struct ip6_frag)) {
+ RSS_DEBUG("short fragment frame?\n");
+ return (-1);
+ }
+ ip6f = (const struct ip6_frag *)((c_caddr_t)ip6 + off);
+ if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
+ off = ip6_lasthdr(m, off, proto, &nxt);
+ if (off < 0) {
+ RSS_DEBUG("invalid extension header\n");
+ return (-1);
+ }
+ proto = nxt;
+ }
+ }
+
+ /*
* If the mbuf flowid/flowtype matches the packet type,
* and we don't support the 4-tuple version of the given protocol,
* then signal to the owner that it can trust the flowid/flowtype
Index: sys/netinet6/ip6_input.c
===================================================================
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -144,6 +144,17 @@
#endif
};
+#ifdef RSS
+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 +233,9 @@
}
netisr_register(&ip6_nh);
+#ifdef RSS
+ netisr_register(&ip6_direct_nh);
+#endif
}
/*
@@ -403,6 +417,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;
+ }
+
+ if (nxt == IPPROTO_FRAGMENT)
+ 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 */
+
+ nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
+ }
+ return;
+bad:
+ m_freem(m);
+}
+#endif
+
void
ip6_input(struct mbuf *m)
{
@@ -713,6 +782,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 +885,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
Sun, Mar 1, 9:38 PM (13 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29126560
Default Alt Text
D3563.id8719.diff (5 KB)

Event Timeline