diff options
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r-- | sys/netinet/udp_usrreq.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 84c5521..7fff2b6 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -137,6 +137,14 @@ udp_zone_change(void *tag) uma_zone_set_max(udbinfo.ipi_zone, maxsockets); } +static int +udp_inpcb_init(void *mem, int size, int flags) +{ + struct inpcb *inp = (struct inpcb *) mem; + INP_LOCK_INIT(inp, "inp", "udpinp"); + return (0); +} + void udp_init() { @@ -147,7 +155,7 @@ udp_init() udbinfo.porthashbase = hashinit(UDBHASHSIZE, M_PCB, &udbinfo.porthashmask); udbinfo.ipi_zone = uma_zcreate("udpcb", sizeof(struct inpcb), NULL, - NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(udbinfo.ipi_zone, maxsockets); EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL, EVENTHANDLER_PRI_ANY); @@ -633,6 +641,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS) error = 0; for (i = 0; i < n; i++) { inp = inp_list[i]; + INP_LOCK(inp); if (inp->inp_gencnt <= gencnt) { struct xinpcb xi; bzero(&xi, sizeof(xi)); @@ -642,8 +651,10 @@ udp_pcblist(SYSCTL_HANDLER_ARGS) if (inp->inp_socket) sotoxsocket(inp->inp_socket, &xi.xi_socket); xi.xi_inp.inp_gencnt = inp->inp_gencnt; + INP_UNLOCK(inp); error = SYSCTL_OUT(req, &xi, sizeof xi); - } + } else + INP_UNLOCK(inp); } if (!error) { /* @@ -966,14 +977,13 @@ udp_attach(struct socket *so, int proto, struct thread *td) if (error) return error; INP_INFO_WLOCK(&udbinfo); - error = in_pcballoc(so, &udbinfo, "udpinp"); + error = in_pcballoc(so, &udbinfo); if (error) { INP_INFO_WUNLOCK(&udbinfo); return error; } inp = (struct inpcb *)so->so_pcb; - INP_LOCK(inp); INP_INFO_WUNLOCK(&udbinfo); inp->inp_vflag |= INP_IPV4; inp->inp_ip_ttl = ip_defttl; |