Abstract out initialization of most aspects of struct inpcbinfo from

their calling contexts in {IP divert, raw IP sockets, TCP, UDP} and
create new helper functions: in_pcbinfo_init() and in_pcbinfo_destroy()
to do this work in a central spot.  As inpcbinfo becomes more complex
due to ongoing work to add connection groups, this will reduce code
duplication.

MFC after:      1 month
Reviewed by:    bz
Sponsored by:   Juniper Networks
This commit is contained in:
Robert Watson 2010-03-14 18:59:11 +00:00
parent 23aa9a76e3
commit 9bcd427b89
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=205157
6 changed files with 62 additions and 84 deletions

View file

@ -183,6 +183,47 @@ SYSCTL_VNET_INT(_net_inet_ip_portrange, OID_AUTO, randomtime, CTLFLAG_RW,
* functions often modify hash chains or addresses in pcbs. * functions often modify hash chains or addresses in pcbs.
*/ */
/*
* Initialize an inpcbinfo -- we should be able to reduce the number of
* arguments in time.
*/
void
in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name,
struct inpcbhead *listhead, int hash_nelements, int porthash_nelements,
char *inpcbzone_name, uma_init inpcbzone_init, uma_fini inpcbzone_fini,
uint32_t inpcbzone_flags)
{
INP_INFO_LOCK_INIT(pcbinfo, name);
#ifdef VIMAGE
pcbinfo->ipi_vnet = curvnet;
#endif
pcbinfo->ipi_listhead = listhead;
LIST_INIT(pcbinfo->ipi_listhead);
pcbinfo->ipi_hashbase = hashinit(hash_nelements, M_PCB,
&pcbinfo->ipi_hashmask);
pcbinfo->ipi_porthashbase = hashinit(porthash_nelements, M_PCB,
&pcbinfo->ipi_porthashmask);
pcbinfo->ipi_zone = uma_zcreate(inpcbzone_name, sizeof(struct inpcb),
NULL, NULL, inpcbzone_init, inpcbzone_fini, UMA_ALIGN_PTR,
inpcbzone_flags);
uma_zone_set_max(pcbinfo->ipi_zone, maxsockets);
}
/*
* Destroy an inpcbinfo.
*/
void
in_pcbinfo_destroy(struct inpcbinfo *pcbinfo)
{
hashdestroy(pcbinfo->ipi_hashbase, M_PCB, pcbinfo->ipi_hashmask);
hashdestroy(pcbinfo->ipi_porthashbase, M_PCB,
pcbinfo->ipi_porthashmask);
uma_zdestroy(pcbinfo->ipi_zone);
INP_INFO_LOCK_DESTROY(pcbinfo);
}
/* /*
* Allocate a PCB and associate it with the socket. * Allocate a PCB and associate it with the socket.
* On success return with the PCB locked. * On success return with the PCB locked.

View file

@ -42,6 +42,7 @@
#ifdef _KERNEL #ifdef _KERNEL
#include <sys/rwlock.h> #include <sys/rwlock.h>
#include <net/vnet.h> #include <net/vnet.h>
#include <vm/uma.h>
#endif #endif
#define in6pcb inpcb /* for KAME src sync over BSD*'s */ #define in6pcb inpcb /* for KAME src sync over BSD*'s */
@ -483,6 +484,10 @@ VNET_DECLARE(int, ipport_tcpallocs);
extern struct callout ipport_tick_callout; extern struct callout ipport_tick_callout;
void in_pcbinfo_destroy(struct inpcbinfo *);
void in_pcbinfo_init(struct inpcbinfo *, const char *, struct inpcbhead *,
int, int, char *, uma_init, uma_fini, uint32_t);
void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *); void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
int in_pcballoc(struct socket *, struct inpcbinfo *); int in_pcballoc(struct socket *, struct inpcbinfo *);
int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *); int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);

View file

