From owner-svn-src-projects@FreeBSD.ORG Mon May 18 21:57:29 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 551541065690; Mon, 18 May 2009 21:57:29 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3894E8FC08; Mon, 18 May 2009 21:57:29 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4ILvSlV076010; Mon, 18 May 2009 21:57:28 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4ILvS0B076009; Mon, 18 May 2009 21:57:28 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200905182157.n4ILvS0B076009@svn.freebsd.org> From: Robert Watson Date: Mon, 18 May 2009 21:57:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192344 - projects/pnet/sys/netinet X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 May 2009 21:57:29 -0000 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.