From dba88ccbb0a3b4f842671564e170755944e514e1 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 25 Apr 2017 18:56:00 -0700 Subject: [PATCH] pimd: replay IGMP static group upon if creation Upon static IGMP configured port down igmp source info is destroyed. Upon port up or quagga restart (if addr add) register IGMP sock with port, source, group. Testing Done: Configure IGMPv3 Report on Host swpx, ifdown/ifup swpx, verify ip mroute containng IGMP mroute tor-1# show ip mroute Source Group Proto Input Output TTL Uptime 30.1.1.1 225.1.1.21 IGMP swp2 swp3 1 00:00:05 Signed-off-by: Chirag Shah --- pimd/pim_iface.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index bdad1c531c..cce87ae5fd 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -50,6 +50,8 @@ struct list *pim_ifchannel_list = NULL; static int pim_iface_vif_index[MAXVIFS]; static void pim_if_igmp_join_del_all(struct interface *ifp); +static int igmp_join_sock(const char *ifname, ifindex_t ifindex, + struct in_addr group_addr, struct in_addr source_addr); void pim_if_init (void) @@ -583,6 +585,35 @@ void pim_if_addr_add(struct connected *ifc) /* if addr new, add IGMP socket */ pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp); } + + /* Replay Static IGMP groups */ + if (pim_ifp->igmp_join_list) + { + struct listnode *node; + struct listnode *nextnode; + struct igmp_join *ij; + int join_fd; + + for (ALL_LIST_ELEMENTS (pim_ifp->igmp_join_list, node, nextnode, ij)) + { + /* Close socket and reopen with Source and Group */ + close(ij->sock_fd); + join_fd = igmp_join_sock(ifp->name, ifp->ifindex, ij->group_addr, ij->source_addr); + if (join_fd < 0) + { + char group_str[INET_ADDRSTRLEN]; + char source_str[INET_ADDRSTRLEN]; + pim_inet4_dump("", ij->group_addr, group_str, sizeof(group_str)); + pim_inet4_dump("", ij->source_addr, source_str, sizeof(source_str)); + zlog_warn("%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s", + __PRETTY_FUNCTION__, + group_str, source_str, ifp->name); + /* warning only */ + } + else + ij->sock_fd = join_fd; + } + } } /* igmp */ if (PIM_IF_TEST_PIM(pim_ifp->options)) @@ -1506,6 +1537,9 @@ pim_if_connected_to_source (struct interface *ifp, struct in_addr src) struct connected *c; struct prefix p; + if (!ifp) + return 0; + p.family = AF_INET; p.u.prefix4 = src; p.prefixlen = IPV4_MAX_BITLEN; -- 2.39.5