Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Jun 2011 16:33:07 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r222691 - in head/sys: contrib/pf/net netinet netinet6
Message-ID:  <201106041633.p54GX7H8017769@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Sat Jun  4 16:33:06 2011
New Revision: 222691
URL: http://svn.freebsd.org/changeset/base/222691

Log:
  Add _mbuf() variants of various inpcb-related interfaces, including lookup,
  hash install, etc.  For now, these are arguments are unused, but as we add
  RSS support, we will want to use hashes extracted from mbufs, rather than
  manually calculated hashes of header fields, due to the expensive of the
  software version of Toeplitz (and similar hashes).
  
  Add notes that it would be nice to be able to pass mbufs into lookup
  routines in pf(4), optimising firewall lookup in the same way, but the
  code structure there doesn't facilitate that currently.
  
  (In principle there is no reason this couldn't be MFCed -- the change
  extends rather than modifies the KBI.  However, it won't be useful without
  other previous possibly less MFCable changes.)
  
  Reviewed by:    bz
  Sponsored by:   Juniper Networks, Inc.

Modified:
  head/sys/contrib/pf/net/pf.c
  head/sys/netinet/in_pcb.c
  head/sys/netinet/in_pcb.h
  head/sys/netinet/tcp_input.c
  head/sys/netinet/tcp_syncache.c
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet6/in6_pcb.c
  head/sys/netinet6/in6_pcb.h
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/contrib/pf/net/pf.c
==============================================================================
--- head/sys/contrib/pf/net/pf.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/contrib/pf/net/pf.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -3034,6 +3034,10 @@ pf_socket_lookup(int direction, struct p
 #ifdef INET
 	case AF_INET:
 #ifdef __FreeBSD__
+		/*
+		 * XXXRW: would be nice if we had an mbuf here so that we
+		 * could use in_pcblookup_mbuf().
+		 */
 		inp = in_pcblookup(pi, saddr->v4, sport, daddr->v4,
 			dport, INPLOOKUP_RLOCKPCB, NULL);
 		if (inp == NULL) {
@@ -3056,6 +3060,10 @@ pf_socket_lookup(int direction, struct p
 #ifdef INET6
 	case AF_INET6:
 #ifdef __FreeBSD__
+		/*
+		 * XXXRW: would be nice if we had an mbuf here so that we
+		 * could use in6_pcblookup_mbuf().
+		 */
 		inp = in6_pcblookup(pi, &saddr->v6, sport,
 			&daddr->v6, dport, INPLOOKUP_RLOCKPCB, NULL);
 		if (inp == NULL) {

Modified: head/sys/netinet/in_pcb.c
==============================================================================
--- head/sys/netinet/in_pcb.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet/in_pcb.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -621,7 +621,8 @@ in_pcbbind_setup(struct inpcb *inp, stru
  * then pick one.
  */
 int
-in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
+in_pcbconnect_mbuf(struct inpcb *inp, struct sockaddr *nam,
+    struct ucred *cred, struct mbuf *m)
 {
 	u_short lport, fport;
 	in_addr_t laddr, faddr;
@@ -654,13 +655,20 @@ in_pcbconnect(struct inpcb *inp, struct 
 	inp->inp_laddr.s_addr = laddr;
 	inp->inp_faddr.s_addr = faddr;
 	inp->inp_fport = fport;
-	in_pcbrehash(inp);
+	in_pcbrehash_mbuf(inp, m);
 
 	if (anonport)
 		inp->inp_flags |= INP_ANONPORT;
 	return (0);
 }
 
+int
+in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
+{
+
+	return (in_pcbconnect_mbuf(inp, nam, cred, NULL));
+}
+
 /*
  * Do proper source address selection on an unbound socket in case
  * of connect. Take jails into account as well.
@@ -1626,7 +1634,8 @@ in_pcblookup_hash(struct inpcbinfo *pcbi
 }
 
 /*
- * Public inpcb lookup routines, accepting a 4-tuple.
+ * Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf
+ * from which a pre-calculated hash value may be extracted.
  */
 struct inpcb *
 in_pcblookup(struct inpcbinfo *pcbinfo, struct in_addr faddr, u_int fport,
@@ -1641,6 +1650,21 @@ in_pcblookup(struct inpcbinfo *pcbinfo, 
 	return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
 	    lookupflags, ifp));
 }
+
+struct inpcb *
+in_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in_addr faddr,
+    u_int fport, struct in_addr laddr, u_int lport, int lookupflags,
+    struct ifnet *ifp, struct mbuf *m)
+{
+
+	KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
+	    ("%s: invalid lookup flags %d", __func__, lookupflags));
+	KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0,
+	    ("%s: LOCKPCB not set", __func__));
+
+	return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
+	    lookupflags, ifp));
+}
 #endif /* INET */
 
 /*
@@ -1707,7 +1731,7 @@ in_pcbinshash(struct inpcb *inp)
  * not change after in_pcbinshash() has been called.
  */
 void
