]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Create override for quagga reinstall of originated routes
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 26 Aug 2015 12:21:40 +0000 (05:21 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 26 Aug 2015 12:21:40 +0000 (05:21 -0700)
Ticket: CM-7026
Reviewed by: CCR-3315
Testing: See bug

Quagga-dev suggested these changes for the quagga override of originated routes.

zebra/main.c
zebra/test_main.c
zebra/zebra_rib.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h [new file with mode: 0644]
zebra/zebra_vty.c

index f8f59327838d425c965e058c8ee9ffcd53bee989..45fe38052b9076cdcad84027ccf6faea07cd3432 100644 (file)
@@ -59,6 +59,9 @@ struct thread_master *master;
 /* Route retain mode flag. */
 int retain_mode = 0;
 
+/* Allow non-quagga entities to delete quagga routes */
+int allow_delete = 0;
+
 /* Don't delete kernel route. */
 int keep_kernel_mode = 0;
 
@@ -70,23 +73,24 @@ u_int32_t nl_rcvbufsize = 4194304;
 /* Command line options. */
 struct option longopts[] = 
 {
-  { "batch",       no_argument,       NULL, 'b'},
-  { "daemon",      no_argument,       NULL, 'd'},
-  { "keep_kernel", no_argument,       NULL, 'k'},
-  { "config_file", required_argument, NULL, 'f'},
-  { "pid_file",    required_argument, NULL, 'i'},
-  { "socket",      required_argument, NULL, 'z'},
-  { "help",        no_argument,       NULL, 'h'},
-  { "vty_addr",    required_argument, NULL, 'A'},
-  { "vty_port",    required_argument, NULL, 'P'},
-  { "retain",      no_argument,       NULL, 'r'},
-  { "dryrun",      no_argument,       NULL, 'C'},
+  { "batch",        no_argument,       NULL, 'b'},
+  { "daemon",       no_argument,       NULL, 'd'},
+  { "allow_delete", no_argument,       NULL, 'a'},
+  { "keep_kernel",  no_argument,       NULL, 'k'},
+  { "config_file",  required_argument, NULL, 'f'},
+  { "pid_file",     required_argument, NULL, 'i'},
+  { "socket",       required_argument, NULL, 'z'},
+  { "help",         no_argument,       NULL, 'h'},
+  { "vty_addr",     required_argument, NULL, 'A'},
+  { "vty_port",     required_argument, NULL, 'P'},
+  { "retain",       no_argument,       NULL, 'r'},
+  { "dryrun",       no_argument,       NULL, 'C'},
 #ifdef HAVE_NETLINK
-  { "nl-bufsize",  required_argument, NULL, 's'},
+  { "nl-bufsize",   required_argument, NULL, 's'},
 #endif /* HAVE_NETLINK */
-  { "user",        required_argument, NULL, 'u'},
-  { "group",       required_argument, NULL, 'g'},
-  { "version",     no_argument,       NULL, 'v'},
+  { "user",         required_argument, NULL, 'u'},
+  { "group",        required_argument, NULL, 'g'},
+  { "version",      no_argument,       NULL, 'v'},
   { 0 }
 };
 
@@ -131,6 +135,7 @@ usage (char *progname, int status)
              "redistribution between different routing protocols.\n\n"\
              "-b, --batch        Runs in batch mode\n"\
              "-d, --daemon       Runs in daemon mode\n"\
+             "-a, --allow_delete Allow other processes to delete Quagga Routes\n" \
              "-f, --config_file  Set configuration file name\n"\
              "-i, --pid_file     Set process identifier file name\n"\
              "-z, --socket       Set path of zebra socket\n"\
@@ -237,9 +242,9 @@ main (int argc, char **argv)
       int opt;
   
 #ifdef HAVE_NETLINK  
-      opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vs:C", longopts, 0);
+      opt = getopt_long (argc, argv, "bdakf:i:z:hA:P:ru:g:vs:C", longopts, 0);
 #else
-      opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vC", longopts, 0);
+      opt = getopt_long (argc, argv, "bdakf:i:z:hA:P:ru:g:vC", longopts, 0);
 #endif /* HAVE_NETLINK */
 
       if (opt == EOF)
@@ -254,6 +259,9 @@ main (int argc, char **argv)
        case 'd':
          daemon_mode = 1;
          break;
+       case 'a':
+         allow_delete = 1;
+         break;
        case 'k':
          keep_kernel_mode = 1;
          break;
index 2d4874b7ddc175cab4eac4174e9b84cc2cec2871..d0a210bcbebfd9b999b37080d7765152f0e8d758 100644 (file)
@@ -45,6 +45,9 @@ struct zebra_t zebrad =
 /* process id. */
 pid_t pid;
 
+/* Allow non-quagga entities to delete quagga routes */
+int allow_delete = 0;
+
 /* zebra_rib's workqueue hold time. Private export for use by test code only */
 extern int rib_process_hold_time;
 
@@ -54,14 +57,15 @@ struct thread_master *master;
 /* Command line options. */
 struct option longopts[] = 
 {
-  { "batch",       no_argument,       NULL, 'b'},
-  { "daemon",      no_argument,       NULL, 'd'},
-  { "config_file", required_argument, NULL, 'f'},
-  { "help",        no_argument,       NULL, 'h'},
-  { "vty_addr",    required_argument, NULL, 'A'},
-  { "vty_port",    required_argument, NULL, 'P'},
-  { "version",     no_argument,       NULL, 'v'},
-  { "rib_hold",           required_argument, NULL, 'r'},
+  { "batch",        no_argument,       NULL, 'b'},
+  { "daemon",       no_argument,       NULL, 'd'},
+  { "allow_delete", no_argument,       NULL, 'a'},
+  { "config_file",  required_argument, NULL, 'f'},
+  { "help",         no_argument,       NULL, 'h'},
+  { "vty_addr",     required_argument, NULL, 'A'},
+  { "vty_port",     required_argument, NULL, 'P'},
+  { "version",      no_argument,       NULL, 'v'},
+  { "rib_hold",     required_argument, NULL, 'r'},
   { 0 }
 };
 
@@ -91,6 +95,7 @@ usage (char *progname, int status)
              "redistribution between different routing protocols.\n\n"\
              "-b, --batch        Runs in batch mode\n"\
              "-d, --daemon       Runs in daemon mode\n"\
+             "-a, --allow_delete Allow other processes to delete Quagga Routes\n" \
              "-f, --config_file  Set configuration file name\n"\
              "-A, --vty_addr     Set vty's bind address\n"\
              "-P, --vty_port     Set vty's port number\n"\
@@ -222,7 +227,7 @@ main (int argc, char **argv)
     {
       int opt;
   
-      opt = getopt_long (argc, argv, "bdf:hA:P:r:v", longopts, 0);
+      opt = getopt_long (argc, argv, "bdaf:hA:P:r:v", longopts, 0);
 
       if (opt == EOF)
        break;
@@ -236,6 +241,9 @@ main (int argc, char **argv)
        case 'd':
          daemon_mode = 1;
          break;
+       case 'a':
+         allow_delete =1;
+         break;
        case 'f':
          config_file = optarg;
          break;
index 41a7f68b885f667a372636922e3f4f88a315ac10..416c1dcf7bb410a6885405e908e90deaa1f00a18 100644 (file)
@@ -48,6 +48,9 @@
 /* Default rtm_table for all clients */
 extern struct zebra_t zebrad;
 
+/* Should we allow non Quagga processes to delete our routes */
+extern int allow_delete;
+
 /* Hold time for RIB process, should be very minimal.
  * it is useful to able to set it otherwise for testing, hence exported
  * as global here for test-rig code.
@@ -2695,9 +2698,20 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
                          inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                          p->prefixlen);
             }
-          /* This means someone else, other than Zebra, has deleted
-           * a Zebra router from the kernel. We will add it back */
-           rib_install_kernel(rn, fib, 0);
+         if (allow_delete)
+           {
+             /* Unset flags. */
+             for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
+               UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+
+             UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
+           }
+         else
+           {
+             /* This means someone else, other than Zebra, has deleted
+              * a Zebra router from the kernel. We will add it back */
+             rib_install_kernel(rn, fib, 0);
+           }
         }
       else
        {
@@ -3448,9 +3462,20 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
                          inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
                          p->prefixlen);
             }
