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

Function igmp_change_state

freebsd/netinet/igmp.c:2317–2369  ·  view source on GitHub ↗

* Process a state change from the upper layer for the given IPv4 group. * * Each socket holds a reference on the in_multi in its own ip_moptions. * The socket layer will have made the necessary updates to.the group * state, it is now up to IGMP to issue a state change report if there * has been any change between T0 (when the last state-change was issued) * and T1 (now). * * We use the IGM

Source from the content-addressed store, hash-verified

2315 * is called from the socket option handlers.
2316 */
2317int
2318igmp_change_state(struct in_multi *inm)
2319{
2320 struct igmp_ifsoftc *igi;
2321 struct ifnet *ifp;
2322 int error;
2323
2324 error = 0;
2325 IN_MULTI_LOCK_ASSERT();
2326 /*
2327 * Try to detect if the upper layer just asked us to change state
2328 * for an interface which has now gone away.
2329 */
2330 KASSERT(inm->inm_ifma != NULL, ("%s: no ifma", __func__));
2331 ifp = inm->inm_ifma->ifma_ifp;
2332 /*
2333 * Sanity check that netinet's notion of ifp is the
2334 * same as net's.
2335 */
2336 KASSERT(inm->inm_ifp == ifp, ("%s: bad ifp", __func__));
2337
2338 IGMP_LOCK();
2339
2340 igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp;
2341 KASSERT(igi != NULL, ("%s: no igmp_ifsoftc for ifp %p", __func__, ifp));
2342
2343 /*
2344 * If we detect a state transition to or from MCAST_UNDEFINED
2345 * for this group, then we are starting or finishing an IGMP
2346 * life cycle for this group.
2347 */
2348 if (inm->inm_st[1].iss_fmode != inm->inm_st[0].iss_fmode) {
2349 CTR3(KTR_IGMPV3, "%s: inm transition %d -> %d", __func__,
2350 inm->inm_st[0].iss_fmode, inm->inm_st[1].iss_fmode);
2351 if (inm->inm_st[0].iss_fmode == MCAST_UNDEFINED) {
2352 CTR1(KTR_IGMPV3, "%s: initial join", __func__);
2353 error = igmp_initial_join(inm, igi);
2354 goto out_locked;
2355 } else if (inm->inm_st[1].iss_fmode == MCAST_UNDEFINED) {
2356 CTR1(KTR_IGMPV3, "%s: final leave", __func__);
2357 igmp_final_leave(inm, igi);
2358 goto out_locked;
2359 }
2360 } else {
2361 CTR1(KTR_IGMPV3, "%s: filter set change", __func__);
2362 }
2363
2364 error = igmp_handle_state_change(inm, igi);
2365
2366out_locked:
2367 IGMP_UNLOCK();
2368 return (error);
2369}
2370
2371/*
2372 * Perform the initial join for an IGMP group.

Callers 6

in_joingroup_lockedFunction · 0.85
in_leavegroup_lockedFunction · 0.85
inp_block_unblock_sourceFunction · 0.85
inp_join_groupFunction · 0.85
inp_leave_groupFunction · 0.85
inp_set_source_filtersFunction · 0.85

Calls 3

igmp_initial_joinFunction · 0.85
igmp_final_leaveFunction · 0.85
igmp_handle_state_changeFunction · 0.85

Tested by

no test coverage detected