-in_pcbrehash(struct inpcb *inp)
+in_pcbrehash_mbuf(struct inpcb *inp, struct mbuf *m)
 {
 	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
 	struct inpcbhead *head;
@@ -1733,6 +1757,13 @@ in_pcbrehash(struct inpcb *inp)
 	LIST_INSERT_HEAD(head, inp, inp_hash);
 }
 
+void
+in_pcbrehash(struct inpcb *inp)
+{
+
+	in_pcbrehash_mbuf(inp, NULL);
+}
+
 /*
  * Remove PCB from various lists.
  */

Modified: head/sys/netinet/in_pcb.h
==============================================================================
--- head/sys/netinet/in_pcb.h	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet/in_pcb.h	Sat Jun  4 16:33:06 2011	(r222691)
@@ -541,6 +541,8 @@ int	in_pcb_lport(struct inpcb *, struct 
 int	in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
 	    u_short *, struct ucred *);
 int	in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
+int	in_pcbconnect_mbuf(struct inpcb *, struct sockaddr *, struct ucred *,
+	    struct mbuf *);
 int	in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
 	    u_short *, in_addr_t *, u_short *, struct inpcb **,
 	    struct ucred *);
@@ -555,10 +557,14 @@ struct inpcb *
 struct inpcb *
 	in_pcblookup(struct inpcbinfo *, struct in_addr, u_int,
 	    struct in_addr, u_int, int, struct ifnet *);
+struct inpcb *
+	in_pcblookup_mbuf(struct inpcbinfo *, struct in_addr, u_int,
+	    struct in_addr, u_int, int, struct ifnet *, struct mbuf *);
 void	in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr,
 	    int, struct inpcb *(*)(struct inpcb *, int));
 void	in_pcbref(struct inpcb *);
 void	in_pcbrehash(struct inpcb *);
+void	in_pcbrehash_mbuf(struct inpcb *, struct mbuf *);
 int	in_pcbrele(struct inpcb *);
 int	in_pcbrele_rlocked(struct inpcb *);
 int	in_pcbrele_wlocked(struct inpcb *);

Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet/tcp_input.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -791,12 +791,14 @@ findpcb:
 		 * Transparently forwarded. Pretend to be the destination.
 		 * already got one like this?
 		 */
