FreeBSD/sys/netinet/in_mcast.c
/*
 * Given an inpcb, return its multicast options structure pointer.  Accepts
 * an unlocked inpcb pointer, but will return it locked.  May sleep.
 *
 * SMPng: NOTE: Potentially calls malloc(M_WAITOK) with Giant held.
 * SMPng: NOTE: Returns with the INP write lock held.
 */
Given an inpcb, return its multicast options structure pointer.  Accepts
an unlocked inpcb pointer, but will return it locked.  May sleep.

Potentially calls malloc(M_WAITOK) with Giant held.
SMPng: NOTE: Returns with the INP write lock held.
Given an inpcb return its multicast options structure pointer . Accepts an unlocked inpcb pointer but will return it locked . May sleep . Potentially calls malloc ( M_WAITOK ) with Giant held . SMPng : NOTE : Returns with the INP write lock held .
static struct ip_moptions *
inp_findmoptions(struct inpcb *inp)
{
	struct ip_moptions	 *imo;
	struct in_multi		**immp;
	struct in_mfilter	 *imfp;
	size_t			  idx;
	INP_WLOCK(inp);
	if (inp->inp_moptions != NULL)
		return (inp->inp_moptions);
	INP_WUNLOCK(inp);
	imo = malloc(sizeof(*imo), M_IPMOPTS, M_WAITOK);
	immp = malloc(sizeof(*immp) * IP_MIN_MEMBERSHIPS, M_IPMOPTS,
	    M_WAITOK | M_ZERO);
	imfp = malloc(sizeof(struct in_mfilter) * IP_MIN_MEMBERSHIPS,
	    M_INMFILTER, M_WAITOK);
	imo->imo_multicast_ifp = NULL;
	imo->imo_multicast_addr.s_addr = INADDR_ANY;
	imo->imo_multicast_vif = -1;
	imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
	imo->imo_multicast_loop = in_mcast_loop;
	imo->imo_num_memberships = 0;
	imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
	imo->imo_membership = immp;
	for (idx = 0; idx < IP_MIN_MEMBERSHIPS; idx++)
		imf_init(&imfp[idx], MCAST_UNDEFINED, MCAST_EXCLUDE);
	imo->imo_mfilters = imfp;
	INP_WLOCK(inp);
	if (inp->inp_moptions != NULL) {
		free(imfp, M_INMFILTER);
		free(immp, M_IPMOPTS);
		free(imo, M_IPMOPTS);
		return (inp->inp_moptions);
	}
	inp->inp_moptions = imo;
	return (imo);
}
static struct ip_moptions * inp_findmoptions ( struct inpcb * inp ) { struct ip_moptions * imo ; struct in_multi * * immp ; struct in_mfilter * imfp ; size_t idx ; INP_WLOCK ( inp ) ; if ( inp -> inp_moptions != NULL ) return ( inp -> inp_moptions ) ; INP_WUNLOCK ( inp ) ; imo = malloc ( sizeof ( * imo ) , M_IPMOPTS , M_WAITOK ) ; immp = malloc ( sizeof ( * immp ) * IP_MIN_MEMBERSHIPS , M_IPMOPTS , M_WAITOK | M_ZERO ) ; imfp = malloc ( sizeof ( struct in_mfilter ) * IP_MIN_MEMBERSHIPS , M_INMFILTER , M_WAITOK ) ; imo -> imo_multicast_ifp = NULL ; imo -> imo_multicast_addr . s_addr = INADDR_ANY ; imo -> imo_multicast_vif = -1 ; imo -> imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL ; imo -> imo_multicast_loop = in_mcast_loop ; imo -> imo_num_memberships = 0 ; imo -> imo_max_memberships = IP_MIN_MEMBERSHIPS ; imo -> imo_membership = immp ; for ( idx = 0 ; idx < IP_MIN_MEMBERSHIPS ; idx ++ ) imf_init ( & imfp [ idx ] , MCAST_UNDEFINED , MCAST_EXCLUDE ) ; imo -> imo_mfilters = imfp ; INP_WLOCK ( inp ) ; if ( inp -> inp_moptions != NULL ) { free ( imfp , M_INMFILTER ) ; free ( immp , M_IPMOPTS ) ; free ( imo , M_IPMOPTS ) ; return ( inp -> inp_moptions ) ; } inp -> inp_moptions = imo ; return ( imo ) ; }
Given an inpcb, return its multicast options structure pointer.
Given an inpcb return its multicast options structure pointer .
/* Initialize per-group source filters. */