]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: replay IGMP static group upon if creation
authorChirag Shah <chirag@cumulusnetworks.com>
Wed, 26 Apr 2017 01:56:00 +0000 (18:56 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Sun, 7 May 2017 00:38:18 +0000 (17:38 -0700)
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>
pimd/pim_iface.c

index bdad1c531cefdde888d9ff9eff9c0c354fd79d1f..cce87ae5fd49b467e2653812e22bd36ad0f7bbb2 100644 (file)
@@ -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;