summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-08-26 05:21:40 -0700
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-08-26 05:21:40 -0700
commit6baf7bb88b1b02221b2d213d089f1077aae4ee1d (patch)
tree12975c88bc6f3504d3ba831f3edca7cfb2993d17
parentc44e65bd3ffc2c342c96c7a12dd2fa4f5880a841 (diff)
Create override for quagga reinstall of originated routes
Ticket: CM-7026 Reviewed by: CCR-3315 Testing: See bug Quagga-dev suggested these changes for the quagga override of originated routes.
-rw-r--r--zebra/main.c42
-rw-r--r--zebra/test_main.c26
-rw-r--r--zebra/zebra_rib.c37
-rw-r--r--zebra/zebra_routemap.c14
-rw-r--r--zebra/zebra_routemap.h28
-rw-r--r--zebra/zebra_vty.c44
6 files changed, 148 insertions, 43 deletions
diff --git a/zebra/main.c b/zebra/main.c
index f8f5932783..45fe38052b 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -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;
diff --git a/zebra/test_main.c b/zebra/test_main.c
index 2d4874b7dd..d0a210bcbe 100644
--- a/zebra/test_main.c
+++ b/zebra/test_main.c
@@ -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;
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 41a7f68b88..416c1dcf7b 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -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
{
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index ec8ee45cdf..6648b8a4d5 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -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
index 0000000000..0449601280
--- /dev/null
+++ b/zebra/zebra_routemap.h
@@ -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
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index c95322a569..a797b88391 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -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);