Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 May 2009 21:57:28 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r192344 - projects/pnet/sys/netinet
Message-ID:  <200905182157.n4ILvS0B076009@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905182157.n4ILvS0B076009>