diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-08-26 05:21:40 -0700 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-08-26 05:21:40 -0700 |
| commit | 6baf7bb88b1b02221b2d213d089f1077aae4ee1d (patch) | |
| tree | 12975c88bc6f3504d3ba831f3edca7cfb2993d17 | |
| parent | c44e65bd3ffc2c342c96c7a12dd2fa4f5880a841 (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.c | 42 | ||||
| -rw-r--r-- | zebra/test_main.c | 26 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 37 | ||||
| -rw-r--r-- | zebra/zebra_routemap.c | 14 | ||||
| -rw-r--r-- | zebra/zebra_routemap.h | 28 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 44 |
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); |
