-/* $OpenBSD: in_pcb.c,v 1.276 2022/10/03 16:43:52 bluhm Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.277 2023/06/24 20:54:46 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
struct pool inpcb_pool;
void in_pcbhash_insert(struct inpcb *);
-struct inpcb *in_pcbhash_lookup(struct inpcbtable *, u_int,
+struct inpcb *in_pcbhash_lookup(struct inpcbtable *, uint64_t, 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 *, u_int,
+uint64_t in_pcbhash(struct inpcbtable *, u_int,
const struct in_addr *, u_short, const struct in_addr *, u_short);
-struct inpcbhead *in_pcblhash(struct inpcbtable *, u_int, u_short);
+uint64_t in_pcblhash(struct inpcbtable *, u_int, u_short);
/*
* in_pcb is used for inet and inet6. in6_pcb only contains special
IPL_SOFTNET, 0, "inpcb", NULL);
}
-struct inpcbhead *
+uint64_t
in_pcbhash(struct inpcbtable *table, u_int rdomain,
const struct in_addr *faddr, u_short fport,
const struct in_addr *laddr, u_short lport)
SipHash24_Update(&ctx, &fport, sizeof(fport));
SipHash24_Update(&ctx, laddr, sizeof(*laddr));
SipHash24_Update(&ctx, &lport, sizeof(lport));
-
- return (&table->inpt_hashtbl[SipHash24_End(&ctx) & table->inpt_mask]);
+ return SipHash24_End(&ctx);
}
-struct inpcbhead *
+uint64_t
in_pcblhash(struct inpcbtable *table, u_int rdomain, u_short lport)
{
SIPHASH_CTX ctx;
SipHash24_Init(&ctx, &table->inpt_lkey);
SipHash24_Update(&ctx, &nrdom, sizeof(nrdom));
SipHash24_Update(&ctx, &lport, sizeof(lport));
-
- return (&table->inpt_lhashtbl[SipHash24_End(&ctx) & table->inpt_lmask]);
+ return SipHash24_End(&ctx);
}
void
struct in6_addr *laddr6 = (struct in6_addr *)laddrp;
#endif
struct inpcbhead *head;
+ uint64_t lhash;
u_int rdomain;
rdomain = rtable_l2(rtable);
+ lhash = in_pcblhash(table, rdomain, lport);
+
mtx_enter(&table->inpt_mtx);
- head = in_pcblhash(table, rdomain, lport);
+ head = &table->inpt_lhashtbl[lhash & table->inpt_lmask];
LIST_FOREACH(inp, head, inp_lhash) {
if (rtable_l2(inp->inp_rtableid) != rdomain)
continue;
{
struct inpcbtable *table = inp->inp_table;
struct inpcbhead *head;
+ uint64_t hash, lhash;
- NET_ASSERT_LOCKED();
MUTEX_ASSERT_LOCKED(&table->inpt_mtx);
- head = in_pcblhash(table, inp->inp_rtableid, inp->inp_lport);
+ lhash = in_pcblhash(table, inp->inp_rtableid, inp->inp_lport);
+ head = &table->inpt_lhashtbl[lhash & table->inpt_lmask];
LIST_INSERT_HEAD(head, inp, inp_lhash);
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
- head = in6_pcbhash(table, rtable_l2(inp->inp_rtableid),
+ hash = 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),
+ hash = in_pcbhash(table, rtable_l2(inp->inp_rtableid),
&inp->inp_faddr, inp->inp_fport,
&inp->inp_laddr, inp->inp_lport);
+ head = &table->inpt_hashtbl[hash & table->inpt_mask];
LIST_INSERT_HEAD(head, inp, inp_hash);
}
struct inpcb *
-in_pcbhash_lookup(struct inpcbtable *table, u_int rdomain,
+in_pcbhash_lookup(struct inpcbtable *table, uint64_t hash, 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);
+ head = &table->inpt_hashtbl[hash & table->inpt_mask];
LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
if (ISSET(inp->inp_flags, INP_IPV6))
table->inpt_mask = nmask;
table->inpt_lmask = nlmask;
table->inpt_size = hashsize;
- arc4random_buf(&table->inpt_key, sizeof(table->inpt_key));
- arc4random_buf(&table->inpt_lkey, sizeof(table->inpt_lkey));
TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) {
LIST_REMOVE(inp, inp_lhash);
u_int fport, struct in_addr laddr, u_int lport, u_int rtable)
{
struct inpcb *inp;
+ uint64_t hash;
u_int rdomain;
rdomain = rtable_l2(rtable);
+ hash = in_pcbhash(table, rdomain, &faddr, fport, &laddr, lport);
+
mtx_enter(&table->inpt_mtx);
- inp = in_pcbhash_lookup(table, rdomain, &faddr, fport, &laddr, lport);
+ inp = in_pcbhash_lookup(table, hash, rdomain,
+ &faddr, fport, &laddr, lport);
in_pcbref(inp);
mtx_leave(&table->inpt_mtx);
+
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: faddr=%08x fport=%d laddr=%08x lport=%d rdom=%u\n",
{
const struct in_addr *key1, *key2;
struct inpcb *inp;
+ uint64_t hash;
u_int16_t lport = lport_arg;
u_int rdomain;
#endif
rdomain = rtable_l2(rtable);
+ hash = in_pcbhash(table, rdomain, &zeroin_addr, 0, key1, lport);
+
mtx_enter(&table->inpt_mtx);
- inp = in_pcbhash_lookup(table, rdomain, &zeroin_addr, 0, key1, lport);
+ inp = in_pcbhash_lookup(table, hash, rdomain,
+ &zeroin_addr, 0, key1, lport);
if (inp == NULL && key1->s_addr != key2->s_addr) {
- inp = in_pcbhash_lookup(table, rdomain,
+ hash = in_pcbhash(table, rdomain,
+ &zeroin_addr, 0, key2, lport);
+ inp = in_pcbhash_lookup(table, hash, rdomain,
&zeroin_addr, 0, key2, lport);
}
in_pcbref(inp);
mtx_leave(&table->inpt_mtx);
+
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: laddr=%08x lport=%d rdom=%u\n",
-/* $OpenBSD: in6_pcb.c,v 1.123 2022/09/03 22:43:38 mvs Exp $ */
+/* $OpenBSD: in6_pcb.c,v 1.124 2023/06/24 20:54:46 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,
+struct inpcb *in6_pcbhash_lookup(struct inpcbtable *, uint64_t, u_int,
const struct in6_addr *, u_short, const struct in6_addr *, u_short);
-struct inpcbhead *
+uint64_t
in6_pcbhash(struct inpcbtable *table, u_int rdomain,
const struct in6_addr *faddr, u_short fport,
const struct in6_addr *laddr, u_short lport)
SipHash24_Update(&ctx, &fport, sizeof(fport));
SipHash24_Update(&ctx, laddr, sizeof(*laddr));
SipHash24_Update(&ctx, &lport, sizeof(lport));
-
- return (&table->inpt_hashtbl[SipHash24_End(&ctx) & table->inpt_mask]);
+ return SipHash24_End(&ctx);
}
int
}
struct inpcb *
-in6_pcbhash_lookup(struct inpcbtable *table, u_int rdomain,
+in6_pcbhash_lookup(struct inpcbtable *table, uint64_t hash, u_int rdomain,
const struct in6_addr *faddr, u_short fport,
const struct in6_addr *laddr, u_short lport)
{
NET_ASSERT_LOCKED();
MUTEX_ASSERT_LOCKED(&table->inpt_mtx);
- head = in6_pcbhash(table, rdomain, faddr, fport, laddr, lport);
+ head = &table->inpt_hashtbl[hash & table->inpt_mask];
LIST_FOREACH(inp, head, inp_hash) {
if (!ISSET(inp->inp_flags, INP_IPV6))
continue;
u_int fport, const struct in6_addr *laddr, u_int lport, u_int rtable)
{
struct inpcb *inp;
+ uint64_t hash;
u_int rdomain;
rdomain = rtable_l2(rtable);
+ hash = in6_pcbhash(table, rdomain, faddr, fport, laddr, lport);
+
mtx_enter(&table->inpt_mtx);
- inp = in6_pcbhash_lookup(table, rdomain, faddr, fport, laddr, lport);
+ inp = in6_pcbhash_lookup(table, hash, rdomain,
+ faddr, fport, laddr, lport);
in_pcbref(inp);
mtx_leave(&table->inpt_mtx);
+
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: faddr= fport=%d laddr= lport=%d rdom=%u\n",
{
const struct in6_addr *key1, *key2;
struct inpcb *inp;
+ uint64_t hash;
u_int rdomain;
key1 = laddr;
#endif
rdomain = rtable_l2(rtable);
+ hash = in6_pcbhash(table, rdomain, &zeroin6_addr, 0, key1, lport);
+
mtx_enter(&table->inpt_mtx);
- inp = in6_pcbhash_lookup(table, rdomain, &zeroin6_addr, 0, key1, lport);
+ inp = in6_pcbhash_lookup(table, hash, rdomain,
+ &zeroin6_addr, 0, key1, lport);
if (inp == NULL && ! IN6_ARE_ADDR_EQUAL(key1, key2)) {
- inp = in6_pcbhash_lookup(table, rdomain,
+ hash = in6_pcbhash(table, rdomain,
+ &zeroin6_addr, 0, key2, lport);
+ inp = in6_pcbhash_lookup(table, hash, rdomain,
&zeroin6_addr, 0, key2, lport);
}
in_pcbref(inp);
mtx_leave(&table->inpt_mtx);
+
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
printf("%s: laddr= lport=%d rdom=%u\n",