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

Function igmp_initial_join

freebsd/netinet/igmp.c:2381–2504  ·  view source on GitHub ↗

* Perform the initial join for an IGMP group. * * When joining a group: * If the group should have its IGMP traffic suppressed, do nothing. * IGMPv1 starts sending IGMPv1 host membership reports. * IGMPv2 starts sending IGMPv2 host membership reports. * IGMPv3 will schedule an IGMPv3 state-change report containing the * initial state of the membership. */

Source from the content-addressed store, hash-verified

2379 * initial state of the membership.
2380 */
2381static int
2382igmp_initial_join(struct in_multi *inm, struct igmp_ifsoftc *igi)
2383{
2384 struct ifnet *ifp;
2385 struct mbufq *mq;
2386 int error, retval, syncstates;
2387
2388 CTR4(KTR_IGMPV3, "%s: initial join 0x%08x on ifp %p(%s)", __func__,
2389 ntohl(inm->inm_addr.s_addr), inm->inm_ifp, inm->inm_ifp->if_xname);
2390
2391 error = 0;
2392 syncstates = 1;
2393
2394 ifp = inm->inm_ifp;
2395
2396 IN_MULTI_LOCK_ASSERT();
2397 IGMP_LOCK_ASSERT();
2398
2399 KASSERT(igi && igi->igi_ifp == ifp, ("%s: inconsistent ifp", __func__));
2400
2401 /*
2402 * Groups joined on loopback or marked as 'not reported',
2403 * e.g. 224.0.0.1, enter the IGMP_SILENT_MEMBER state and
2404 * are never reported in any IGMP protocol exchanges.
2405 * All other groups enter the appropriate IGMP state machine
2406 * for the version in use on this link.
2407 * A link marked as IGIF_SILENT causes IGMP to be completely
2408 * disabled for the link.
2409 */
2410 if ((ifp->if_flags & IFF_LOOPBACK) ||
2411 (igi->igi_flags & IGIF_SILENT) ||
2412 !igmp_isgroupreported(inm->inm_addr)) {
2413 CTR1(KTR_IGMPV3,
2414"%s: not kicking state machine for silent group", __func__);
2415 inm->inm_state = IGMP_SILENT_MEMBER;
2416 inm->inm_timer = 0;
2417 } else {
2418 /*
2419 * Deal with overlapping in_multi lifecycle.
2420 * If this group was LEAVING, then make sure
2421 * we drop the reference we picked up to keep the
2422 * group around for the final INCLUDE {} enqueue.
2423 */
2424 if (igi->igi_version == IGMP_VERSION_3 &&
2425 inm->inm_state == IGMP_LEAVING_MEMBER) {
2426 MPASS(inm->inm_refcount > 1);
2427 inm_rele_locked(NULL, inm);
2428 }
2429 inm->inm_state = IGMP_REPORTING_MEMBER;
2430
2431 switch (igi->igi_version) {
2432 case IGMP_VERSION_1:
2433 case IGMP_VERSION_2:
2434 inm->inm_state = IGMP_IDLE_MEMBER;
2435 error = igmp_v1v2_queue_report(inm,
2436 (igi->igi_version == IGMP_VERSION_2) ?
2437 IGMP_v2_HOST_MEMBERSHIP_REPORT :
2438 IGMP_v1_HOST_MEMBERSHIP_REPORT);

Callers 1

igmp_change_stateFunction · 0.85

Calls 6

igmp_isgroupreportedFunction · 0.85
igmp_v1v2_queue_reportFunction · 0.85
inm_commitFunction · 0.85
inm_rele_lockedFunction · 0.70
mbufq_drainFunction · 0.50

Tested by

no test coverage detected