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