static void pim_vxlan_term_mr_oif_add(struct pim_vxlan_sg *vxlan_sg) { if (vxlan_sg->flags & PIM_VXLAN_SGF_OIF_INSTALLED) return; if (PIM_DEBUG_VXLAN) zlog_debug("vxlan SG %s term-oif %s add", vxlan_sg->sg_str, vxlan_sg->term_oif->name); if (pim_ifchannel_local_membership_add(vxlan_sg->term_oif, &vxlan_sg->sg)) { vxlan_sg->flags |= PIM_VXLAN_SGF_OIF_INSTALLED; } else { zlog_warn("vxlan SG %s term-oif %s add failed", vxlan_sg->sg_str, vxlan_sg->term_oif->name); } }
void igmp_source_forward_start(struct igmp_source *source) { struct igmp_group *group; int result; if (PIM_DEBUG_IGMP_TRACE) { char source_str[100]; char group_str[100]; pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str)); zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d", __PRETTY_FUNCTION__, source_str, group_str, source->source_group->group_igmp_sock->fd, source->source_group->group_igmp_sock->interface->name, IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); } /* Prevent IGMP interface from installing multicast route multiple times */ if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) { return; } group = source->source_group; if (!source->source_channel_oil) { struct pim_interface *pim_oif; int input_iface_vif_index = fib_lookup_if_vif_index(source->source_addr); if (input_iface_vif_index < 1) { char source_str[100]; pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); zlog_warn("%s %s: could not find input interface for source %s", __FILE__, __PRETTY_FUNCTION__, source_str); return; } /* Protect IGMP against adding looped MFC entries created by both source and receiver attached to the same interface. See TODO T22. */ pim_oif = source->source_group->group_igmp_sock->interface->info; if (!pim_oif) { zlog_warn("%s: multicast not enabled on oif=%s ?", __PRETTY_FUNCTION__, source->source_group->group_igmp_sock->interface->name); return; } if (pim_oif->mroute_vif_index < 1) { zlog_warn("%s %s: oif=%s vif_index=%d < 1", __FILE__, __PRETTY_FUNCTION__, source->source_group->group_igmp_sock->interface->name, pim_oif->mroute_vif_index); return; } if (input_iface_vif_index == pim_oif->mroute_vif_index) { /* ignore request for looped MFC entry */ if (PIM_DEBUG_IGMP_TRACE) { char source_str[100]; char group_str[100]; pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str)); zlog_debug("%s: ignoring request for looped MFC entry (S,G)=(%s,%s): igmp_sock=%d oif=%s vif_index=%d", __PRETTY_FUNCTION__, source_str, group_str, source->source_group->group_igmp_sock->fd, source->source_group->group_igmp_sock->interface->name, input_iface_vif_index); } return; } source->source_channel_oil = pim_channel_oil_add(group->group_addr, source->source_addr, input_iface_vif_index); if (!source->source_channel_oil) { char group_str[100]; char source_str[100]; pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str)); pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)", __FILE__, __PRETTY_FUNCTION__, source_str, group_str); return; } } result = add_oif(source->source_channel_oil, group->group_igmp_sock->interface, PIM_OIF_FLAG_PROTO_IGMP); if (result) { zlog_warn("%s: add_oif() failed with return=%d", __func__, result); return; } /* Feed IGMPv3-gathered local membership information into PIM per-interface (S,G) state. */ pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, source->source_addr, group->group_addr); IGMP_SOURCE_DO_FORWARDING(source->source_flags); }