]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_cmd.c
Merge remote-tracking branch 'origin/stable/3.0'
[mirror_frr.git] / pimd / pim_cmd.c
index 5fe52fc3fc54ba344304e423381bc613df6d88bd..da07dcb4acbe769021e4045eceb8378ba00b21a6 100644 (file)
@@ -1,22 +1,21 @@
 /*
-  PIM for Quagga
-  Copyright (C) 2008  Everton da Silva Marques
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  General Public License for more details.
-  
-  You should have received a copy of the GNU General Public License
-  along with this program; see the file COPYING; if not, write to the
-  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-  MA 02110-1301 USA
-*/
+ * PIM for Quagga
+ * Copyright (C) 2008  Everton da Silva Marques
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 
 #include <zebra.h>
 
@@ -3495,7 +3494,7 @@ static void show_mroute(struct vty *vty, u_char uj)
         json_object_string_add(json_ifp_out, "group", grp_str);
         json_object_boolean_true_add(json_ifp_out, "protocolStatic");
         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_int_add(json_ifp_out, "iVifI", s_route->c_oil.oil.mfcc_parent);
         json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
         json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
         json_object_int_add(json_ifp_out, "ttl", ttl);
@@ -3779,6 +3778,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",
@@ -3787,10 +3813,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,
@@ -3802,15 +3838,26 @@ 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,
        ip_pim_joinprune_time_cmd,
-       "ip pim join-prune-interval <60-600>",
+       "ip pim join-prune-interval (60-600)",
        IP_STR
        "pim multicast routing\n"
        "Join Prune Send Interval\n"
