diff options
Diffstat (limited to 'sys/netinet6/ip6_input.c')
-rw-r--r-- | sys/netinet6/ip6_input.c | 61 |
1 files changed, 55 insertions, 6 deletions
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 78e8ef3..fc38168 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include "opt_ipfw.h" #include "opt_ipsec.h" #include "opt_route.h" +#include "opt_rss.h" #include <sys/param.h> #include <sys/systm.h> @@ -82,6 +83,8 @@ __FBSDID("$FreeBSD$"); #include <sys/errno.h> #include <sys/time.h> #include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/rmlock.h> #include <sys/syslog.h> #include <net/if.h> @@ -90,6 +93,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_dl.h> #include <net/route.h> #include <net/netisr.h> +#include <net/rss_config.h> #include <net/pfil.h> #include <net/vnet.h> @@ -110,6 +114,7 @@ __FBSDID("$FreeBSD$"); #include <netinet6/scope6_var.h> #include <netinet6/in6_ifattach.h> #include <netinet6/nd6.h> +#include <netinet6/in6_rss.h> #ifdef IPSEC #include <netipsec/ipsec.h> @@ -130,7 +135,13 @@ static struct netisr_handler ip6_nh = { .nh_name = "ip6", .nh_handler = ip6_input, .nh_proto = NETISR_IPV6, +#ifdef RSS + .nh_m2cpuid = rss_soft_m2cpuid_v6, + .nh_policy = NETISR_POLICY_CPU, + .nh_dispatch = NETISR_DISPATCH_HYBRID, +#else .nh_policy = NETISR_POLICY_FLOW, +#endif }; VNET_DECLARE(struct callout, in6_tmpaddrtimer_ch); @@ -144,8 +155,8 @@ VNET_PCPUSTAT_SYSINIT(ip6stat); VNET_PCPUSTAT_SYSUNINIT(ip6stat); #endif /* VIMAGE */ -struct rwlock in6_ifaddr_lock; -RW_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); +struct rmlock in6_ifaddr_lock; +RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); static void ip6_init2(void *); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); @@ -1339,6 +1350,44 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp) loopend: ; } + + if (in6p->inp_flags2 & INP_RECVFLOWID) { + uint32_t flowid, flow_type; + + flowid = m->m_pkthdr.flowid; + flow_type = M_HASHTYPE_GET(m); + + /* + * XXX should handle the failure of one or the + * other - don't populate both? + */ + *mp = sbcreatecontrol((caddr_t) &flowid, + sizeof(uint32_t), IPV6_FLOWID, IPPROTO_IPV6); + if (*mp) + mp = &(*mp)->m_next; + *mp = sbcreatecontrol((caddr_t) &flow_type, + sizeof(uint32_t), IPV6_FLOWTYPE, IPPROTO_IPV6); + if (*mp) + mp = &(*mp)->m_next; + } + +#ifdef RSS + if (in6p->inp_flags2 & INP_RECVRSSBUCKETID) { + uint32_t flowid, flow_type; + uint32_t rss_bucketid; + + flowid = m->m_pkthdr.flowid; + flow_type = M_HASHTYPE_GET(m); + + if (rss_hash2bucket(flowid, flow_type, &rss_bucketid) == 0) { + *mp = sbcreatecontrol((caddr_t) &rss_bucketid, + sizeof(uint32_t), IPV6_RSSBUCKETID, IPPROTO_IPV6); + if (*mp) + mp = &(*mp)->m_next; + } + } +#endif + } #undef IS2292 @@ -1438,7 +1487,7 @@ ip6_pullexthdr(struct mbuf *m, size_t off, int nxt) * we develop `neater' mechanism to process extension headers. */ char * -ip6_get_prevhdr(struct mbuf *m, int off) +ip6_get_prevhdr(const struct mbuf *m, int off) { struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); @@ -1477,7 +1526,7 @@ ip6_get_prevhdr(struct mbuf *m, int off) * get next header offset. m will be retained. */ int -ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp) +ip6_nexthdr(const struct mbuf *m, int off, int proto, int *nxtp) { struct ip6_hdr ip6; struct ip6_ext ip6e; @@ -1545,14 +1594,14 @@ ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp) return -1; } - return -1; + /* NOTREACHED */ } /* * get offset for the last header in the chain. m will be kept untainted. */ int -ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp) +ip6_lasthdr(const struct mbuf *m, int off, int proto, int *nxtp) { int newoff; int nxt; |