MCPcopy Create free account
hub / github.com/F-Stack/f-stack / in_getmulti

Function in_getmulti

freebsd/netinet/in_mcast.c:508–616  ·  view source on GitHub ↗

* Find and return a reference to an in_multi record for (ifp, group), * and bump its reference count. * If one does not exist, try to allocate it, and update link-layer multicast * filters on ifp to listen for group. * Assumes the IN_MULTI lock is held across the call. * Return 0 if successful, otherwise return an appropriate error code. */

Source from the content-addressed store, hash-verified

506 * Return 0 if successful, otherwise return an appropriate error code.
507 */
508static int
509in_getmulti(struct ifnet *ifp, const struct in_addr *group,
510 struct in_multi **pinm)
511{
512 struct sockaddr_in gsin;
513 struct ifmultiaddr *ifma;
514 struct in_ifinfo *ii;
515 struct in_multi *inm;
516 int error;
517
518 IN_MULTI_LOCK_ASSERT();
519
520 ii = (struct in_ifinfo *)ifp->if_afdata[AF_INET];
521 IN_MULTI_LIST_LOCK();
522 inm = inm_lookup(ifp, *group);
523 if (inm != NULL) {
524 /*
525 * If we already joined this group, just bump the
526 * refcount and return it.
527 */
528 KASSERT(inm->inm_refcount >= 1,
529 ("%s: bad refcount %d", __func__, inm->inm_refcount));
530 inm_acquire_locked(inm);
531 *pinm = inm;
532 }
533 IN_MULTI_LIST_UNLOCK();
534 if (inm != NULL)
535 return (0);
536
537 memset(&gsin, 0, sizeof(gsin));
538 gsin.sin_family = AF_INET;
539 gsin.sin_len = sizeof(struct sockaddr_in);
540 gsin.sin_addr = *group;
541
542 /*
543 * Check if a link-layer group is already associated
544 * with this network-layer group on the given ifnet.
545 */
546 error = if_addmulti(ifp, (struct sockaddr *)&gsin, &ifma);
547 if (error != 0)
548 return (error);
549
550 /* XXX ifma_protospec must be covered by IF_ADDR_LOCK */
551 IN_MULTI_LIST_LOCK();
552 IF_ADDR_WLOCK(ifp);
553
554 /*
555 * If something other than netinet is occupying the link-layer
556 * group, print a meaningful error message and back out of
557 * the allocation.
558 * Otherwise, bump the refcount on the existing network-layer
559 * group association and return it.
560 */
561 if (ifma->ifma_protospec != NULL) {
562 inm = (struct in_multi *)ifma->ifma_protospec;
563#ifdef INVARIANTS
564 KASSERT(ifma->ifma_addr != NULL, ("%s: no ifma_addr",
565 __func__));

Callers 1

in_joingroup_lockedFunction · 0.85

Calls 9

inm_lookupFunction · 0.85
memsetFunction · 0.85
if_addmultiFunction · 0.85
inet_ntoa_rFunction · 0.85
mallocFunction · 0.85
if_delmulti_ifmaFunction · 0.85
inm_acquire_lockedFunction · 0.70
panicFunction · 0.50
mbufq_initFunction · 0.50

Tested by

no test coverage detected