]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Fixup tracking of where we got OIF's from.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 19 Jan 2017 17:09:26 +0000 (12:09 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 30 Jan 2017 17:49:38 +0000 (12:49 -0500)
This commit does these three things:

1) Add code to 'show ip pim state' to show where OIF's got their
decision to include that interface

2) Add code in pim_mroute_[add|del] to display what we think we are
adding to the kernel

3) Add code to properly track where we got the incoming request from and
to appropriately not remove a OIL if we have state still

Ticket: CM-14034
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed-by: Chirag Shah <chirag@cumulusnetworks.com>
pimd/pim_cmd.c
pimd/pim_ifchannel.c
pimd/pim_mroute.c
pimd/pim_oil.c
pimd/pim_oil.h
pimd/pim_upstream.c

index 7dc1aeccb958d7c27fd8247da2a95354d7f1edd7..8f3e2cb3e0e42f19d5e2972d218c1c1ee84bb183 100644 (file)
@@ -1367,7 +1367,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
   if (uj) {
     json = json_object_new_object();
   } else {
-    vty_out(vty, "%sSource           Group            IIF    OIL%s", VTY_NEWLINE, VTY_NEWLINE);
+    vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
+    vty_out(vty, "%sInstalled Source           Group            IIF      OIL%s", VTY_NEWLINE, VTY_NEWLINE);
   }
 
   for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
@@ -1379,9 +1380,6 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
     struct interface *ifp_in;
     first_oif = 1;
 
-    if (!c_oil->installed)
-      continue;
-
     pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
     pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
     ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
@@ -1426,7 +1424,8 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
         json_object_object_add(json_source, in_ifname, json_ifp_in);
       }
     } else {
-        vty_out(vty, "%-15s  %-15s  %-5s  ",
+        vty_out(vty, "%-9d %-15s  %-15s  %-7s  ",
+                c_oil->installed,
                 src_str,
                 grp_str,
                 ifp_in->name);
@@ -1455,16 +1454,25 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
         json_object_string_add(json_ifp_out, "group", grp_str);
         json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
         json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
+        json_object_int_add(json_ifp_out, "installed", c_oil->installed);
 
         json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
       } else {
         if (first_oif)
           {
             first_oif = 0;
-            vty_out(vty, "%s", out_ifname);
+            vty_out(vty, "%s(%c%c%c%c)", out_ifname,
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ');
           }
         else
-          vty_out(vty, ",%s", out_ifname);
+          vty_out(vty, ", %s(%c%c%c%c)", out_ifname,
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ' );
       }
     }
 
@@ -2963,6 +2971,9 @@ static void show_mroute(struct vty *vty, u_char uj)
         if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
           json_object_boolean_true_add(json_ifp_out, "protocolSource");
 
+        if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR)
+          json_object_boolean_true_add(json_ifp_out, "protocolInherited");
+
         json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
         json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
         json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
@@ -2987,6 +2998,10 @@ static void show_mroute(struct vty *vty, u_char uj)
           strcpy(proto, "SRC");
         }
 
+        if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) {
+          strcpy(proto, "STAR");
+        }
+
         vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d  %8s%s",
                 src_str,
                 grp_str,
index 07318791e789bd3e6dc937e21da817d41150e8c6..8d2de3c8785893babbb62e6212c8131a9e6e3180 100644 (file)
@@ -153,7 +153,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
          struct listnode *up_node;
 
          for (ALL_LIST_ELEMENTS_RO (ch->upstream->sources, up_node, child))
-           pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+            pim_channel_del_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
        }
     }
 
@@ -270,7 +270,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
                    continue;
 
                  if (!pim_upstream_evaluate_join_desired (child))
-                   pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+                    pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
 
                  /*
                   * If the S,G has no if channel and the c_oil still
@@ -278,7 +278,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
                   * if channel.  So remove it.
                   */
                  if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
-                   pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+                    pim_channel_del_oif (c_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
                }
            }
          if (ch->ifjoin_state == PIM_IFJOIN_JOIN)
