FreeBSD/sys/netinet/in_mcast.c
/*
 * Resize the ip_moptions vector to the next power-of-two minus 1.
 * May be called with locks held; do not sleep.
 */
Resize the ip_moptions vector to the next power-of-two minus 1.
May be called with locks held; do not sleep.
Resize the ip_moptions vector to the next power - of - two minus 1 . May be called with locks held ; do not sleep .
static int
imo_grow(struct ip_moptions *imo)
{
	struct in_multi		**nmships;
	struct in_multi		**omships;
	struct in_mfilter	 *nmfilters;
	struct in_mfilter	 *omfilters;
	size_t			  idx;
	size_t			  newmax;
	size_t			  oldmax;
	nmships = NULL;
	nmfilters = NULL;
	omships = imo->imo_membership;
	omfilters = imo->imo_mfilters;
	oldmax = imo->imo_max_memberships;
	newmax = ((oldmax + 1) * 2) - 1;
	if (newmax <= IP_MAX_MEMBERSHIPS) {
		nmships = (struct in_multi **)realloc(omships,
		    sizeof(struct in_multi *) * newmax, M_IPMOPTS, M_NOWAIT);
		nmfilters = (struct in_mfilter *)realloc(omfilters,
		    sizeof(struct in_mfilter) * newmax, M_INMFILTER, M_NOWAIT);
		if (nmships != NULL && nmfilters != NULL) {
			for (idx = oldmax; idx < newmax; idx++) {
				imf_init(&nmfilters[idx], MCAST_UNDEFINED,
				    MCAST_EXCLUDE);
			}
			imo->imo_max_memberships = newmax;
			imo->imo_membership = nmships;
			imo->imo_mfilters = nmfilters;
		}
	}
	if (nmships == NULL || nmfilters == NULL) {
		if (nmships != NULL)
			free(nmships, M_IPMOPTS);
		if (nmfilters != NULL)
			free(nmfilters, M_INMFILTER);
		return (ETOOMANYREFS);
	}
	return (0);
}
static int imo_grow ( struct ip_moptions * imo ) { struct in_multi * * nmships ; struct in_multi * * omships ; struct in_mfilter * nmfilters ; struct in_mfilter * omfilters ; size_t idx ; size_t newmax ; size_t oldmax ; nmships = NULL ; nmfilters = NULL ; omships = imo -> imo_membership ; omfilters = imo -> imo_mfilters ; oldmax = imo -> imo_max_memberships ; newmax = ( ( oldmax + 1 ) * 2 ) - 1 ; if ( newmax <= IP_MAX_MEMBERSHIPS ) { nmships = ( struct in_multi * * ) realloc ( omships , sizeof ( struct in_multi * ) * newmax , M_IPMOPTS , M_NOWAIT ) ; nmfilters = ( struct in_mfilter * ) realloc ( omfilters , sizeof ( struct in_mfilter ) * newmax , M_INMFILTER , M_NOWAIT ) ; if ( nmships != NULL && nmfilters != NULL ) { for ( idx = oldmax ; idx < newmax ; idx ++ ) { imf_init ( & nmfilters [ idx ] , MCAST_UNDEFINED , MCAST_EXCLUDE ) ; } imo -> imo_max_memberships = newmax ; imo -> imo_membership = nmships ; imo -> imo_mfilters = nmfilters ; } } if ( nmships == NULL || nmfilters == NULL ) { if ( nmships != NULL ) free ( nmships , M_IPMOPTS ) ; if ( nmfilters != NULL ) free ( nmfilters , M_INMFILTER ) ; return ( ETOOMANYREFS ) ; } return ( 0 ) ; }
Resize the ip_moptions vector to the next power-of-two minus 1.
Resize the ip_moptions vector to the next power - of - two minus 1 .
/* Initialize newly allocated source filter heads. */