@@ -3822,7 +3869,7 @@ DEFUN (ip_pim_joinprune_time,
 
 DEFUN (no_ip_pim_joinprune_time,
        no_ip_pim_joinprune_time_cmd,
-       "no ip pim join-prune-interval <60-600>",
+       "no ip pim join-prune-interval (60-600)",
        NO_STR
        IP_STR
        "pim multicast routing\n"
@@ -3835,19 +3882,19 @@ DEFUN (no_ip_pim_joinprune_time,
 
 DEFUN (ip_pim_register_suppress,
        ip_pim_register_suppress_cmd,
-       "ip pim register-suppress-time <5-60000>",
+       "ip pim register-suppress-time (5-60000)",
        IP_STR
        "pim multicast routing\n"
        "Register Suppress Timer\n"
        "Seconds\n")
 {
-  qpim_keep_alive_time = atoi (argv[3]->arg);
+  qpim_register_suppress_time = atoi (argv[3]->arg);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_ip_pim_register_suppress,
        no_ip_pim_register_suppress_cmd,
-       "no ip pim register-suppress-time <5-60000>",
+       "no ip pim register-suppress-time (5-60000)",
        NO_STR
        IP_STR
        "pim multicast routing\n"
@@ -3860,19 +3907,19 @@ DEFUN (no_ip_pim_register_suppress,
 
 DEFUN (ip_pim_keep_alive,
        ip_pim_keep_alive_cmd,
-       "ip pim keep-alive-timer <31-60000>",
+       "ip pim keep-alive-timer (31-60000)",
        IP_STR
        "pim multicast routing\n"
        "Keep alive Timer\n"
        "Seconds\n")
 {
-  qpim_rp_keep_alive_time = atoi (argv[4]->arg);
+  qpim_keep_alive_time = atoi (argv[3]->arg);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_ip_pim_keep_alive,
        no_ip_pim_keep_alive_cmd,
-       "no ip pim keep-alive-timer <31-60000>",
+       "no ip pim keep-alive-timer (31-60000)",
        NO_STR
        IP_STR
        "pim multicast routing\n"
@@ -3885,7 +3932,7 @@ DEFUN (no_ip_pim_keep_alive,
 
 DEFUN (ip_pim_packets,
        ip_pim_packets_cmd,
-       "ip pim packets <1-100>",
+       "ip pim packets (1-100)",
        IP_STR
        "pim multicast routing\n"
        "packets to process at one time per fd\n"
@@ -3897,7 +3944,7 @@ DEFUN (ip_pim_packets,
 
 DEFUN (no_ip_pim_packets,
        no_ip_pim_packets_cmd,
-       "no ip pim packets <1-100>",
+       "no ip pim packets (1-100)",
        NO_STR
        IP_STR
        "pim multicast routing\n"
@@ -3945,9 +3992,10 @@ DEFUN (ip_pim_rp,
   int idx_ipv4 = 3;
 
   if (argc == (idx_ipv4 + 1))
-    return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
-  else
     return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
+  else
+    return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+
 }
 
 DEFUN (ip_pim_rp_prefix_list,
@@ -4200,7 +4248,7 @@ DEFUN (ip_ssmpingd,
   int idx_ipv4 = 2;
   int result;
   struct in_addr source_addr;
-  const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+  const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
 
   result = inet_pton(AF_INET, source_str, &source_addr);
   if (result <= 0) {
@@ -4230,7 +4278,7 @@ DEFUN (no_ip_ssmpingd,
   int idx_ipv4 = 3;
   int result;
   struct in_addr source_addr;
-  const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+  const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
 
   result = inet_pton(AF_INET, source_str, &source_addr);
   if (result <= 0) {
@@ -4282,6 +4330,7 @@ DEFUN (ip_pim_ecmp_rebalance,
        "Enable PIM ECMP \n"
        "Enable PIM ECMP Rebalance\n")
 {
+  qpim_ecmp_enable = 1;
   qpim_ecmp_rebalance_enable = 1;
 
   return CMD_SUCCESS;
@@ -4305,23 +4354,37 @@ static int
 pim_cmd_igmp_start (struct vty *vty, struct interface *ifp)
 {
   struct pim_interface *pim_ifp;
+  uint8_t need_startup = 0;
 
   pim_ifp = ifp->info;
 
-  if (!pim_ifp) {
-    pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
-    if (!pim_ifp) {
-      vty_out(vty, "Could not enable IGMP on interface %s%s",
+  if (!pim_ifp)
+    {
+      pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
+      if (!pim_ifp)
+        {
+          vty_out(vty, "Could not enable IGMP on interface %s%s",
              ifp->name, VTY_NEWLINE);
-      return CMD_WARNING;
+          return CMD_WARNING;
+        }
+      need_startup = 1;
+    }
+  else
+    {
+      if (!PIM_IF_TEST_IGMP(pim_ifp->options))
+        {
+          PIM_IF_DO_IGMP(pim_ifp->options);
+          need_startup = 1;
+        }
     }
-  }
-  else {
-    PIM_IF_DO_IGMP(pim_ifp->options);
-  }
 
-  pim_if_addr_add_all(ifp);
-  pim_if_membership_refresh(ifp);
+  /* 'ip igmp' executed multiple times, with need_startup
+    avoid multiple if add all and membership refresh */
+  if (need_startup)
+    {
+      pim_if_addr_add_all(ifp);
+      pim_if_membership_refresh(ifp);
+    }
 
   return CMD_SUCCESS;
 }
@@ -4687,22 +4750,37 @@ DEFUN (interface_ip_igmp_version,
        "IGMP version number\n")
 {
   VTY_DECLVAR_CONTEXT(interface,ifp);
-  struct pim_interface *pim_ifp;
-  int igmp_version;
+  struct pim_interface *pim_ifp = NULL;
+  int igmp_version, old_version = 0;
   int ret;
 
   pim_ifp = ifp->info;
 
-  if (!pim_ifp) {
-    ret = pim_cmd_igmp_start(vty, ifp);
-    if (ret != CMD_SUCCESS)
-      return ret;
-    pim_ifp = ifp->info;
-  }
+  if (!pim_ifp)
+    {
+      ret = pim_cmd_igmp_start(vty, ifp);
+      if (ret != CMD_SUCCESS)
+        return ret;
+      pim_ifp = ifp->info;
+    }
 
   igmp_version = atoi(argv[3]->arg);
+  old_version = pim_ifp->igmp_version;
   pim_ifp->igmp_version = igmp_version;
 
+  //Check if IGMP is Enabled otherwise, enable on interface
+  if (!PIM_IF_TEST_IGMP (pim_ifp->options))
+    {
+      PIM_IF_DO_IGMP(pim_ifp->options);
+      pim_if_addr_add_all(ifp);
+      pim_if_membership_refresh(ifp);
+      old_version = igmp_version;   //avoid refreshing membership again.
+    }
+  /* Current and new version is different refresh existing
+     membership. Going from 3 -> 2 or 2 -> 3. */
+  if (old_version != igmp_version)
+    pim_if_membership_refresh(ifp);
+
   return CMD_SUCCESS;
 }
 
@@ -5249,7 +5327,7 @@ DEFUN (interface_ip_pim_hello,
 
   pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
 
-  if (argc == idx_hold)
+  if (argc == idx_hold + 1)
     pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
 
   return CMD_SUCCESS;
@@ -6124,7 +6202,7 @@ DEFUN (no_ip_msdp_mesh_group_source,
        "mesh group source\n"
        "mesh group local address\n")
 {
-  if (argc == 6)
+  if (argc == 7)
     return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
   else
     return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
@@ -6660,7 +6738,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);
@@ -6716,7 +6796,6 @@ void pim_cmd_init()
   install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
   install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
   install_element (VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
-  install_element (VIEW_NODE, &show_ip_pim_interface_traffic_single_cmd);
   install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
   install_element (VIEW_NODE, &show_ip_pim_join_cmd);
   install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);