Index: netinet/in_pcb.c =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.67 diff -u -r1.67 in_pcb.c --- netinet/in_pcb.c 15 Aug 2003 20:32:20 -0000 1.67 +++ netinet/in_pcb.c 24 Oct 2003 08:53:33 -0000 @@ -117,6 +117,9 @@ (faddr)->s6_addr32[3]) + ntohs((fport)) + ntohs((lport))) & \ (table->inpt_hash)] +#define INPCBLHASH(table, lport) \ + &(table)->inpt_lhashtbl[lport & table->inpt_lhash] + void in_pcbinit(table, hashsize) struct inpcbtable *table; @@ -124,9 +127,14 @@ { CIRCLEQ_INIT(&table->inpt_queue); - table->inpt_hashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, &table->inpt_hash); + table->inpt_hashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, + &table->inpt_hash); if (table->inpt_hashtbl == NULL) panic("in_pcbinit: hashinit failed"); + table->inpt_lhashtbl = hashinit(hashsize, M_PCB, M_NOWAIT, + &table->inpt_lhash); + if (table->inpt_lhashtbl == NULL) + panic("in_pcbinit: hashinit failed for lport"); table->inpt_lastport = 0; } @@ -175,6 +183,7 @@ inp->inp_seclevel[SL_IPCOMP] = ipsec_ipcomp_default_level; s = splnet(); CIRCLEQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); + LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport), inp, inp_lhash); LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, inp->inp_fport, &inp->inp_laddr, inp->inp_lport), inp, inp_hash); splx(s); @@ -496,6 +505,7 @@ splx(s); #endif s = splnet(); + LIST_REMOVE(inp, inp_lhash); LIST_REMOVE(inp, inp_hash); CIRCLEQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); splx(s); @@ -713,9 +723,8 @@ struct in_addr faddr = *(struct in_addr *)faddrp; struct in_addr laddr = *(struct in_addr *)laddrp; - for (inp = table->inpt_queue.cqh_first; - inp != (struct inpcb *)&table->inpt_queue; - inp = inp->inp_queue.cqe_next) { + for (inp = LIST_FIRST(INPCBLHASH(table, lport)); inp; + inp = LIST_NEXT(inp, inp_lhash)) { if (inp->inp_lport != lport) continue; wildcard = 0; @@ -923,6 +932,8 @@ int s; s = splnet(); + LIST_REMOVE(inp, inp_lhash); + LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport), inp, inp_lhash); LIST_REMOVE(inp, inp_hash); #ifdef INET6 if (inp->inp_flags & INP_IPV6) { Index: netinet/in_pcb.h =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.h,v retrieving revision 1.45 diff -u -r1.45 in_pcb.h --- netinet/in_pcb.h 2 Jun 2003 23:28:14 -0000 1.45 +++ netinet/in_pcb.h 24 Oct 2003 08:53:33 -0000 @@ -87,10 +87,11 @@ */ struct inpcb { LIST_ENTRY(inpcb) inp_hash; + LIST_ENTRY(inpcb) inp_lhash; /* extra hash for lport */ CIRCLEQ_ENTRY(inpcb) inp_queue; struct inpcbtable *inp_table; - union inpaddru inp_faddru; /* Foreign address. */ - union inpaddru inp_laddru; /* Local address. */ + union inpaddru inp_faddru; /* Foreign address. */ + union inpaddru inp_laddru; /* Local address. */ #define inp_faddr inp_faddru.iau_a4u.inaddr #define inp_faddr6 inp_faddru.iau_addr6 #define inp_laddr inp_laddru.iau_a4u.inaddr @@ -147,8 +148,8 @@ struct inpcbtable { CIRCLEQ_HEAD(, inpcb) inpt_queue; - LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl; - u_long inpt_hash; + LIST_HEAD(inpcbhead, inpcb) *inpt_hashtbl, *inpt_lhashtbl; + u_long inpt_hash, inpt_lhash; u_int16_t inpt_lastport; };