]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Add prefix list handling to spt-switchover
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 7 Apr 2017 14:16:23 +0000 (10:16 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 20 Apr 2017 19:55:50 +0000 (15:55 -0400)
To the 'ip pim spt-switchover infinity-and-beyond' command
add 'prefix-list <PLIST>'. To the command.

Use this as the basis to deny (Not immediate switchover)
or permit (Immediate switchover), based upon matching
the group address and the prefix-list.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_cmd.c
pimd/pim_ifchannel.c
pimd/pim_memory.c
pimd/pim_memory.h
pimd/pim_upstream.c
pimd/pim_upstream.h
pimd/pim_vty.c
pimd/pimd.c
pimd/pimd.h

index de2b7cbba6db84befdf469037f007d29c944b6cb..f04fafdafa9825dbda349fb0574f03ba784be345 100644 (file)
@@ -3416,6 +3416,33 @@ pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const cha
   return CMD_SUCCESS;
 }
 
+static int
+pim_cmd_spt_switchover (enum pim_spt_switchover spt, const char *plist)
+{
+  pimg->spt.switchover = spt;
+
+  switch (pimg->spt.switchover)
+    {
+    case PIM_SPT_IMMEDIATE:
+      if (pimg->spt.plist)
+        XFREE (MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
+
+      pim_upstream_add_lhr_star_pimreg ();
+      break;
+    case PIM_SPT_INFINITY:
+      pim_upstream_remove_lhr_star_pimreg (plist);
+
+      if (pimg->spt.plist)
+        XFREE (MTYPE_PIM_SPT_PLIST_NAME, pimg->spt.plist);
+
+      if (plist)
+        pimg->spt.plist = XSTRDUP (MTYPE_PIM_SPT_PLIST_NAME, plist);
+      break;
+    }
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (ip_pim_spt_switchover_infinity,
        ip_pim_spt_switchover_infinity_cmd,
        "ip pim spt-switchover infinity-and-beyond",
@@ -3424,10 +3451,20 @@ DEFUN (ip_pim_spt_switchover_infinity,
        "SPT-Switchover\n"
        "Never switch to SPT Tree\n")
 {
-  pimg->spt_switchover = PIM_SPT_INFINITY;
+  return pim_cmd_spt_switchover (PIM_SPT_INFINITY, NULL);
+}
 
-  pim_upstream_remove_lhr_star_pimreg();
-  return CMD_SUCCESS;
+DEFUN (ip_pim_spt_switchover_infinity_plist,
+       ip_pim_spt_switchover_infinity_plist_cmd,
+       "ip pim spt-switchover infinity-and-beyond prefix-list WORD",
+       IP_STR
+       PIM_STR
+       "SPT-Switchover\n"
+       "Never switch to SPT Tree\n"
+       "Prefix-List to control which groups to switch\n"
+       "Prefix-List name\n")
+{
+  return pim_cmd_spt_switchover (PIM_SPT_INFINITY, argv[5]->arg);
 }
 
 DEFUN (no_ip_pim_spt_switchover_infinity,
@@ -3439,10 +3476,21 @@ DEFUN (no_ip_pim_spt_switchover_infinity,
        "SPT_Switchover\n"
        "Never switch to SPT Tree\n")
 {
-  pimg->spt_switchover = PIM_SPT_IMMEDIATE;
+  return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE, NULL);
+}
 
-  pim_upstream_add_lhr_star_pimreg();
-  return CMD_SUCCESS;
+DEFUN (no_ip_pim_spt_switchover_infinity_plist,
+       no_ip_pim_spt_switchover_infinity_plist_cmd,
+       "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
+       NO_STR
+       IP_STR
+       PIM_STR
+       "SPT_Switchover\n"
+       "Never switch to SPT Tree\n"
+       "Prefix-List to control which groups to switch\n"
+       "Prefix-List name\n")
+{
+  return pim_cmd_spt_switchover (PIM_SPT_IMMEDIATE, NULL);
 }
 
 DEFUN (ip_pim_joinprune_time,
@@ -6217,7 +6265,9 @@ void pim_cmd_init()
   install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
   install_element (CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
+  install_element (CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
   install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
   install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
index ebd36f8782509c45fa47abaa3e4ab54156dd9afd..fc84a5c2fe57e6afb8580296d674906363ca6fec 100644 (file)
@@ -27,6 +27,7 @@
 #include "vrf.h"
 #include "hash.h"
 #include "jhash.h"
+#include "prefix.h"
 
 #include "pimd.h"
 #include "pim_str.h"
@@ -1006,8 +1007,25 @@ pim_ifchannel_local_membership_add(struct interface *ifp,
              pim_upstream_switch (child, PIM_UPSTREAM_JOINED);
            }
         }
-      if (pimg->spt_switchover != PIM_SPT_INFINITY)
-        pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
+
+      if (pimg->spt.switchover == PIM_SPT_INFINITY)
+        {
+          if (pimg->spt.plist)
+            {
+              struct prefix_list *plist = prefix_list_lookup (AFI_IP, pimg->spt.plist);
+              struct prefix g;
+              g.family = AF_INET;
+              g.prefixlen = IPV4_MAX_PREFIXLEN;
+              g.u.prefix4 = up->sg.grp;
+
+              if (prefix_list_apply (plist, &g) == PREFIX_DENY)
+                {
+                  pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
+                }
+            }
+         }
+       else
+         pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
     }
 
   return 1;
index 2acca6f49be879483ee3cdc56db6fa8c4eaac0d0..ab92665b97939469f4fbab9eb6998d135488024e 100644 (file)
@@ -52,3 +52,4 @@ DEFINE_MTYPE(PIMD, PIM_JP_AGG_SOURCE,     "PIM JP AGG Source")
 DEFINE_MTYPE(PIMD, PIM_PIM_INSTANCE,      "PIM global state")
 DEFINE_MTYPE(PIMD, PIM_NEXTHOP_CACHE,     "PIM nexthop cache state")
 DEFINE_MTYPE(PIMD, PIM_SSM_INFO,          "PIM SSM configuration")
+DEFINE_MTYPE(PIMD, PIM_SPT_PLIST_NAME,    "PIM SPT Prefix List Name")
index 02446de46a65f93d48c725d129490a15ba10cb86..e366377c87b5dae6ee2f8c75139b23ecb424ceaa 100644 (file)
@@ -51,5 +51,6 @@ DECLARE_MTYPE(PIM_JP_AGG_SOURCE)
 DECLARE_MTYPE(PIM_PIM_INSTANCE)
 DECLARE_MTYPE(PIM_NEXTHOP_CACHE)
 DECLARE_MTYPE(PIM_SSM_INFO)
+DECLARE_MTYPE(PIM_SPT_PLIST_NAME);
 
 #endif /* _QUAGGA_PIM_MEMORY_H */
index 5743dac6548ad4235e68dfa6d02bf71e0d872d0f..167588daef61d21d5a41700e1a2dd9b175409408 100644 (file)
@@ -1695,10 +1695,41 @@ pim_upstream_add_lhr_star_pimreg (void)
 }
 
 void
-pim_upstream_remove_lhr_star_pimreg (void)
+pim_upstream_spt_prefix_list_update (struct prefix_list *pl)
+{
+  const char *pname = prefix_list_name (pl);
+
+  if (pimg->spt.plist && strcmp (pimg->spt.plist, pname) == 0)
+    {
+      pim_upstream_remove_lhr_star_pimreg (pname);
+    }
+}
+
+/*
+ * nlist -> The new prefix list
+ *
+ * Per Group Application of pimreg to the OIL
+ * If the prefix list tells us DENY then
+ * we need to Switchover to SPT immediate
+ * so add the pimreg.
+ * If the prefix list tells us to ACCEPT than
+ * we need to Never do the SPT so remove
+ * the interface
+ *
+ */
+void
+pim_upstream_remove_lhr_star_pimreg (const char *nlist)
 {
   struct pim_upstream *up;
   struct listnode *node;
+  struct prefix_list *np;
+  struct prefix g;
+  enum prefix_list_type apply_new;
+
+  np = prefix_list_lookup (AFI_IP, nlist);
+
+  g.family = AF_INET;
+  g.prefixlen = IPV4_MAX_PREFIXLEN;
 
   for (ALL_LIST_ELEMENTS_RO (pim_upstream_list, node, up))
     {
@@ -1708,7 +1739,17 @@ pim_upstream_remove_lhr_star_pimreg (void)
       if (!PIM_UPSTREAM_FLAG_TEST_SRC_IGMP (up->flags))
         continue;
 
-      pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
+      if (!nlist)
+        {
+          pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
+          continue;
+        }
+      g.u.prefix4 = up->sg.grp;
+      apply_new = prefix_list_apply (np, &g);
+      if (apply_new == PREFIX_DENY)
+        pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
+      else
+        pim_channel_del_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_IGMP);
     }
 }
 
index a1af4483acd703695705ace44c8b66ef7e328fcd..ec40f3c243fa9883befde50e779c114f24697d80 100644 (file)
@@ -200,5 +200,7 @@ int pim_upstream_compare (void *arg1, void *arg2);
 void pim_upstream_register_reevaluate (void);
 
 void pim_upstream_add_lhr_star_pimreg (void);
-void pim_upstream_remove_lhr_star_pimreg (void);
+void pim_upstream_remove_lhr_star_pimreg (const char *nlist);
+
+void pim_upstream_spt_prefix_list_update (struct prefix_list *pl);
 #endif /* PIM_UPSTREAM_H */
index 3d52dc9c41624a630c1e6f38e978ecebb565894e..c8322b629a8907c36f3ea580fdb5a40ed3d035f5 100644 (file)
@@ -182,10 +182,14 @@ int pim_global_config_write(struct vty *vty)
                ssm->plist_name, VTY_NEWLINE);
       ++writes;
     }