-		inp = in_pcblookup(&V_tcbinfo, ip->ip_src, th->th_sport,
+		inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src, th->th_sport,
 		    ip->ip_dst, th->th_dport, INPLOOKUP_WLOCKPCB,
-		    m->m_pkthdr.rcvif);
+		    m->m_pkthdr.rcvif, m);
 		if (!inp) {
 			/*
 			 * It's new.  Try to find the ambushing socket.
+			 * Because we've rewritten the destination address,
+			 * any hardware-generated hash is ignored.
 			 */
 			inp = in_pcblookup(&V_tcbinfo, ip->ip_src,
 			    th->th_sport, next_hop->sin_addr,
@@ -812,19 +814,19 @@ findpcb:
 	{
 #ifdef INET6
 		if (isipv6)
-			inp = in6_pcblookup(&V_tcbinfo, &ip6->ip6_src,
+			inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src,
 			    th->th_sport, &ip6->ip6_dst, th->th_dport,
 			    INPLOOKUP_WILDCARD | INPLOOKUP_WLOCKPCB,
-			    m->m_pkthdr.rcvif);
+			    m->m_pkthdr.rcvif, m);
 #endif
 #if defined(INET) && defined(INET6)
 		else
 #endif
 #ifdef INET
-			inp = in_pcblookup(&V_tcbinfo, ip->ip_src,
+			inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src,
 			    th->th_sport, ip->ip_dst, th->th_dport,
 			    INPLOOKUP_WILDCARD | INPLOOKUP_WLOCKPCB,
-			    m->m_pkthdr.rcvif);
+			    m->m_pkthdr.rcvif, m);
 #endif
 	}
 

