svn commit: r192344 - projects/pnet/sys/netinet
Robert Watson
rwatson at FreeBSD.org
Mon May 18 21:57:29 UTC 2009
Author: rwatson
Date: Mon May 18 21:57:28 2009
New Revision: 192344
URL: http://svn.freebsd.org/changeset/base/192344
Log:
Implement nh_m2flow for IPv4 -- if no flow ID is available on an mbuf
destined for NETISR_IP, calculate a flow ID quickly using the source
and destination IP addresses. It's easy to imagine something more
complicated here, such as using the same RSS algorithm and parameters
programmed into cxgb and other supporting devices.
Modified:
projects/pnet/sys/netinet/ip_input.c
Modified: projects/pnet/sys/netinet/ip_input.c
==============================================================================
--- projects/pnet/sys/netinet/ip_input.c Mon May 18 21:50:06 2009 (r192343)
+++ projects/pnet/sys/netinet/ip_input.c Mon May 18 21:57:28 2009 (r192344)
@@ -167,9 +167,11 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_inet
struct pfil_head inet_pfil_hook; /* Packet filter hooks */
#ifdef NETISR2
+static struct mbuf *ip_input_m2flow(struct mbuf *m, uintptr_t source);
static struct netisr_handler ip_nh = {
.nh_name = "ip",
.nh_handler = ip_input,
+ .nh_m2flow = ip_input_m2flow,
.nh_proto = NETISR_IP,
.nh_qlimit = IFQ_MAXLEN,
.nh_policy = NETISR_POLICY_FLOW,
@@ -299,6 +301,11 @@ sysctl_netinet_intr_queue_drops(SYSCTL_H
SYSCTL_PROC(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops,
CTLTYPE_INT|CTLFLAG_RD, 0, 0, sysctl_netinet_intr_queue_drops, "I",
"Number of packets dropped from the IP input queue");
+
+static int ip_m2flow_enable = 1;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, m2flow_enable, CTLFLAG_RW,
+ &ip_m2flow_enable, 0,
+ "Enable software flow ID calculation for parallel netisr distribution");
#endif
/*
@@ -416,6 +423,57 @@ ip_fini(void *xtp)
callout_stop(&ipport_tick_callout);
}
+#ifdef NETISR2
+/*
+ * Calculate a flow ID for an IP packet if one isn't already present; this is
+ * a subset of the work done by ip_input() necessary to validate and read the
+ * IP header. We only do stats on the packet if we drop it -- otherwise, the
+ * normal input routine manages its statistics.
+ */
+static struct mbuf *
+ip_input_m2flow(struct mbuf *m, uintptr_t source)
+{
+ struct ip *ip;
+ int hlen;
+
+ M_ASSERTPKTHDR(m);
+ KASSERT(!(m->m_flags & M_FLOWID),
+ ("ip_input_m2flow: M_FLOWID already set"));
+
+ if (!ip_m2flow_enable)
+ return (m);
+
+ if (m->m_pkthdr.len < sizeof(struct ip)) {
+ IPSTAT_INC(ips_tooshort);
+ goto bad;
+ }
+ if (m->m_len < sizeof (struct ip) &&
+ (m = m_pullup(m, sizeof(struct ip))) == NULL) {
+ IPSTAT_INC(ips_total);
+ IPSTAT_INC(ips_toosmall);
+ return (NULL);
+ }
+ ip = mtod(m, struct ip *);
+ if (ip->ip_v != IPVERSION) {
+ IPSTAT_INC(ips_badvers);
+ goto bad;
+ }
+ hlen = ip->ip_hl << 2;
+ if (hlen < sizeof(struct ip)) {
+ IPSTAT_INC(ips_badhlen);
+ goto bad;
+ }
+ m->m_flags |= M_FLOWID;
+ m->m_pkthdr.flowid = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
+ return (m);
+
+bad:
+ IPSTAT_INC(ips_total);
+ m_freem(m);
+ return (NULL);
+}
+#endif
+
/*
* Ip input routine. Checksum and byte swap header. If fragmented
* try to reassemble. Process options. Pass to next level.
More information about the svn-src-projects
mailing list