@ -147,35 +147,20 @@ static void
div_init(void) div_init(void)
{ {
INP_INFO_LOCK_INIT(&V_divcbinfo, "div");
LIST_INIT(&V_divcb);
V_divcbinfo.ipi_listhead = &V_divcb;
#ifdef VIMAGE
V_divcbinfo.ipi_vnet = curvnet;
#endif
/* /*
* XXX We don't use the hash list for divert IP, but it's easier * XXX We don't use the hash list for divert IP, but it's easier to
* to allocate a one entry hash list than it is to check all * allocate one-entry hash lists than it is to check all over the
* over the place for hashbase == NULL. * place for hashbase == NULL.
*/ */
V_divcbinfo.ipi_hashbase = hashinit(1, M_PCB, &V_divcbinfo.ipi_hashmask); in_pcbinfo_init(&V_divcbinfo, "div", &V_divcb, 1, 1, "divcb",
V_divcbinfo.ipi_porthashbase = hashinit(1, M_PCB, div_inpcb_init, div_inpcb_fini, UMA_ZONE_NOFREE);
&V_divcbinfo.ipi_porthashmask);
V_divcbinfo.ipi_zone = uma_zcreate("divcb", sizeof(struct inpcb),
NULL, NULL, div_inpcb_init, div_inpcb_fini, UMA_ALIGN_PTR,
UMA_ZONE_NOFREE);
uma_zone_set_max(V_divcbinfo.ipi_zone, maxsockets);
} }
static void static void
div_destroy(void) div_destroy(void)
{ {
INP_INFO_LOCK_DESTROY(&V_divcbinfo); in_pcbinfo_destroy(&V_divcbinfo);
uma_zdestroy(V_divcbinfo.ipi_zone);
hashdestroy(V_divcbinfo.ipi_hashbase, M_PCB, V_divcbinfo.ipi_hashmask);
hashdestroy(V_divcbinfo.ipi_porthashbase, M_PCB,
V_divcbinfo.ipi_porthashmask);
} }
/* /*

View file

@ -185,19 +185,8 @@ void
rip_init(void) rip_init(void)
{ {
INP_INFO_LOCK_INIT(&V_ripcbinfo, "rip"); in_pcbinfo_init(&V_ripcbinfo, "rip", &V_ripcb, INP_PCBHASH_RAW_SIZE,
LIST_INIT(&V_ripcb); 1, "ripcb", rip_inpcb_init, NULL, UMA_ZONE_NOFREE);
#ifdef VIMAGE
V_ripcbinfo.ipi_vnet = curvnet;
#endif
V_ripcbinfo.ipi_listhead = &V_ripcb;
V_ripcbinfo.ipi_hashbase =
hashinit(INP_PCBHASH_RAW_SIZE, M_PCB, &V_ripcbinfo.ipi_hashmask);
V_ripcbinfo.ipi_porthashbase =
hashinit(1, M_PCB, &V_ripcbinfo.ipi_porthashmask);
V_ripcbinfo.ipi_zone = uma_zcreate("ripcb", sizeof(struct inpcb),
NULL, NULL, rip_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_ripcbinfo.ipi_zone, maxsockets);
EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL, EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
EVENTHANDLER_PRI_ANY); EVENTHANDLER_PRI_ANY);
} }
@ -207,10 +196,7 @@ void
rip_destroy(void) rip_destroy(void)
{ {
hashdestroy(V_ripcbinfo.ipi_hashbase, M_PCB, in_pcbinfo_destroy(&V_ripcbinfo);
V_ripcbinfo.ipi_hashmask);
hashdestroy(V_ripcbinfo.ipi_porthashbase, M_PCB,
V_ripcbinfo.ipi_porthashmask);
} }
#endif #endif

View file

@ -376,25 +376,15 @@ tcp_init(void)
TUNABLE_INT_FETCH("net.inet.tcp.sack.enable", &V_tcp_do_sack); TUNABLE_INT_FETCH("net.inet.tcp.sack.enable", &V_tcp_do_sack);
INP_INFO_LOCK_INIT(&V_tcbinfo, "tcp");
LIST_INIT(&V_tcb);
#ifdef VIMAGE
V_tcbinfo.ipi_vnet = curvnet;
#endif
V_tcbinfo.ipi_listhead = &V_tcb;
hashsize = TCBHASHSIZE; hashsize = TCBHASHSIZE;
TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize); TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize);
if (!powerof2(hashsize)) { if (!powerof2(hashsize)) {
printf("WARNING: TCB hash size not a power of 2\n"); printf("WARNING: TCB hash size not a power of 2\n");
hashsize = 512; /* safe default */ hashsize = 512; /* safe default */
} }
V_tcbinfo.ipi_hashbase = hashinit(hashsize, M_PCB, in_pcbinfo_init(&V_tcbinfo, "tcp", &V_tcb, hashsize, hashsize,
&V_tcbinfo.ipi_hashmask); "tcp_inpcb", tcp_inpcb_init, NULL, UMA_ZONE_NOFREE);
V_tcbinfo.ipi_porthashbase = hashinit(hashsize, M_PCB,
&V_tcbinfo.ipi_porthashmask);
V_tcbinfo.ipi_zone = uma_zcreate("tcp_inpcb", sizeof(struct inpcb),
NULL, NULL, tcp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_tcbinfo.ipi_zone, maxsockets);
/* /*
* These have to be type stable for the benefit of the timers. * These have to be type stable for the benefit of the timers.
*/ */
@ -463,18 +453,9 @@ tcp_destroy(void)
tcp_hc_destroy(); tcp_hc_destroy();
syncache_destroy(); syncache_destroy();
tcp_tw_destroy(); tcp_tw_destroy();
in_pcbinfo_destroy(&V_tcbinfo);
/* XXX check that hashes are empty! */
hashdestroy(V_tcbinfo.ipi_hashbase, M_PCB,
V_tcbinfo.ipi_hashmask);
hashdestroy(V_tcbinfo.ipi_porthashbase, M_PCB,
V_tcbinfo.ipi_porthashmask);
uma_zdestroy(V_sack_hole_zone); uma_zdestroy(V_sack_hole_zone);
uma_zdestroy(V_tcpcb_zone); uma_zdestroy(V_tcpcb_zone);
uma_zdestroy(V_tcbinfo.ipi_zone);
INP_INFO_LOCK_DESTROY(&V_tcbinfo);
} }
#endif #endif

