Page MenuHomeFreeBSD

D3563.id9246.diff
No OneTemporary

D3563.id9246.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>
@@ -159,6 +162,10 @@
int fragoff, frgpartlen; /* must be larger than u_int16_t */
struct ifnet *dstifp;
u_int8_t ecn, ecn0;
+#ifdef RSS
+ struct m_tag *mtag;
+#endif
+
#if 0
char ip6buf[INET6_ADDRSTRLEN];
#endif
@@ -577,9 +584,30 @@
m->m_pkthdr.len = plen;
}
+#ifdef RSS
+ mtag = m_tag_alloc(MTAG_ABI_IPV6, IPV6_TAG_DIRECT, 2 * sizeof(int),
+ M_NOWAIT);
+ if (mtag == NULL)
+ goto dropfrag;
+
+ *((int *)(mtag + 1) + 0) = nxt;
+ *((int *)(mtag + 1) + 1) = offset;
+
+ m_tag_prepend(m, mtag);
+#endif
+
+ IP6Q_UNLOCK();
IP6STAT_INC(ip6s_reassembled);
in6_ifstat_inc(dstifp, ifs6_reass_ok);
+#ifdef RSS
+ /*
+ * Queue/dispatch for reprocessing.
+ */
+ netisr_dispatch(NETISR_IPV6_DIRECT, m);
+ return IPPROTO_DONE;
+#endif
+
/*
* Tell launch routine the next header
*/
@@ -587,7 +615,6 @@
*mp = m;
*offp = offset;
- IP6Q_UNLOCK();
return nxt;
dropfrag:
Index: sys/netinet6/in6.h
===================================================================
--- sys/netinet6/in6.h
+++ sys/netinet6/in6.h
@@ -382,6 +382,11 @@
};
#endif
+#ifdef _KERNEL
+#define MTAG_ABI_IPV6 1444287380 /* IPv6 ABI */
+#define IPV6_TAG_DIRECT 0 /* direct-dispatch IPv6 */
+#endif /* _KERNEL */
+
/*
* Options for use with [gs]etsockopt at the IPV6 level.
* First word of comment is data type; bool is stored in int.
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,65 @@
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 off, nxt;
+ int nest;
+ struct m_tag *mtag;
+
+ mtag = m_tag_locate(m, MTAG_ABI_IPV6, IPV6_TAG_DIRECT, NULL);
+ if (mtag == NULL)
+ goto bad;
+
+ nxt = *((int *)(mtag + 1) + 0);
+ off = *((int *)(mtag + 1) + 1);
+
+ nest = 0;
+
+ m_tag_delete(m, mtag);
+
+ 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 */
+
+ nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
+ }
+ return;
+bad:
+ m_freem(m);
+}
+#endif
+
void
ip6_input(struct mbuf *m)
{
@@ -713,6 +786,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 +889,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
Sat, Nov 22, 12:49 AM (21 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25848897
Default Alt Text
D3563.id9246.diff (5 KB)

Event Timeline