-          /* This means someone else, other than Zebra, has deleted a Zebra
-           * route from the kernel. We will add it back */
-          rib_install_kernel(rn, fib, 0);
+         if (allow_delete)
+           {
+             /* Unset flags. */
+             for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
+               UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+
+             UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
+           }
+         else
+           {
+             /* This means someone else, other than Zebra, has deleted a Zebra
+              * route from the kernel. We will add it back */
+             rib_install_kernel(rn, fib, 0);
+           }
         }
       else
        {
index ec8ee45cdf6f72f7a0fdd9f62960b97ad36ab7c6..6648b8a4d518663f2f9b11d19d2e04464d837809 100644 (file)
@@ -33,6 +33,7 @@
 #include "zebra/zserv.h"
 #include "zebra/debug.h"
 #include "zebra/zebra_rnh.h"
+#include "zebra/zebra_routemap.h"
 
 static u_int32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
 static struct thread *zebra_t_rmap_update = NULL;
@@ -1558,16 +1559,11 @@ zebra_route_map_event (route_map_event_t event, const char *rmap_name)
 }
 
 /* ip protocol configuration write function */
-static int config_write_protocol(struct vty *vty)
+void
+zebra_routemap_config_write_protocol (struct vty *vty)
 {
   int i;
 
-  if (zebra_rnh_ip_default_route)
-    vty_out (vty, "ip nht resolve-via-default%s", VTY_NEWLINE);
-
-  if (zebra_rnh_ipv6_default_route)
-    vty_out (vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE);
-
   for (i=0;i<ZEBRA_ROUTE_MAX;i++)
     {
       if (proto_rm[AFI_IP][i])
@@ -1598,15 +1594,11 @@ static int config_write_protocol(struct vty *vty)
   if (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER)
     vty_out (vty, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer,
             VTY_NEWLINE);
-  return 1;
 }
-/* table node for protocol filtering */
-static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
 
 void
 zebra_route_map_init ()
 {
-  install_node (&protocol_node, config_write_protocol);
   install_element (CONFIG_NODE, &ip_protocol_cmd);
   install_element (CONFIG_NODE, &no_ip_protocol_cmd);
   install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h
new file mode 100644 (file)
index 0000000..0449601
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Zebra routemap header
+ * Copyright (C) 2015 Cumulus Networks, Inc.
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra 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, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __ZEBRA_ROUTEMAP_H__
+#define __ZEBRA_ROUTEMAP_H__
+
+extern void zebra_routemap_config_write_protocol(struct vty *vty);
+
+#endif
index c95322a5696ac89f25d84e9e2d9bd50f0c461c33..a797b88391a74a812ef884d9b541b4d4f7d1eef4 100644 (file)
@@ -32,6 +32,9 @@
 #include "zebra/zserv.h"
 #include "zebra/zebra_rnh.h"
 #include "zebra/redistribute.h"
+#include "zebra/zebra_routemap.h"
+
+extern int allow_delete;
 
 /* General fucntion for static route. */
 static int
@@ -2958,6 +2961,26 @@ static_config_ipv6 (struct vty *vty)
 }
 #endif /* HAVE_IPV6 */
 
+DEFUN (allow_external_route_update,
+       allow_external_route_update_cmd,
+       "allow-external-route-update",
+       "Allow Quagga routes to be overwritten by external processes")
+{
+  allow_delete = 1;
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_allow_external_route_update,
+       no_allow_external_route_update_cmd,
+       "no allow-external-route-update",
+       "Allow Quagga routes to be overwritten by external processes")
+{
+  allow_delete = 0;
+
+  return CMD_SUCCESS;
+}
+
 /* Static ip route configuration write function. */
 static int
 zebra_ip_config (struct vty *vty)
@@ -3060,15 +3083,36 @@ ALIAS (no_ip_zebra_import_table,
        "kernel routing table id\n"
        "distance to be used\n")
 
+static int
+config_write_protocol (struct vty *vty)
+{
+  if (allow_delete)
+    vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE);
+
+  if (zebra_rnh_ip_default_route)
+    vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE);
+
+  if (zebra_rnh_ipv6_default_route)
+    vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE);
+
+  zebra_routemap_config_write_protocol(vty);
+
+  return 1;
+}
+
 /* IP node for static routes. */
 static struct cmd_node ip_node = { IP_NODE,  "",  1 };
+static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
 
 /* Route VTY.  */
 void
 zebra_vty_init (void)
 {
   install_node (&ip_node, zebra_ip_config);
+  install_node (&protocol_node, config_write_protocol);
 
+  install_element (CONFIG_NODE, &allow_external_route_update_cmd);
+  install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
   install_element (CONFIG_NODE, &ip_route_cmd);
   install_element (CONFIG_NODE, &ip_route_tag_cmd);
   install_element (CONFIG_NODE, &ip_route_flags_cmd);