Modified: head/sys/netinet/tcp_syncache.c
==============================================================================
--- head/sys/netinet/tcp_syncache.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet/tcp_syncache.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -730,8 +730,8 @@ syncache_socket(struct syncache *sc, str
 		laddr6 = inp->in6p_laddr;
 		if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
 			inp->in6p_laddr = sc->sc_inc.inc6_laddr;
-		if ((error = in6_pcbconnect(inp, (struct sockaddr *)&sin6,
-		    thread0.td_ucred)) != 0) {
+		if ((error = in6_pcbconnect_mbuf(inp, (struct sockaddr *)&sin6,
+		    thread0.td_ucred, m)) != 0) {
 			inp->in6p_laddr = laddr6;
 			if ((s = tcp_log_addrs(&sc->sc_inc, NULL, NULL, NULL))) {
 				log(LOG_DEBUG, "%s; %s: in6_pcbconnect failed "
@@ -770,8 +770,8 @@ syncache_socket(struct syncache *sc, str
 		laddr = inp->inp_laddr;
 		if (inp->inp_laddr.s_addr == INADDR_ANY)
 			inp->inp_laddr = sc->sc_inc.inc_laddr;
-		if ((error = in_pcbconnect(inp, (struct sockaddr *)&sin,
-		    thread0.td_ucred)) != 0) {
+		if ((error = in_pcbconnect_mbuf(inp, (struct sockaddr *)&sin,
+		    thread0.td_ucred, m)) != 0) {
 			inp->inp_laddr = laddr;
 			if ((s = tcp_log_addrs(&sc->sc_inc, NULL, NULL, NULL))) {
 				log(LOG_DEBUG, "%s; %s: in_pcbconnect failed "

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet/udp_usrreq.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -567,9 +567,9 @@ udp_input(struct mbuf *m, int off)
 	/*
 	 * Locate pcb for datagram.
 	 */
-	inp = in_pcblookup(&V_udbinfo, ip->ip_src, uh->uh_sport,
+	inp = in_pcblookup_mbuf(&V_udbinfo, ip->ip_src, uh->uh_sport,
 	    ip->ip_dst, uh->uh_dport, INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
-	    ifp);
+	    ifp, m);
 	if (inp == NULL) {
 		if (udp_log_in_vain) {
 			char buf[4*sizeof "123"];

Modified: head/sys/netinet6/in6_pcb.c
==============================================================================
--- head/sys/netinet6/in6_pcb.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet6/in6_pcb.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -364,8 +364,8 @@ in6_pcbladdr(register struct inpcb *inp,
  * then pick one.
  */
 int
-in6_pcbconnect(register struct inpcb *inp, struct sockaddr *nam,
-    struct ucred *cred)
+in6_pcbconnect_mbuf(register struct inpcb *inp, struct sockaddr *nam,
+    struct ucred *cred, struct mbuf *m)
 {
 	struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
 	register struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
@@ -405,11 +405,18 @@ in6_pcbconnect(register struct inpcb *in
 		inp->inp_flow |=
 		    (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
 
-	in_pcbrehash(inp);
+	in_pcbrehash_mbuf(inp, m);
 
 	return (0);
 }
 
+int
+in6_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred)
+{
+
+	return (in6_pcbconnect_mbuf(inp, nam, cred, NULL));
+}
+
 void
 in6_pcbdisconnect(struct inpcb *inp)
 {
@@ -974,13 +981,27 @@ in6_pcblookup_hash(struct inpcbinfo *pcb
 }
 
 /*
- * Public inpcb lookup routines, accepting a 4-tuple.
+ * Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf
+ * from which a pre-calculated hash value may be extracted.
  */
 struct inpcb *
 in6_pcblookup(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, u_int fport,
     struct in6_addr *laddr, u_int lport, int lookupflags, struct ifnet *ifp)
 {
+	KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
+	    ("%s: invalid lookup flags %d", __func__, lookupflags));
+	KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0,
+	    ("%s: LOCKPCB not set", __func__));
+
+	return (in6_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
+	    lookupflags, ifp));
+}
 
+struct inpcb *
+in6_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
+    u_int fport, struct in6_addr *laddr, u_int lport, int lookupflags,
+    struct ifnet *ifp, struct mbuf *m)
+{
 	KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0,
 	    ("%s: invalid lookup flags %d", __func__, lookupflags));
 	KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0,

Modified: head/sys/netinet6/in6_pcb.h
==============================================================================
--- head/sys/netinet6/in6_pcb.h	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet6/in6_pcb.h	Sat Jun  4 16:33:06 2011	(r222691)
@@ -73,6 +73,8 @@ void	in6_pcbpurgeif0 __P((struct inpcbin
 void	in6_losing __P((struct inpcb *));
 int	in6_pcbbind __P((struct inpcb *, struct sockaddr *, struct ucred *));
 int	in6_pcbconnect __P((struct inpcb *, struct sockaddr *, struct ucred *));
+int	in6_pcbconnect_mbuf __P((struct inpcb *, struct sockaddr *,
+	    struct ucred *, struct mbuf *));
 void	in6_pcbdisconnect __P((struct inpcb *));
 int	in6_pcbladdr(struct inpcb *, struct sockaddr *, struct in6_addr *);
 struct	inpcb *
@@ -87,6 +89,10 @@ struct	inpcb *
 	in6_pcblookup_hash_locked __P((struct inpcbinfo *, struct in6_addr *,
 			   u_int, struct in6_addr *, u_int, int,
 			   struct ifnet *));
+struct	inpcb *
+	in6_pcblookup_mbuf __P((struct inpcbinfo *, struct in6_addr *,
+			   u_int, struct in6_addr *, u_int, int,
+			   struct ifnet *ifp, struct mbuf *));
 void	in6_pcbnotify __P((struct inpcbinfo *, struct sockaddr *,
 			   u_int, const struct sockaddr *, u_int, int, void *,
 			   struct inpcb *(*)(struct inpcb *, int)));

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c	Sat Jun  4 16:26:02 2011	(r222690)
+++ head/sys/netinet6/udp6_usrreq.c	Sat Jun  4 16:33:06 2011	(r222691)
@@ -377,9 +377,9 @@ udp6_input(struct mbuf **mp, int *offp, 
 	/*
 	 * Locate pcb for datagram.
 	 */
-	inp = in6_pcblookup(&V_udbinfo, &ip6->ip6_src, uh->uh_sport,
+	inp = in6_pcblookup_mbuf(&V_udbinfo, &ip6->ip6_src, uh->uh_sport,
 	    &ip6->ip6_dst, uh->uh_dport, INPLOOKUP_WILDCARD |
-	    INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif);
+	    INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif, m);
 	if (inp == NULL) {
 		if (udp_log_in_vain) {
 			char ip6bufs[INET6_ADDRSTRLEN];



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