Refactor internet PCB lookup function. Rename in_pcbhashlookup()
authorbluhm <bluhm@openbsd.org>
Tue, 30 Aug 2022 11:53:03 +0000 (11:53 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 30 Aug 2022 11:53:03 +0000 (11:53 +0000)
so the public API is in_pcblookup() and in_pcblookup_listen().  For
internal use introduce in_pcbhash_insert() and in_pcbhash_lookup()
to avoid code duplication.  Routing domain is unsigned, change the
type to u_int.
OK mvs@

sys/net/pf.c
sys/netinet/in_pcb.c
sys/netinet/in_pcb.h
sys/netinet/tcp_input.c
sys/netinet/tcp_subr.c
sys/netinet/tcp_usrreq.c
sys/netinet/udp_usrreq.c
sys/netinet6/in6_pcb.c
sys/netinet6/raw_ip6.c

index f23968f..81a53fe 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pf.c,v 1.1137 2022/08/08 12:06:30 bluhm Exp $ */
+/*     $OpenBSD: pf.c,v 1.1138 2022/08/30 11:53:03 bluhm Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -3348,7 +3348,7 @@ pf_socket_lookup(struct pf_pdesc *pd)
                 * Fails when rtable is changed while evaluating the ruleset
                 * The socket looked up will not match the one hit in the end.
                 */
-               inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport,
+               inp = in_pcblookup(tb, saddr->v4, sport, daddr->v4, dport,
                    pd->rdomain);
                if (inp == NULL) {
                        inp = in_pcblookup_listen(tb, daddr->v4, dport,
@@ -3359,7 +3359,7 @@ pf_socket_lookup(struct pf_pdesc *pd)
                break;
 #ifdef INET6
        case AF_INET6:
-               inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
+               inp = in6_pcblookup(tb, &saddr->v6, sport, &daddr->v6,
                    dport, pd->rdomain);
                if (inp == NULL) {
                        inp = in6_pcblookup_listen(tb, &daddr->v6, dport,
index d145fb6..b326f3f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in_pcb.c,v 1.272 2022/08/22 10:37:27 bluhm Exp $      */
+/*     $OpenBSD: in_pcb.c,v 1.273 2022/08/30 11:53:04 bluhm Exp $      */
 /*     $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $     */
 
 /*
@@ -120,14 +120,16 @@ struct baddynamicports baddynamicports;
 struct baddynamicports rootonlyports;
 struct pool inpcb_pool;
 
-void   in_pcbrehash_locked(struct inpcb *);
+void   in_pcbhash_insert(struct inpcb *);
+struct inpcb *in_pcbhash_lookup(struct inpcbtable *, u_int,
+    const struct in_addr *, u_short, const struct in_addr *, u_short);
 int    in_pcbresize(struct inpcbtable *, int);
 
 #define        INPCBHASH_LOADFACTOR(_x)        (((_x) * 3) / 4)
 
-struct inpcbhead *in_pcbhash(struct inpcbtable *, int,
+struct inpcbhead *in_pcbhash(struct inpcbtable *, u_int,
     const struct in_addr *, u_short, const struct in_addr *, u_short);
-struct inpcbhead *in_pcblhash(struct inpcbtable *, int, u_short);
+struct inpcbhead *in_pcblhash(struct inpcbtable *, u_int, u_short);
 
 /*
  * in_pcb is used for inet and inet6.  in6_pcb only contains special
@@ -141,12 +143,12 @@ in_init(void)
 }
 
 struct inpcbhead *
-in_pcbhash(struct inpcbtable *table, int rdom,
+in_pcbhash(struct inpcbtable *table, u_int rdomain,
     const struct in_addr *faddr, u_short fport,
     const struct in_addr *laddr, u_short lport)
 {
        SIPHASH_CTX ctx;
-       u_int32_t nrdom = htonl(rdom);
+       u_int32_t nrdom = htonl(rdomain);
 
        SipHash24_Init(&ctx, &table->inpt_key);
        SipHash24_Update(&ctx, &nrdom, sizeof(nrdom));
@@ -159,10 +161,10 @@ in_pcbhash(struct inpcbtable *table, int rdom,
 }
 
 struct inpcbhead *
-in_pcblhash(struct inpcbtable *table, int rdom, u_short lport)
+in_pcblhash(struct inpcbtable *table, u_int rdomain, u_short lport)
 {
        SIPHASH_CTX ctx;
-       u_int32_t nrdom = htonl(rdom);
+       u_int32_t nrdom = htonl(rdomain);
 
        SipHash24_Init(&ctx, &table->inpt_lkey);
        SipHash24_Update(&ctx, &nrdom, sizeof(nrdom));
@@ -227,9 +229,6 @@ int
 in_pcballoc(struct socket *so, struct inpcbtable *table)
 {
        struct inpcb *inp;
-       struct inpcbhead *head;
-
-       NET_ASSERT_LOCKED();
 
        inp = pool_get(&inpcb_pool, PR_NOWAIT|PR_ZERO);
        if (inp == NULL)
@@ -259,19 +258,7 @@ in_pcballoc(struct socket *so, struct inpcbtable *table)
        if (table->inpt_count++ > INPCBHASH_LOADFACTOR(table->inpt_size))
                (void)in_pcbresize(table, table->inpt_size * 2);
        TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue);
-       head = in_pcblhash(table, inp->inp_rtableid, inp->inp_lport);
-       LIST_INSERT_HEAD(head, inp, inp_lhash);
-#ifdef INET6
-       if (sotopf(so) == PF_INET6)
-               head = in6_pcbhash(table, rtable_l2(inp->inp_rtableid),
-                   &inp->inp_faddr6, inp->inp_fport,
-                   &inp->inp_laddr6, inp->inp_lport);
-       else
-#endif /* INET6 */
-               head = in_pcbhash(table, rtable_l2(inp->inp_rtableid),
-                   &inp->inp_faddr, inp->inp_fport,
-                   &inp->inp_laddr, inp->inp_lport);
-       LIST_INSERT_HEAD(head, inp, inp_hash);
+       in_pcbhash_insert(inp);
        mtx_leave(&table->inpt_mtx);
 
        so->so_pcb = inp;
@@ -513,7 +500,7 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam)
        if (error)
                return (error);
 
-       t = in_pcbhashlookup(inp->inp_table, sin->sin_addr, sin->sin_port,
+       t = in_pcblookup(inp->inp_table, sin->sin_addr, sin->sin_port,
            ina, inp->inp_lport, inp->inp_rtableid);
        if (t != NULL) {
                in_pcbunref(t);
@@ -527,7 +514,7 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam)
                        error = in_pcbbind(inp, NULL, curproc);
                        if (error)
                                return (error);
-                       t = in_pcbhashlookup(inp->inp_table, sin->sin_addr,
+                       t = in_pcblookup(inp->inp_table, sin->sin_addr,
                            sin->sin_port, ina, inp->inp_lport,
                            inp->inp_rtableid);
                        if (t != NULL) {
@@ -582,8 +569,6 @@ in_pcbdetach(struct inpcb *inp)
        struct socket *so = inp->inp_socket;
        struct inpcbtable *table = inp->inp_table;
 
-       NET_ASSERT_LOCKED();
-
        so->so_pcb = NULL;
        /*
         * As long as the NET_LOCK() is the default lock for Internet
@@ -1037,12 +1022,14 @@ in_pcbrehash(struct inpcb *inp)
        struct inpcbtable *table = inp->inp_table;
 
        mtx_enter(&table->inpt_mtx);
-       in_pcbrehash_locked(inp);
+       LIST_REMOVE(inp, inp_lhash);
+       LIST_REMOVE(inp, inp_hash);
+       in_pcbhash_insert(inp);
        mtx_leave(&table->inpt_mtx);
 }
 
 void
-in_pcbrehash_locked(struct inpcb *inp)
+in_pcbhash_insert(struct inpcb *inp)
 {
        struct inpcbtable *table = inp->inp_table;
        struct inpcbhead *head;
@@ -1050,10 +1037,8 @@ in_pcbrehash_locked(struct inpcb *inp)
        NET_ASSERT_LOCKED();
        MUTEX_ASSERT_LOCKED(&table->inpt_mtx);
 
-       LIST_REMOVE(inp, inp_lhash);
        head = in_pcblhash(table, inp->inp_rtableid, inp->inp_lport);
        LIST_INSERT_HEAD(head, inp, inp_lhash);
-       LIST_REMOVE(inp, inp_hash);
 #ifdef INET6
        if (inp->inp_flags & INP_IPV6)
                head = in6_pcbhash(table, rtable_l2(inp->inp_rtableid),
@@ -1067,6 +1052,44 @@ in_pcbrehash_locked(struct inpcb *inp)
        LIST_INSERT_HEAD(head, inp, inp_hash);
 }
 
+struct inpcb *
+in_pcbhash_lookup(struct inpcbtable *table, u_int rdomain,
+    const struct in_addr *faddr, u_short fport,
+    const struct in_addr *laddr, u_short lport)
+{
+       struct inpcbhead *head;
+       struct inpcb *inp;
+
+       NET_ASSERT_LOCKED();
+       MUTEX_ASSERT_LOCKED(&table->inpt_mtx);
+
+       head = in_pcbhash(table, rdomain, faddr, fport, laddr, lport);
+       LIST_FOREACH(inp, head, inp_hash) {
+#ifdef INET6
+               if (ISSET(inp->inp_flags, INP_IPV6))
+                       continue;
+#endif
+               if (inp->inp_fport == fport && inp->inp_lport == lport &&
+                   inp->inp_faddr.s_addr == faddr->s_addr &&
+                   inp->inp_laddr.s_addr == laddr->s_addr &&
+                   rtable_l2(inp->inp_rtableid) == rdomain) {
+                       break;
+               }
+       }
+       if (inp != NULL) {
+               /*
+                * Move this PCB to the head of hash chain so that
+                * repeated accesses are quicker.  This is analogous to
+                * the historic single-entry PCB cache.
+                */
+               if (inp != LIST_FIRST(head)) {
+                       LIST_REMOVE(inp, inp_hash);
+                       LIST_INSERT_HEAD(head, inp, inp_hash);
+               }
+       }
+       return (inp);
+}
+
 int
 in_pcbresize(struct inpcbtable *table, int hashsize)
 {
@@ -1098,7 +1121,9 @@ in_pcbresize(struct inpcbtable *table, int hashsize)
        arc4random_buf(&table->inpt_lkey, sizeof(table->inpt_lkey));
 
        TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) {
-               in_pcbrehash_locked(inp);
+               LIST_REMOVE(inp, inp_lhash);
+               LIST_REMOVE(inp, inp_hash);
+               in_pcbhash_insert(inp);
        }
        hashfree(ohashtbl, osize, M_PCB);
        hashfree(olhashtbl, osize, M_PCB);
@@ -1111,7 +1136,7 @@ int       in_pcbnotifymiss = 0;
 #endif
 
 /*
- * The in(6)_pcbhashlookup functions are used to locate connected sockets
+ * The in(6)_pcblookup functions are used to locate connected sockets
  * quickly:
  *     faddr.fport <-> laddr.lport
  * No wildcard matching is done so that listening sockets are not found.
@@ -1120,38 +1145,15 @@ int     in_pcbnotifymiss = 0;
  * After those two lookups no other are necessary.
  */
 struct inpcb *
-in_pcbhashlookup(struct inpcbtable *table, struct in_addr faddr,
-    u_int fport_arg, struct in_addr laddr, u_int lport_arg, u_int rtable)
+in_pcblookup(struct inpcbtable *table, struct in_addr faddr,
+    u_int fport, struct in_addr laddr, u_int lport, u_int rtable)
 {
-       struct inpcbhead *head;
        struct inpcb *inp;
-       u_int16_t fport = fport_arg, lport = lport_arg;
        u_int rdomain;
 
        rdomain = rtable_l2(rtable);
        mtx_enter(&table->inpt_mtx);
-       head = in_pcbhash(table, rdomain, &faddr, fport, &laddr, lport);
-       LIST_FOREACH(inp, head, inp_hash) {
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6)
-                       continue;       /*XXX*/
-#endif
-               if (inp->inp_faddr.s_addr == faddr.s_addr &&
-                   inp->inp_fport == fport && inp->inp_lport == lport &&
-                   inp->inp_laddr.s_addr == laddr.s_addr &&
-                   rtable_l2(inp->inp_rtableid) == rdomain) {
-                       /*
-                        * Move this PCB to the head of hash chain so that
-                        * repeated accesses are quicker.  This is analogous to
-                        * the historic single-entry PCB cache.
-                        */
-                       if (inp != LIST_FIRST(head)) {
-                               LIST_REMOVE(inp, inp_hash);
-                               LIST_INSERT_HEAD(head, inp, inp_hash);
-                       }
-                       break;
-               }
-       }
+       inp = in_pcbhash_lookup(table, rdomain, &faddr, fport, &laddr, lport);
        in_pcbref(inp);
        mtx_leave(&table->inpt_mtx);
 #ifdef DIAGNOSTIC
@@ -1175,7 +1177,6 @@ struct inpcb *
 in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
     u_int lport_arg, struct mbuf *m, u_int rtable)
 {
-       struct inpcbhead *head;
        const struct in_addr *key1, *key2;
        struct inpcb *inp;
        u_int16_t lport = lport_arg;
@@ -1216,41 +1217,10 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
 
        rdomain = rtable_l2(rtable);
        mtx_enter(&table->inpt_mtx);
-       head = in_pcbhash(table, rdomain, &zeroin_addr, 0, key1, lport);
-       LIST_FOREACH(inp, head, inp_hash) {
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6)
-                       continue;       /*XXX*/
-#endif
-               if (inp->inp_lport == lport && inp->inp_fport == 0 &&
-                   inp->inp_laddr.s_addr == key1->s_addr &&
-                   inp->inp_faddr.s_addr == INADDR_ANY &&
-                   rtable_l2(inp->inp_rtableid) == rdomain)
-                       break;
-       }
+       inp = in_pcbhash_lookup(table, rdomain, &zeroin_addr, 0, key1, lport);
        if (inp == NULL && key1->s_addr != key2->s_addr) {
-               head = in_pcbhash(table, rdomain,
+               inp = in_pcbhash_lookup(table, rdomain,
                    &zeroin_addr, 0, key2, lport);
-               LIST_FOREACH(inp, head, inp_hash) {
-#ifdef INET6
-                       if (inp->inp_flags & INP_IPV6)
-                               continue;       /*XXX*/
-#endif
-                       if (inp->inp_lport == lport && inp->inp_fport == 0 &&
-                           inp->inp_laddr.s_addr == key2->s_addr &&
-                           inp->inp_faddr.s_addr == INADDR_ANY &&
-                           rtable_l2(inp->inp_rtableid) == rdomain)
-                               break;
-               }
-       }
-       /*
-        * Move this PCB to the head of hash chain so that
-        * repeated accesses are quicker.  This is analogous to
-        * the historic single-entry PCB cache.
-        */
-       if (inp != NULL && inp != LIST_FIRST(head)) {
-               LIST_REMOVE(inp, inp_hash);
-               LIST_INSERT_HEAD(head, inp, inp_hash);
        }
        in_pcbref(inp);
        mtx_leave(&table->inpt_mtx);
index cc262a2..4726009 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in_pcb.h,v 1.131 2022/08/22 10:37:27 bluhm Exp $      */
+/*     $OpenBSD: in_pcb.h,v 1.132 2022/08/30 11:53:04 bluhm Exp $      */
 /*     $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $     */
 
 /*
@@ -288,17 +288,17 @@ struct inpcb *
 void    in_pcbunref(struct inpcb *);
 void    in_pcbdisconnect(struct inpcb *);
 struct inpcb *
-        in_pcbhashlookup(struct inpcbtable *, struct in_addr,
+        in_pcblookup(struct inpcbtable *, struct in_addr,
                               u_int, struct in_addr, u_int, u_int);
 struct inpcb *
         in_pcblookup_listen(struct inpcbtable *, struct in_addr, u_int,
            struct mbuf *, u_int);
 #ifdef INET6
 struct inpcbhead *
-        in6_pcbhash(struct inpcbtable *, int, const struct in6_addr *,
+        in6_pcbhash(struct inpcbtable *, u_int, const struct in6_addr *,
            u_short, const struct in6_addr *, u_short);
 struct inpcb *
-        in6_pcbhashlookup(struct inpcbtable *, const struct in6_addr *,
+        in6_pcblookup(struct inpcbtable *, const struct in6_addr *,
                               u_int, const struct in6_addr *, u_int, u_int);
 struct inpcb *
         in6_pcblookup_listen(struct inpcbtable *, struct in6_addr *, u_int,
index a6c5962..59ef806 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_input.c,v 1.378 2022/08/21 16:22:17 mvs Exp $     */
+/*     $OpenBSD: tcp_input.c,v 1.379 2022/08/30 11:53:04 bluhm Exp $   */
 /*     $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $  */
 
 /*
@@ -531,13 +531,13 @@ findpcb:
                switch (af) {
 #ifdef INET6
                case AF_INET6:
-                       inp = in6_pcbhashlookup(&tcbtable, &ip6->ip6_src,
+                       inp = in6_pcblookup(&tcbtable, &ip6->ip6_src,
                            th->th_sport, &ip6->ip6_dst, th->th_dport,
                            m->m_pkthdr.ph_rtableid);
                        break;
 #endif
                case AF_INET:
-                       inp = in_pcbhashlookup(&tcbtable, ip->ip_src,
+                       inp = in_pcblookup(&tcbtable, ip->ip_src,
                            th->th_sport, ip->ip_dst, th->th_dport,
                            m->m_pkthdr.ph_rtableid);
                        break;
index b7d5eb2..53be810 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_subr.c,v 1.185 2022/08/08 12:06:30 bluhm Exp $    */
+/*     $OpenBSD: tcp_subr.c,v 1.186 2022/08/30 11:53:04 bluhm Exp $    */
 /*     $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $   */
 
 /*
@@ -661,7 +661,7 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d)
                 * corresponding to the address in the ICMPv6 message
                 * payload.
                 */
-               inp = in6_pcbhashlookup(&tcbtable, &sa6->sin6_addr,
+               inp = in6_pcblookup(&tcbtable, &sa6->sin6_addr,
                    th.th_dport, &sa6_src->sin6_addr, th.th_sport, rdomain);
                if (cmd == PRC_MSGSIZE) {
                        /*
@@ -733,7 +733,7 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
                 */
                th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
                seq = ntohl(th->th_seq);
-               inp = in_pcbhashlookup(&tcbtable,
+               inp = in_pcblookup(&tcbtable,
                    ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport,
                    rdomain);
                if (inp && (tp = intotcpcb(inp)) &&
@@ -798,7 +798,7 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
 
        if (ip) {
                th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
-               inp = in_pcbhashlookup(&tcbtable,
+               inp = in_pcblookup(&tcbtable,
                    ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport,
                    rdomain);
                if (inp) {
index 44722fd..539c086 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tcp_usrreq.c,v 1.200 2022/08/29 09:50:38 mbuhl Exp $  */
+/*     $OpenBSD: tcp_usrreq.c,v 1.201 2022/08/30 11:53:04 bluhm Exp $  */
 /*     $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
 
 /*
@@ -1156,12 +1156,12 @@ tcp_ident(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int dodrop)
        switch (tir.faddr.ss_family) {
 #ifdef INET6
        case AF_INET6:
-               inp = in6_pcbhashlookup(&tcbtable, &f6,
+               inp = in6_pcblookup(&tcbtable, &f6,
                    fin6->sin6_port, &l6, lin6->sin6_port, tir.rdomain);
                break;
 #endif
        case AF_INET:
-               inp = in_pcbhashlookup(&tcbtable, fin->sin_addr,
+               inp = in_pcblookup(&tcbtable, fin->sin_addr,
                    fin->sin_port, lin->sin_addr, lin->sin_port, tir.rdomain);
                break;
        default:
index ea39aaa..938df27 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: udp_usrreq.c,v 1.295 2022/08/30 09:35:24 bluhm Exp $  */
+/*     $OpenBSD: udp_usrreq.c,v 1.296 2022/08/30 11:53:04 bluhm Exp $  */
 /*     $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
 
 /*
@@ -488,12 +488,12 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af)
        if (inp == NULL) {
 #ifdef INET6
                if (ip6)
-                       inp = in6_pcbhashlookup(&udbtable, &ip6->ip6_src,
+                       inp = in6_pcblookup(&udbtable, &ip6->ip6_src,
                            uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
                            m->m_pkthdr.ph_rtableid);
                else
 #endif /* INET6 */
-               inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
+               inp = in_pcblookup(&udbtable, ip->ip_src, uh->uh_sport,
                    ip->ip_dst, uh->uh_dport, m->m_pkthdr.ph_rtableid);
        }
        if (inp == NULL) {
@@ -789,7 +789,7 @@ udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d)
                         * corresponding to the address in the ICMPv6 message
                         * payload.
                         */
-                       inp = in6_pcbhashlookup(&udbtable, &sa6.sin6_addr,
+                       inp = in6_pcblookup(&udbtable, &sa6.sin6_addr,
                            uh.uh_dport, &sa6_src.sin6_addr, uh.uh_sport,
                            rdomain);
 #if 0
@@ -875,7 +875,7 @@ udp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
                        return;
                }
 #endif
-               inp = in_pcbhashlookup(&udbtable,
+               inp = in_pcblookup(&udbtable,
                    ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport,
                    rdomain);
                if (inp && inp->inp_socket != NULL)
index 471a961..8825c7f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6_pcb.c,v 1.120 2022/08/22 10:37:27 bluhm Exp $     */
+/*     $OpenBSD: in6_pcb.c,v 1.121 2022/08/30 11:53:04 bluhm Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 
 const struct in6_addr zeroin6_addr;
 
+struct inpcb *in6_pcbhash_lookup(struct inpcbtable *, u_int,
+    const struct in6_addr *, u_short, const struct in6_addr *, u_short);
+
 struct inpcbhead *
-in6_pcbhash(struct inpcbtable *table, int rdom,
+in6_pcbhash(struct inpcbtable *table, u_int rdomain,
     const struct in6_addr *faddr, u_short fport,
     const struct in6_addr *laddr, u_short lport)
 {
        SIPHASH_CTX ctx;
-       u_int32_t nrdom = htonl(rdom);
+       u_int32_t nrdom = htonl(rdomain);
 
        SipHash24_Init(&ctx, &table->inpt_key);
        SipHash24_Update(&ctx, &nrdom, sizeof(nrdom));
@@ -280,7 +283,7 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam)
 
        inp->inp_ipv6.ip6_hlim = (u_int8_t)in6_selecthlim(inp);
 
-       t = in6_pcbhashlookup(inp->inp_table, &sin6->sin6_addr, sin6->sin6_port,
+       t = in6_pcblookup(inp->inp_table, &sin6->sin6_addr, sin6->sin6_port,
            IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) ? in6a : &inp->inp_laddr6,
            inp->inp_lport, inp->inp_rtableid);
        if (t != NULL) {
@@ -295,7 +298,7 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam)
                        error = in_pcbbind(inp, NULL, curproc);
                        if (error)
                                return (error);
-                       t = in6_pcbhashlookup(inp->inp_table, &sin6->sin6_addr,
+                       t = in6_pcblookup(inp->inp_table, &sin6->sin6_addr,
                            sin6->sin6_port, in6a, inp->inp_lport,
                            inp->inp_rtableid);
                        if (t != NULL) {
@@ -516,37 +519,51 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst,
 }
 
 struct inpcb *
-in6_pcbhashlookup(struct inpcbtable *table, const struct in6_addr *faddr,
-    u_int fport_arg, const struct in6_addr *laddr, u_int lport_arg,
-    u_int rtable)
+in6_pcbhash_lookup(struct inpcbtable *table, u_int rdomain,
+    const struct in6_addr *faddr, u_short fport,
+    const struct in6_addr *laddr, u_short lport)
 {
        struct inpcbhead *head;
        struct inpcb *inp;
-       u_int16_t fport = fport_arg, lport = lport_arg;
-       u_int rdomain;
 
-       rdomain = rtable_l2(rtable);
-       mtx_enter(&table->inpt_mtx);
+       NET_ASSERT_LOCKED();
+       MUTEX_ASSERT_LOCKED(&table->inpt_mtx);
+
        head = in6_pcbhash(table, rdomain, faddr, fport, laddr, lport);
        LIST_FOREACH(inp, head, inp_hash) {
-               if (!(inp->inp_flags & INP_IPV6))
+               if (!ISSET(inp->inp_flags, INP_IPV6))
                        continue;
-               if (IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, faddr) &&
-                   inp->inp_fport == fport && inp->inp_lport == lport &&
+               if (inp->inp_fport == fport && inp->inp_lport == lport &&
+                   IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, faddr) &&
                    IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr) &&
                    rtable_l2(inp->inp_rtableid) == rdomain) {
-                       /*
-                        * Move this PCB to the head of hash chain so that
-                        * repeated accesses are quicker.  This is analogous to
-                        * the historic single-entry PCB cache.
-                        */
-                       if (inp != LIST_FIRST(head)) {
-                               LIST_REMOVE(inp, inp_hash);
-                               LIST_INSERT_HEAD(head, inp, inp_hash);
-                       }
                        break;
                }
        }
+       if (inp != NULL) {
+               /*
+                * Move this PCB to the head of hash chain so that
+                * repeated accesses are quicker.  This is analogous to
+                * the historic single-entry PCB cache.
+                */
+               if (inp != LIST_FIRST(head)) {
+                       LIST_REMOVE(inp, inp_hash);
+                       LIST_INSERT_HEAD(head, inp, inp_hash);
+               }
+       }
+       return (inp);
+}
+
+struct inpcb *
+in6_pcblookup(struct inpcbtable *table, const struct in6_addr *faddr,
+    u_int fport, const struct in6_addr *laddr, u_int lport, u_int rtable)
+{
+       struct inpcb *inp;
+       u_int rdomain;
+
+       rdomain = rtable_l2(rtable);
+       mtx_enter(&table->inpt_mtx);
+       inp = in6_pcbhash_lookup(table, rdomain, faddr, fport, laddr, lport);
        in_pcbref(inp);
        mtx_leave(&table->inpt_mtx);
 #ifdef DIAGNOSTIC
@@ -560,12 +577,10 @@ in6_pcbhashlookup(struct inpcbtable *table, const struct in6_addr *faddr,
 
 struct inpcb *
 in6_pcblookup_listen(struct inpcbtable *table, struct in6_addr *laddr,
-    u_int lport_arg, struct mbuf *m, u_int rtable)
+    u_int lport, struct mbuf *m, u_int rtable)
 {
-       struct inpcbhead *head;
        const struct in6_addr *key1, *key2;
        struct inpcb *inp;
-       u_int16_t lport = lport_arg;
        u_int rdomain;
 
        key1 = laddr;
@@ -600,37 +615,10 @@ in6_pcblookup_listen(struct inpcbtable *table, struct in6_addr *laddr,
 
        rdomain = rtable_l2(rtable);
        mtx_enter(&table->inpt_mtx);
-       head = in6_pcbhash(table, rdomain, &zeroin6_addr, 0, key1, lport);
-       LIST_FOREACH(inp, head, inp_hash) {
-               if (!(inp->inp_flags & INP_IPV6))
-                       continue;
-               if (inp->inp_lport == lport && inp->inp_fport == 0 &&
-                   IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, key1) &&
-                   IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6) &&
-                   rtable_l2(inp->inp_rtableid) == rdomain)
-                       break;
-       }
+       inp = in6_pcbhash_lookup(table, rdomain, &zeroin6_addr, 0, key1, lport);
        if (inp == NULL && ! IN6_ARE_ADDR_EQUAL(key1, key2)) {
-               head = in6_pcbhash(table, rdomain,
+               inp = in6_pcbhash_lookup(table, rdomain,
                    &zeroin6_addr, 0, key2, lport);
-               LIST_FOREACH(inp, head, inp_hash) {
-                       if (!(inp->inp_flags & INP_IPV6))
-                               continue;
-                       if (inp->inp_lport == lport && inp->inp_fport == 0 &&
-                           IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, key2) &&
-                           IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6) &&
-                           rtable_l2(inp->inp_rtableid) == rdomain)
-                               break;
-               }
-       }
-       /*
-        * Move this PCB to the head of hash chain so that
-        * repeated accesses are quicker.  This is analogous to
-        * the historic single-entry PCB cache.
-        */
-       if (inp != NULL && inp != LIST_FIRST(head)) {
-               LIST_REMOVE(inp, inp_hash);
-               LIST_INSERT_HEAD(head, inp, inp_hash);
        }
        in_pcbref(inp);
        mtx_leave(&table->inpt_mtx);
index 00fe919..bd50d72 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: raw_ip6.c,v 1.162 2022/08/29 08:08:17 mvs Exp $       */
+/*     $OpenBSD: raw_ip6.c,v 1.163 2022/08/30 11:53:04 bluhm Exp $     */
 /*     $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $        */
 
 /*
@@ -331,7 +331,7 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d)
                 * XXX chase extension headers, or pass final nxt value
                 * from icmp6_notify_error()
                 */
-               in6p = in6_pcbhashlookup(&rawin6pcbtable, &sa6->sin6_addr, 0,
+               in6p = in6_pcblookup(&rawin6pcbtable, &sa6->sin6_addr, 0,
                    &sa6_src->sin6_addr, 0, rdomain);
 
                if (in6p && in6p->inp_ipv6.ip6_nxt &&