Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in_pcb.c
Show First 20 Lines • Show All 496 Lines • ▼ Show 20 Lines | CK_LIST_FOREACH(grp, hdr, il_list) { | ||||
} | } | ||||
} | } | ||||
err = ENOENT; | err = ENOENT; | ||||
abort_with_hash_wlock: | abort_with_hash_wlock: | ||||
INP_HASH_WUNLOCK(pcbinfo); | INP_HASH_WUNLOCK(pcbinfo); | ||||
return (err); | return (err); | ||||
} | } | ||||
/* | |||||
* Different protocols initialize their inpcbs differently - giving | |||||
* different name to the lock. But they all are disposed the same. | |||||
*/ | |||||
static void | |||||
inpcb_fini(void *mem, int size) | |||||
{ | |||||
struct inpcb *inp = mem; | |||||
INP_LOCK_DESTROY(inp); | |||||
} | |||||
/* Make sure it is safe to use hashinit(9) on CK_LIST. */ | /* Make sure it is safe to use hashinit(9) on CK_LIST. */ | ||||
CTASSERT(sizeof(struct inpcbhead) == sizeof(LIST_HEAD(, inpcb))); | CTASSERT(sizeof(struct inpcbhead) == sizeof(LIST_HEAD(, inpcb))); | ||||
/* | /* | ||||
* Initialize an inpcbinfo -- we should be able to reduce the number of | * Initialize an inpcbinfo -- we should be able to reduce the number of | ||||
* arguments in time. | * arguments in time. | ||||
*/ | */ | ||||
static void inpcb_dtor(void *, int, void *); | |||||
static void inpcb_fini(void *, int); | |||||
void | void | ||||
in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name, | in_pcbinfo_init(struct inpcbinfo *pcbinfo, const char *name, | ||||
u_int hash_nelements, int porthash_nelements, char *inpcbzone_name, | u_int hash_nelements, int porthash_nelements, char *inpcbzone_name, | ||||
uma_init inpcbzone_init) | uma_init inpcbzone_init) | ||||
{ | { | ||||
mtx_init(&pcbinfo->ipi_lock, name, NULL, MTX_DEF); | mtx_init(&pcbinfo->ipi_lock, name, NULL, MTX_DEF); | ||||
mtx_init(&pcbinfo->ipi_hash_lock, "pcbinfohash", NULL, MTX_DEF); | mtx_init(&pcbinfo->ipi_hash_lock, "pcbinfohash", NULL, MTX_DEF); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
pcbinfo->ipi_vnet = curvnet; | pcbinfo->ipi_vnet = curvnet; | ||||
#endif | #endif | ||||
CK_LIST_INIT(&pcbinfo->ipi_listhead); | CK_LIST_INIT(&pcbinfo->ipi_listhead); | ||||
pcbinfo->ipi_count = 0; | pcbinfo->ipi_count = 0; | ||||
pcbinfo->ipi_hashbase = hashinit(hash_nelements, M_PCB, | pcbinfo->ipi_hashbase = hashinit(hash_nelements, M_PCB, | ||||
&pcbinfo->ipi_hashmask); | &pcbinfo->ipi_hashmask); | ||||
porthash_nelements = imin(porthash_nelements, IPPORT_MAX + 1); | porthash_nelements = imin(porthash_nelements, IPPORT_MAX + 1); | ||||
pcbinfo->ipi_porthashbase = hashinit(porthash_nelements, M_PCB, | pcbinfo->ipi_porthashbase = hashinit(porthash_nelements, M_PCB, | ||||
&pcbinfo->ipi_porthashmask); | &pcbinfo->ipi_porthashmask); | ||||
pcbinfo->ipi_lbgrouphashbase = hashinit(porthash_nelements, M_PCB, | pcbinfo->ipi_lbgrouphashbase = hashinit(porthash_nelements, M_PCB, | ||||
&pcbinfo->ipi_lbgrouphashmask); | &pcbinfo->ipi_lbgrouphashmask); | ||||
pcbinfo->ipi_zone = uma_zcreate(inpcbzone_name, sizeof(struct inpcb), | pcbinfo->ipi_zone = uma_zcreate(inpcbzone_name, sizeof(struct inpcb), | ||||
NULL, NULL, inpcbzone_init, inpcb_fini, UMA_ALIGN_PTR, | NULL, inpcb_dtor, inpcbzone_init, inpcb_fini, UMA_ALIGN_PTR, | ||||
UMA_ZONE_SMR); | UMA_ZONE_SMR); | ||||
uma_zone_set_max(pcbinfo->ipi_zone, maxsockets); | uma_zone_set_max(pcbinfo->ipi_zone, maxsockets); | ||||
uma_zone_set_warning(pcbinfo->ipi_zone, | uma_zone_set_warning(pcbinfo->ipi_zone, | ||||
"kern.ipc.maxsockets limit reached"); | "kern.ipc.maxsockets limit reached"); | ||||
pcbinfo->ipi_smr = uma_zone_get_smr(pcbinfo->ipi_zone); | pcbinfo->ipi_smr = uma_zone_get_smr(pcbinfo->ipi_zone); | ||||
pcbinfo->ipi_portzone = uma_zcreate(inpcbzone_name, | pcbinfo->ipi_portzone = uma_zcreate(inpcbzone_name, | ||||
sizeof(struct inpcbport), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | sizeof(struct inpcbport), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | ||||
uma_zone_set_smr(pcbinfo->ipi_portzone, pcbinfo->ipi_smr); | uma_zone_set_smr(pcbinfo->ipi_portzone, pcbinfo->ipi_smr); | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | #endif | ||||
CK_LIST_INSERT_HEAD(&pcbinfo->ipi_listhead, inp, inp_list); | CK_LIST_INSERT_HEAD(&pcbinfo->ipi_listhead, inp, inp_list); | ||||
INP_INFO_WUNLOCK(pcbinfo); | INP_INFO_WUNLOCK(pcbinfo); | ||||
so->so_pcb = inp; | so->so_pcb = inp; | ||||
return (0); | return (0); | ||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT) || defined(MAC) | #if defined(IPSEC) || defined(IPSEC_SUPPORT) || defined(MAC) | ||||
out: | out: | ||||
crfree(inp->inp_cred); | |||||
uma_zfree_smr(pcbinfo->ipi_zone, inp); | uma_zfree_smr(pcbinfo->ipi_zone, inp); | ||||
return (error); | return (error); | ||||
#endif | #endif | ||||
} | } | ||||
#ifdef INET | #ifdef INET | ||||
int | int | ||||
in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) | in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) | ||||
▲ Show 20 Lines • Show All 1,172 Lines • ▼ Show 20 Lines | if (inp->inp_flags & INP_INHASHLIST) { | ||||
if (CK_LIST_FIRST(&phd->phd_pcblist) == NULL) { | if (CK_LIST_FIRST(&phd->phd_pcblist) == NULL) { | ||||
CK_LIST_REMOVE(phd, phd_hash); | CK_LIST_REMOVE(phd, phd_hash); | ||||
uma_zfree_smr(pcbinfo->ipi_portzone, phd); | uma_zfree_smr(pcbinfo->ipi_portzone, phd); | ||||
} | } | ||||
INP_HASH_WUNLOCK(pcbinfo); | INP_HASH_WUNLOCK(pcbinfo); | ||||
inp->inp_flags &= ~INP_INHASHLIST; | inp->inp_flags &= ~INP_INHASHLIST; | ||||
} | } | ||||
crfree(inp->inp_cred); | |||||
RO_INVALIDATE_CACHE(&inp->inp_route); | RO_INVALIDATE_CACHE(&inp->inp_route); | ||||
#ifdef MAC | #ifdef MAC | ||||
mac_inpcb_destroy(inp); | mac_inpcb_destroy(inp); | ||||
#endif | #endif | ||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT) | #if defined(IPSEC) || defined(IPSEC_SUPPORT) | ||||
if (inp->inp_sp != NULL) | if (inp->inp_sp != NULL) | ||||
ipsec_delete_pcbpolicy(inp); | ipsec_delete_pcbpolicy(inp); | ||||
#endif | #endif | ||||
Show All 14 Lines | if (__predict_false(in_pcbrele_wlocked(inp) == false)) { | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
} | } | ||||
#ifdef INET6 | #ifdef INET6 | ||||
ip6_freemoptions(im6o); | ip6_freemoptions(im6o); | ||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
inp_freemoptions(imo); | inp_freemoptions(imo); | ||||
#endif | #endif | ||||
/* Destruction is finalized in inpcb_dtor(). */ | |||||
} | |||||
static void | |||||
inpcb_dtor(void *mem, int size, void *arg) | |||||
{ | |||||
struct inpcb *inp = mem; | |||||
crfree(inp->inp_cred); | |||||
markj: Perhaps set `inp->inp_cred = NULL` at least if INVARIANTS is defined. | |||||
Done Inline ActionsI can do it. glebius: I can do it. | |||||
#ifdef INVARIANTS | |||||
inp->inp_cred = NULL; | |||||
#endif | |||||
} | |||||
/* | |||||
* Different protocols initialize their inpcbs differently - giving | |||||
* different name to the lock. But they all are disposed the same. | |||||
*/ | |||||
static void | |||||
inpcb_fini(void *mem, int size) | |||||
{ | |||||
struct inpcb *inp = mem; | |||||
INP_LOCK_DESTROY(inp); | |||||
} | } | ||||
Not Done Inline ActionsIMHO it is more logical to group UMA zone methods together, i.e., I would group this with inpcb_fini(). markj: IMHO it is more logical to group UMA zone methods together, i.e., I would group this with… | |||||
Done Inline ActionsDo you agree if I move inpcb_fini() down to here, rather than move inpcb_dtor() up? I'd like to put the whole destruction sequence sequential and readable from top to bottom? glebius: Do you agree if I move inpcb_fini() down to here, rather than move inpcb_dtor() up? I'd like to… | |||||
Not Done Inline ActionsFine with me. markj: Fine with me. | |||||
/* | /* | ||||
* in_pcbdrop() removes an inpcb from hashed lists, releasing its address and | * in_pcbdrop() removes an inpcb from hashed lists, releasing its address and | ||||
* port reservation, and preventing it from being returned by inpcb lookups. | * port reservation, and preventing it from being returned by inpcb lookups. | ||||
* | * | ||||
* It is used by TCP to mark an inpcb as unused and avoid future packet | * It is used by TCP to mark an inpcb as unused and avoid future packet | ||||
* delivery or event notification when a socket remains open but TCP has | * delivery or event notification when a socket remains open but TCP has | ||||
* closed. This might occur as a result of a shutdown()-initiated TCP close | * closed. This might occur as a result of a shutdown()-initiated TCP close | ||||
▲ Show 20 Lines • Show All 1,436 Lines • Show Last 20 Lines |
Perhaps set inp->inp_cred = NULL at least if INVARIANTS is defined.