summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChirag Shah <chirag@cumulusnetworks.com>2017-04-26 03:56:00 +0200
committerChirag Shah <chirag@cumulusnetworks.com>2017-05-07 02:38:18 +0200
commitdba88ccbb0a3b4f842671564e170755944e514e1 (patch)
treed6a190f08c27a6018ee36bda129ebd4484703fcb
parentpimd: fix pimd crash when pim interface disabled (diff)
downloadfrr-dba88ccbb0a3b4f842671564e170755944e514e1.tar.xz
frr-dba88ccbb0a3b4f842671564e170755944e514e1.zip
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 <chirag@cumulusnetworks.com>
-rw-r--r--pimd/pim_iface.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index bdad1c531..cce87ae5f 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("<grp?>", ij->group_addr, group_str, sizeof(group_str));
+ pim_inet4_dump("<src?>", 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;