@@ -292,7 +292,7 @@ void pim_ifchannel_ifjoin_switch(const char *caller,
 
                  if (pim_upstream_evaluate_join_desired (child))
                    {
-                     pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+                      pim_channel_add_oif (child->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_STAR);
                      pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
                    }
                }
@@ -964,7 +964,7 @@ void pim_ifchannel_local_membership_add(struct interface *ifp,
 
          if (pim_upstream_evaluate_join_desired (child))
            {
-             pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
+             pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
              pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
            }
         }
@@ -1008,7 +1008,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
                       up->sg_str, ifp->name, child->sg_str);
 
          if (c_oil && !pim_upstream_evaluate_join_desired (child))
-           pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
+            pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
 
          /*
           * If the S,G has no if channel and the c_oil still
@@ -1016,7 +1016,7 @@ void pim_ifchannel_local_membership_del(struct interface *ifp,
           * if channel.  So remove it.
           */
          if (!chchannel && c_oil && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index])
-           pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM);
+            pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_STAR);
         }
     }
   delete_on_noinfo(ch);
index dfd22b7022e9d50ab3fb83c41199e8c58992ceec..05d08b6e918ee992c0c410c95a681b5b689403a3 100644 (file)
@@ -812,13 +812,10 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
 
   if (PIM_DEBUG_MROUTE)
     {
-      struct prefix_sg sg;
-
-      sg.src = c_oil->oil.mfcc_origin;
-      sg.grp = c_oil->oil.mfcc_mcastgrp;
-
-      zlog_debug("%s(%s), Added Route: %s to mroute table",
-                __PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg));
+      char buf[1000];
+      zlog_debug("%s(%s), Added Route: %s",
+                 __PRETTY_FUNCTION__, name,
+                 pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
     }
 
   c_oil->installed = 1;
@@ -850,14 +847,12 @@ int pim_mroute_del (struct channel_oil *c_oil, const char *name)
 
   if (PIM_DEBUG_MROUTE)
     {
-      struct prefix_sg sg;
-
-      sg.src = c_oil->oil.mfcc_origin;
-      sg.grp = c_oil->oil.mfcc_mcastgrp;
-
-      zlog_debug("%s(%s), Deleted Route: %s from mroute table",
-                __PRETTY_FUNCTION__, name, pim_str_sg_dump(&sg));
+      char buf[1000];
+      zlog_debug("%s(%s), Deleted Route: %s",
+                 __PRETTY_FUNCTION__, name,
+                 pim_channel_oil_dump (c_oil, buf, sizeof(buf)));
     }
+
   c_oil->installed = 0;
 
   return 0;
index 0cebe473558fe51914b2970de7afd24b10adcb37..4c5eff4883e36992d52f1b712630815c5ad56c29 100644 (file)
 struct list *pim_channel_oil_list = NULL;
 struct hash *pim_channel_oil_hash = NULL;
 