View file

@ -180,25 +180,11 @@ udp_init(void)
{ {
V_udp_blackhole = 0; V_udp_blackhole = 0;
in_pcbinfo_init(&V_udbinfo, "udp", &V_udb, UDBHASHSIZE, UDBHASHSIZE,
INP_INFO_LOCK_INIT(&V_udbinfo, "udp"); "udp_inpcb", udp_inpcb_init, NULL, UMA_ZONE_NOFREE);
LIST_INIT(&V_udb);
#ifdef VIMAGE
V_udbinfo.ipi_vnet = curvnet;
#endif
V_udbinfo.ipi_listhead = &V_udb;
V_udbinfo.ipi_hashbase = hashinit(UDBHASHSIZE, M_PCB,
&V_udbinfo.ipi_hashmask);
V_udbinfo.ipi_porthashbase = hashinit(UDBHASHSIZE, M_PCB,
&V_udbinfo.ipi_porthashmask);
V_udbinfo.ipi_zone = uma_zcreate("udp_inpcb", sizeof(struct inpcb),
NULL, NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_udbinfo.ipi_zone, maxsockets);
V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb), V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_udpcb_zone, maxsockets); uma_zone_set_max(V_udpcb_zone, maxsockets);
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL, EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
EVENTHANDLER_PRI_ANY); EVENTHANDLER_PRI_ANY);
} }
@ -241,14 +227,8 @@ void
udp_destroy(void) udp_destroy(void)
{ {
hashdestroy(V_udbinfo.ipi_hashbase, M_PCB, in_pcbinfo_destroy(&V_udbinfo);
V_udbinfo.ipi_hashmask);
hashdestroy(V_udbinfo.ipi_porthashbase, M_PCB,
V_udbinfo.ipi_porthashmask);
uma_zdestroy(V_udpcb_zone); uma_zdestroy(V_udpcb_zone);
uma_zdestroy(V_udbinfo.ipi_zone);
INP_INFO_LOCK_DESTROY(&V_udbinfo);
} }
#endif #endif