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

Function igmp_intr

freebsd/netinet/igmp.c:3439–3522  ·  view source on GitHub ↗

* Transmit the next pending IGMP message in the output queue. * * We get called from netisr_processqueue(). A mutex private to igmpoq * will be acquired and released around this routine. * * VIMAGE: Needs to store/restore vnet pointer on a per-mbuf-chain basis. * MRT: Nothing needs to be done, as IGMP traffic is always local to * a link and uses a link-scope multicast address. */

Source from the content-addressed store, hash-verified

3437 * a link and uses a link-scope multicast address.
3438 */
3439static void
3440igmp_intr(struct mbuf *m)
3441{
3442 struct ip_moptions imo;
3443 struct ifnet *ifp;
3444 struct mbuf *ipopts, *m0;
3445 int error;
3446 uint32_t ifindex;
3447
3448 CTR2(KTR_IGMPV3, "%s: transmit %p", __func__, m);
3449
3450 /*
3451 * Set VNET image pointer from enqueued mbuf chain
3452 * before doing anything else. Whilst we use interface
3453 * indexes to guard against interface detach, they are
3454 * unique to each VIMAGE and must be retrieved.
3455 */
3456 CURVNET_SET((struct vnet *)(m->m_pkthdr.PH_loc.ptr));
3457 ifindex = igmp_restore_context(m);
3458
3459 /*
3460 * Check if the ifnet still exists. This limits the scope of
3461 * any race in the absence of a global ifp lock for low cost
3462 * (an array lookup).
3463 */
3464 ifp = ifnet_byindex(ifindex);
3465 if (ifp == NULL) {
3466 CTR3(KTR_IGMPV3, "%s: dropped %p as ifindex %u went away.",
3467 __func__, m, ifindex);
3468 m_freem(m);
3469 IPSTAT_INC(ips_noroute);
3470 goto out;
3471 }
3472
3473 ipopts = V_igmp_sendra ? m_raopt : NULL;
3474
3475 imo.imo_multicast_ttl = 1;
3476 imo.imo_multicast_vif = -1;
3477 imo.imo_multicast_loop = (V_ip_mrouter != NULL);
3478
3479 /*
3480 * If the user requested that IGMP traffic be explicitly
3481 * redirected to the loopback interface (e.g. they are running a
3482 * MANET interface and the routing protocol needs to see the
3483 * updates), handle this now.
3484 */
3485 if (m->m_flags & M_IGMP_LOOP)
3486 imo.imo_multicast_ifp = V_loif;
3487 else
3488 imo.imo_multicast_ifp = ifp;
3489
3490 if (m->m_flags & M_IGMPV2) {
3491 m0 = m;
3492 } else {
3493 m0 = igmp_v3_encap_report(ifp, m);
3494 if (m0 == NULL) {
3495 CTR2(KTR_IGMPV3, "%s: dropped %p", __func__, m);
3496 m_freem(m);

Callers

nothing calls this directly

Calls 8

igmp_restore_contextFunction · 0.85
ifnet_byindexFunction · 0.85
igmp_v3_encap_reportFunction · 0.85
igmp_scrub_contextFunction · 0.85
mac_netinet_igmp_sendFunction · 0.85
ip_outputFunction · 0.85
m_freemFunction · 0.50
m_clrprotoflagsFunction · 0.50

Tested by

no test coverage detected