+char *
+pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size)
+{
+  struct prefix_sg sg;
+  int i;
+
+  memset (buf, 0, size);
+  sg.src = c_oil->oil.mfcc_origin;
+  sg.grp = c_oil->oil.mfcc_mcastgrp;
+  sprintf(buf, "%s IIF: %d, OIFS: ",
+          pim_str_sg_dump (&sg), c_oil->oil.mfcc_parent);
+
+  for (i = 0 ; i < MAXVIFS ; i++)
+    {
+      if (c_oil->oil.mfcc_ttls[i] != 0)
+        {
+          char buf1[10];
+          sprintf(buf1, "%d ", i);
+          strcat(buf, buf1);
+        }
+    }
+
+  return buf;
+}
+
 static int
 pim_channel_oil_compare (struct channel_oil *c1, struct channel_oil *c2)
 {
@@ -353,25 +378,26 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
   }
 
   /* Allow other protocol to request subscription of same interface to
-     channel (S,G) multiple times, by silently ignoring further
-     requests */
+   * channel (S,G), we need to note this information
+   */
   if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & PIM_OIF_FLAG_PROTO_ANY) {
 
+    channel_oil->oif_creation[pim_ifp->mroute_vif_index] = pim_time_monotonic_sec();
+    channel_oil->oif_flags[pim_ifp->mroute_vif_index] |= proto_mask;
     /* Check the OIF really exists before returning, and only log
        warning otherwise */
     if (channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index] < 1) {
-      if (PIM_DEBUG_MROUTE)
-       {
-         char group_str[INET_ADDRSTRLEN];
-         char source_str[INET_ADDRSTRLEN];
-         pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-         pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
-         zlog_debug("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
-                    __FILE__, __PRETTY_FUNCTION__,
-                    proto_mask, oif->name, pim_ifp->mroute_vif_index,
-                    channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
-                    source_str, group_str);
-       }
+      {
+        char group_str[INET_ADDRSTRLEN];
+        char source_str[INET_ADDRSTRLEN];
+        pim_inet4_dump("<group?>", channel_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
+        pim_inet4_dump("<source?>", channel_oil->oil.mfcc_origin, source_str, sizeof(source_str));
+        zlog_warn("%s %s: new protocol mask %u requested nonexistent OIF %s (vif_index=%d, min_ttl=%d) for channel (S,G)=(%s,%s)",
+                  __FILE__, __PRETTY_FUNCTION__,
+                  proto_mask, oif->name, pim_ifp->mroute_vif_index,
+                  channel_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index],
+                  source_str, group_str);
+      }
     }
 
     return 0;
index 143cfb7942d2c1c008876c3eac4d5bd773237a75..6b96750ad107ca747a57f32e645f135ae8bb56a9 100644 (file)
  * IGMP - Learned from IGMP
  * PIM - Learned from PIM
  * SOURCE - Learned from Source multicast packet received
+ * STAR - Inherited
  */
 #define PIM_OIF_FLAG_PROTO_IGMP   (1 << 0)
 #define PIM_OIF_FLAG_PROTO_PIM    (1 << 1)
-#define PIM_OIF_FLAG_PROTO_SOURCE (2 << 1)
+#define PIM_OIF_FLAG_PROTO_SOURCE (1 << 2)
+#define PIM_OIF_FLAG_PROTO_STAR   (1 << 3)
 #define PIM_OIF_FLAG_PROTO_ANY    (PIM_OIF_FLAG_PROTO_IGMP | \
                                    PIM_OIF_FLAG_PROTO_PIM | \
-                                   PIM_OIF_FLAG_PROTO_SOURCE)
+                                   PIM_OIF_FLAG_PROTO_SOURCE | \
+                                   PIM_OIF_FLAG_PROTO_STAR)
 
 /*
  * We need a pimreg vif id from the kernel.
@@ -96,4 +99,6 @@ int pim_channel_del_oif (struct channel_oil *c_oil,
                         uint32_t proto_mask);
 
 int pim_channel_oil_empty (struct channel_oil *c_oil);
+
+char *pim_channel_oil_dump (struct channel_oil *c_oil, char *buf, size_t size);
 #endif /* PIM_OIL_H */
index fbb7d84a25a1a45a7faebbd65adf1689de410ff5..4ae49c0fd47709ed3bac04999db98d2fc82bda0c 100644 (file)
@@ -1288,7 +1288,11 @@ pim_upstream_inherited_olist_decide (struct pim_upstream *up)
 
       if (pim_upstream_evaluate_join_desired_interface (up, ch))
        {
-         pim_channel_add_oif (up->channel_oil, ch->interface, PIM_OIF_FLAG_PROTO_PIM);
+          int flag = PIM_OIF_FLAG_PROTO_PIM;
+
+          if (ch->sg.src.s_addr == INADDR_ANY && ch->upstream != up)
+            flag = PIM_OIF_FLAG_PROTO_STAR;
+          pim_channel_add_oif (up->channel_oil, ch->interface, flag);
          output_intf++;
        }
     }