-/* $OpenBSD: in_pcb.c,v 1.156 2014/06/04 13:45:47 mpi Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.157 2014/07/12 21:06:34 yasuoka Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
struct pool inpcb_pool;
int inpcb_pool_initialized = 0;
+int in_pcbresize (struct inpcbtable *, int);
+
+#define INPCBHASH_LOADFACTOR(_x) (((_x) * 3) / 4)
+
#define INPCBHASH(table, faddr, fport, laddr, lport, rdom) \
&(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \
ntohs((fport)) + ntohs((lport)) + (rdom)) & (table->inpt_hash)]
if (table->inpt_lhashtbl == NULL)
panic("in_pcbinit: hashinit failed for lport");
table->inpt_lastport = 0;
+ table->inpt_count = 0;
}
/*
inp->inp_seclevel[SL_IPCOMP] = IPSEC_IPCOMP_LEVEL_DEFAULT;
inp->inp_rtableid = curproc->p_p->ps_rtableid;
s = splnet();
+ if (table->inpt_hash != 0 &&
+ table->inpt_count++ > INPCBHASH_LOADFACTOR(table->inpt_hash))
+ (void)in_pcbresize(table, (table->inpt_hash + 1) * 2);
TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue);
LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport,
inp->inp_rtableid), inp, inp_lhash);
LIST_REMOVE(inp, inp_lhash);
LIST_REMOVE(inp, inp_hash);
TAILQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue);
+ inp->inp_table->inpt_count--;
splx(s);
pool_put(&inpcb_pool, inp);
}
splx(s);
}
+int
+in_pcbresize(struct inpcbtable *table, int hashsize)
+{
+ u_long nhash, nlhash;
+ void *nhashtbl, *nlhashtbl, *ohashtbl, *olhashtbl;
+ struct inpcb *inp0, *inp1;
+
+ ohashtbl = table->inpt_hashtbl;
+ olhashtbl = table->inpt_lhashtbl;
+
+ nhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nhash);
+ nlhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &nlhash);
+ if (nhashtbl == NULL || nlhashtbl == NULL) {
+ if (nhashtbl != NULL)
+ free(nhashtbl, M_PCB, 0);
+ if (nlhashtbl != NULL)
+ free(nlhashtbl, M_PCB, 0);
+ return (ENOBUFS);
+ }
+ table->inpt_hashtbl = nhashtbl;
+ table->inpt_lhashtbl = nlhashtbl;
+ table->inpt_hash = nhash;
+ table->inpt_lhash = nlhash;
+
+ TAILQ_FOREACH_SAFE(inp0, &table->inpt_queue, inp_queue, inp1) {
+ in_pcbrehash(inp0);
+ }
+ free(ohashtbl, M_PCB, 0);
+ free(olhashtbl, M_PCB, 0);
+
+ return (0);
+}
+
#ifdef DIAGNOSTIC
int in_pcbnotifymiss = 0;
#endif
-/* $OpenBSD: tcp_subr.c,v 1.130 2014/07/12 18:44:23 tedu Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.131 2014/07/12 21:06:34 yasuoka Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
u_int32_t tcp_now = 1;
-#ifndef TCBHASHSIZE
-#define TCBHASHSIZE 128
+#ifndef TCB_INITIAL_HASH_SIZE
+#define TCB_INITIAL_HASH_SIZE 128
#endif
-int tcbhashsize = TCBHASHSIZE;
/* syn hash parameters */
#define TCP_SYN_HASH_SIZE 293
NULL);
pool_sethardlimit(&sackhl_pool, tcp_sackhole_limit, NULL, 0);
#endif /* TCP_SACK */
- in_pcbinit(&tcbtable, tcbhashsize);
+ in_pcbinit(&tcbtable, TCB_INITIAL_HASH_SIZE);
#ifdef INET6
/*
-/* $OpenBSD: udp_usrreq.c,v 1.187 2014/07/11 13:15:34 bluhm Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.188 2014/07/12 21:06:34 yasuoka Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
void udp_detach(struct inpcb *);
void udp_notify(struct inpcb *, int);
-#ifndef UDBHASHSIZE
-#define UDBHASHSIZE 128
+#ifndef UDB_INITIAL_HASH_SIZE
+#define UDB_INITIAL_HASH_SIZE 128
#endif
-int udbhashsize = UDBHASHSIZE;
void
udp_init()
{
- in_pcbinit(&udbtable, udbhashsize);
+ in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE);
}
#ifdef INET6