diff options
author | rwatson <rwatson@FreeBSD.org> | 2011-06-04 16:33:06 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2011-06-04 16:33:06 +0000 |
commit | e9eb5d3b9cabfc492871c5e6a6b40f13063f17f9 (patch) | |
tree | f8c4b2222ac90d9dcf29f0f56f99b2e15040c5b0 /sys/netinet6 | |
parent | f2e70f34fff765930c45c50d9cb2c5a6c47c24df (diff) | |
download | FreeBSD-src-e9eb5d3b9cabfc492871c5e6a6b40f13063f17f9.zip FreeBSD-src-e9eb5d3b9cabfc492871c5e6a6b40f13063f17f9.tar.gz |
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.
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_pcb.c | 29 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.h | 6 | ||||
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 4 |
3 files changed, 33 insertions, 6 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 17fb953..da73f21 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -364,8 +364,8 @@ in6_pcbladdr(register struct inpcb *inp, struct sockaddr *nam, * 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 *inp, struct sockaddr *nam, 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 *pcbinfo, struct in6_addr *faddr, } /* - * 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, diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h index bce5ee3..cf24704 100644 --- a/sys/netinet6/in6_pcb.h +++ b/sys/netinet6/in6_pcb.h @@ -73,6 +73,8 @@ void in6_pcbpurgeif0 __P((struct inpcbinfo *, struct ifnet *)); 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))); diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 75145d7..6723007 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -377,9 +377,9 @@ udp6_input(struct mbuf **mp, int *offp, int proto) /* * 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]; |