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

Function igmp_final_leave

freebsd/netinet/igmp.c:2567–2658  ·  view source on GitHub ↗

* Perform the final leave for an IGMP group. * * When leaving a group: * IGMPv1 does nothing. * IGMPv2 sends a host leave message, if and only if we are the reporter. * IGMPv3 enqueues a state-change report containing a transition * to INCLUDE {} for immediate transmission. */

Source from the content-addressed store, hash-verified

2565 * to INCLUDE {} for immediate transmission.
2566 */
2567static void
2568igmp_final_leave(struct in_multi *inm, struct igmp_ifsoftc *igi)
2569{
2570 int syncstates;
2571
2572 syncstates = 1;
2573
2574 CTR4(KTR_IGMPV3, "%s: final leave 0x%08x on ifp %p(%s)",
2575 __func__, ntohl(inm->inm_addr.s_addr), inm->inm_ifp,
2576 inm->inm_ifp->if_xname);
2577
2578 IN_MULTI_LIST_LOCK_ASSERT();
2579 IGMP_LOCK_ASSERT();
2580
2581 switch (inm->inm_state) {
2582 case IGMP_NOT_MEMBER:
2583 case IGMP_SILENT_MEMBER:
2584 case IGMP_LEAVING_MEMBER:
2585 /* Already leaving or left; do nothing. */
2586 CTR1(KTR_IGMPV3,
2587"%s: not kicking state machine for silent group", __func__);
2588 break;
2589 case IGMP_REPORTING_MEMBER:
2590 case IGMP_IDLE_MEMBER:
2591 case IGMP_G_QUERY_PENDING_MEMBER:
2592 case IGMP_SG_QUERY_PENDING_MEMBER:
2593 if (igi->igi_version == IGMP_VERSION_2) {
2594#ifdef INVARIANTS
2595 if (inm->inm_state == IGMP_G_QUERY_PENDING_MEMBER ||
2596 inm->inm_state == IGMP_SG_QUERY_PENDING_MEMBER)
2597 panic("%s: IGMPv3 state reached, not IGMPv3 mode",
2598 __func__);
2599#endif
2600 igmp_v1v2_queue_report(inm, IGMP_HOST_LEAVE_MESSAGE);
2601 inm->inm_state = IGMP_NOT_MEMBER;
2602 } else if (igi->igi_version == IGMP_VERSION_3) {
2603 /*
2604 * Stop group timer and all pending reports.
2605 * Immediately enqueue a state-change report
2606 * TO_IN {} to be sent on the next fast timeout,
2607 * giving us an opportunity to merge reports.
2608 */
2609 mbufq_drain(&inm->inm_scq);
2610 inm->inm_timer = 0;
2611 if (igi->igi_flags & IGIF_LOOPBACK) {
2612 inm->inm_scrv = 1;
2613 } else {
2614 inm->inm_scrv = igi->igi_rv;
2615 }
2616 CTR4(KTR_IGMPV3, "%s: Leaving 0x%08x/%s with %d "
2617 "pending retransmissions.", __func__,
2618 ntohl(inm->inm_addr.s_addr),
2619 inm->inm_ifp->if_xname, inm->inm_scrv);
2620 if (inm->inm_scrv == 0) {
2621 inm->inm_state = IGMP_NOT_MEMBER;
2622 inm->inm_sctimer = 0;
2623 } else {
2624 int retval __unused;

Callers 1

igmp_change_stateFunction · 0.85

Calls 6

igmp_v1v2_queue_reportFunction · 0.85
inm_commitFunction · 0.85
inm_acquire_lockedFunction · 0.70
panicFunction · 0.50
mbufq_drainFunction · 0.50

Tested by

no test coverage detected