-  if (pimg->spt_switchover == PIM_SPT_INFINITY)
+  if (pimg->spt.switchover == PIM_SPT_INFINITY)
     {
-      vty_out (vty, "ip pim spt-switchover infinity-and-beyond%s",
-               VTY_NEWLINE);
+      if (pimg->spt.plist)
+        vty_out (vty, "ip pim spt-switchover infinity-and-beyond prefix-list %s%s",
+                 pimg->spt.plist, VTY_NEWLINE);
+      else
+        vty_out (vty, "ip pim spt-switchover infinity-and-beyond%s",
+                 VTY_NEWLINE);
       ++writes;
     }
 
index eaef4ff5c0331bbe0a7fc78be7403c8a4ec30220..a8a2a806e098b90494c3937abcbe541c2534a8c8 100644 (file)
@@ -194,6 +194,7 @@ pim_prefix_list_update (struct prefix_list *plist)
 {
     pim_rp_prefix_list_update (plist);
     pim_ssm_prefix_list_update (plist);
+    pim_upstream_spt_prefix_list_update (plist);
 }
 
 static void
@@ -249,7 +250,9 @@ pim_instance_init (vrf_id_t vrf_id, afi_t afi)
   pim->vrf_id = vrf_id;
   pim->afi = afi;
 
-  pim->spt_switchover = PIM_SPT_IMMEDIATE;
+  pim->spt.switchover = PIM_SPT_IMMEDIATE;
+  pim->spt.plist = NULL;
+
   pim->rpf_hash = hash_create_size (256, pim_rpf_hash_key, pim_rpf_equal);
 
   if (PIM_DEBUG_ZEBRA)
index 6c3dcfafcabea50fce4035cd8d2dbec66ed04f7d..246be17d4068b69411902db9ad0cf5125734a11d 100644 (file)
@@ -248,7 +248,10 @@ struct pim_instance
   afi_t afi;
   vrf_id_t vrf_id;
 
-  enum pim_spt_switchover spt_switchover;
+  struct {
+    enum pim_spt_switchover switchover;
+    char *plist;
+  } spt;
 
   struct hash *rpf_hash;
   void *ssm_info; /* per-vrf SSM configuration */