diff options
author | Chirag Shah <chirag@cumulusnetworks.com> | 2017-04-26 03:56:00 +0200 |
---|---|---|
committer | Chirag Shah <chirag@cumulusnetworks.com> | 2017-05-07 02:38:18 +0200 |
commit | dba88ccbb0a3b4f842671564e170755944e514e1 (patch) | |
tree | d6a190f08c27a6018ee36bda129ebd4484703fcb | |
parent | pimd: fix pimd crash when pim interface disabled (diff) | |
download | frr-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.c | 34 |
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; |