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.
This commit is contained in:
Donald Sharp 2015-08-26 05:21:40 -07:00
parent c44e65bd3f
commit 6baf7bb88b
6 changed files with 148 additions and 43 deletions

View File

@ -59,6 +59,9 @@ struct thread_master *master;
/* Route retain mode flag. */ /* Route retain mode flag. */
int retain_mode = 0; int retain_mode = 0;
/* Allow non-quagga entities to delete quagga routes */
int allow_delete = 0;
/* Don't delete kernel route. */ /* Don't delete kernel route. */
int keep_kernel_mode = 0; int keep_kernel_mode = 0;
@ -70,23 +73,24 @@ u_int32_t nl_rcvbufsize = 4194304;
/* Command line options. */ /* Command line options. */
struct option longopts[] = struct option longopts[] =
{ {
{ "batch", no_argument, NULL, 'b'}, { "batch", no_argument, NULL, 'b'},
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
{ "keep_kernel", no_argument, NULL, 'k'}, { "allow_delete", no_argument, NULL, 'a'},
{ "config_file", required_argument, NULL, 'f'}, { "keep_kernel", no_argument, NULL, 'k'},
{ "pid_file", required_argument, NULL, 'i'}, { "config_file", required_argument, NULL, 'f'},
{ "socket", required_argument, NULL, 'z'}, { "pid_file", required_argument, NULL, 'i'},
{ "help", no_argument, NULL, 'h'}, { "socket", required_argument, NULL, 'z'},
{ "vty_addr", required_argument, NULL, 'A'}, { "help", no_argument, NULL, 'h'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_addr", required_argument, NULL, 'A'},
{ "retain", no_argument, NULL, 'r'}, { "vty_port", required_argument, NULL, 'P'},
{ "dryrun", no_argument, NULL, 'C'}, { "retain", no_argument, NULL, 'r'},
{ "dryrun", no_argument, NULL, 'C'},
#ifdef HAVE_NETLINK #ifdef HAVE_NETLINK
{ "nl-bufsize", required_argument, NULL, 's'}, { "nl-bufsize", required_argument, NULL, 's'},
#endif /* HAVE_NETLINK */ #endif /* HAVE_NETLINK */
{ "user", required_argument, NULL, 'u'}, { "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'}, { "group", required_argument, NULL, 'g'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ 0 } { 0 }
}; };
@ -131,6 +135,7 @@ usage (char *progname, int status)
"redistribution between different routing protocols.\n\n"\ "redistribution between different routing protocols.\n\n"\
"-b, --batch Runs in batch mode\n"\ "-b, --batch Runs in batch mode\n"\
"-d, --daemon Runs in daemon 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"\ "-f, --config_file Set configuration file name\n"\
"-i, --pid_file Set process identifier file name\n"\ "-i, --pid_file Set process identifier file name\n"\
"-z, --socket Set path of zebra socket\n"\ "-z, --socket Set path of zebra socket\n"\
@ -237,9 +242,9 @@ main (int argc, char **argv)
int opt; int opt;
#ifdef HAVE_NETLINK #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 #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 */ #endif /* HAVE_NETLINK */
if (opt == EOF) if (opt == EOF)
@ -254,6 +259,9 @@ main (int argc, char **argv)
case 'd': case 'd':
daemon_mode = 1; daemon_mode = 1;
break; break;
case 'a':
allow_delete = 1;
break;
case 'k': case 'k':
keep_kernel_mode = 1; keep_kernel_mode = 1;
break; break;

View File

@ -45,6 +45,9 @@ struct zebra_t zebrad =
/* process id. */ /* process id. */
pid_t pid; 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 */ /* zebra_rib's workqueue hold time. Private export for use by test code only */
extern int rib_process_hold_time; extern int rib_process_hold_time;
@ -54,14 +57,15 @@ struct thread_master *master;
/* Command line options. */ /* Command line options. */
struct option longopts[] = struct option longopts[] =
{ {
{ "batch", no_argument, NULL, 'b'}, { "batch", no_argument, NULL, 'b'},
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
{ "config_file", required_argument, NULL, 'f'}, { "allow_delete", no_argument, NULL, 'a'},
{ "help", no_argument, NULL, 'h'}, { "config_file", required_argument, NULL, 'f'},
{ "vty_addr", required_argument, NULL, 'A'}, { "help", no_argument, NULL, 'h'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_addr", required_argument, NULL, 'A'},
{ "version", no_argument, NULL, 'v'}, { "vty_port", required_argument, NULL, 'P'},
{ "rib_hold", required_argument, NULL, 'r'}, { "version", no_argument, NULL, 'v'},
{ "rib_hold", required_argument, NULL, 'r'},
{ 0 } { 0 }
}; };
@ -91,6 +95,7 @@ usage (char *progname, int status)
"redistribution between different routing protocols.\n\n"\ "redistribution between different routing protocols.\n\n"\
"-b, --batch Runs in batch mode\n"\ "-b, --batch Runs in batch mode\n"\
"-d, --daemon Runs in daemon 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"\ "-f, --config_file Set configuration file name\n"\
"-A, --vty_addr Set vty's bind address\n"\ "-A, --vty_addr Set vty's bind address\n"\
"-P, --vty_port Set vty's port number\n"\ "-P, --vty_port Set vty's port number\n"\
@ -222,7 +227,7 @@ main (int argc, char **argv)
{ {
int opt; 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) if (opt == EOF)
break; break;
@ -236,6 +241,9 @@ main (int argc, char **argv)
case 'd': case 'd':
daemon_mode = 1; daemon_mode = 1;
break; break;
case 'a':
allow_delete =1;
break;
case 'f': case 'f':
config_file = optarg; config_file = optarg;
break; break;

View File

@ -48,6 +48,9 @@
/* Default rtm_table for all clients */ /* Default rtm_table for all clients */
extern struct zebra_t zebrad; 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. /* Hold time for RIB process, should be very minimal.
* it is useful to able to set it otherwise for testing, hence exported * it is useful to able to set it otherwise for testing, hence exported
* as global here for test-rig code. * 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), inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
p->prefixlen); p->prefixlen);
} }
/* This means someone else, other than Zebra, has deleted if (allow_delete)
* a Zebra router from the kernel. We will add it back */ {
rib_install_kernel(rn, fib, 0); /* 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 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), inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
p->prefixlen); p->prefixlen);
} }
/* This means someone else, other than Zebra, has deleted a Zebra if (allow_delete)
* route from the kernel. We will add it back */ {
rib_install_kernel(rn, fib, 0); /* 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 else
{ {

View File

@ -33,6 +33,7 @@
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/debug.h" #include "zebra/debug.h"
#include "zebra/zebra_rnh.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 u_int32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
static struct thread *zebra_t_rmap_update = NULL; 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 */ /* ip protocol configuration write function */
static int config_write_protocol(struct vty *vty) void
zebra_routemap_config_write_protocol (struct vty *vty)
{ {
int i; 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++) for (i=0;i<ZEBRA_ROUTE_MAX;i++)
{ {
if (proto_rm[AFI_IP][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) 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_out (vty, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer,
VTY_NEWLINE); VTY_NEWLINE);
return 1;
} }
/* table node for protocol filtering */
static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
void void
zebra_route_map_init () zebra_route_map_init ()
{ {
install_node (&protocol_node, config_write_protocol);
install_element (CONFIG_NODE, &ip_protocol_cmd); install_element (CONFIG_NODE, &ip_protocol_cmd);
install_element (CONFIG_NODE, &no_ip_protocol_cmd); install_element (CONFIG_NODE, &no_ip_protocol_cmd);
install_element (CONFIG_NODE, &no_ip_protocol_val_cmd); install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);

28
zebra/zebra_routemap.h Normal file
View File

@ -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

View File

@ -32,6 +32,9 @@
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/zebra_rnh.h" #include "zebra/zebra_rnh.h"
#include "zebra/redistribute.h" #include "zebra/redistribute.h"
#include "zebra/zebra_routemap.h"
extern int allow_delete;
/* General fucntion for static route. */ /* General fucntion for static route. */
static int static int
@ -2958,6 +2961,26 @@ static_config_ipv6 (struct vty *vty)
} }
#endif /* HAVE_IPV6 */ #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 ip route configuration write function. */
static int static int
zebra_ip_config (struct vty *vty) zebra_ip_config (struct vty *vty)
@ -3060,15 +3083,36 @@ ALIAS (no_ip_zebra_import_table,
"kernel routing table id\n" "kernel routing table id\n"
"distance to be used\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. */ /* IP node for static routes. */
static struct cmd_node ip_node = { IP_NODE, "", 1 }; static struct cmd_node ip_node = { IP_NODE, "", 1 };
static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
/* Route VTY. */ /* Route VTY. */
void void
zebra_vty_init (void) zebra_vty_init (void)
{ {
install_node (&ip_node, zebra_ip_config); 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_cmd);
install_element (CONFIG_NODE, &ip_route_tag_cmd); install_element (CONFIG_NODE, &ip_route_tag_cmd);
install_element (CONFIG_NODE, &ip_route_flags_cmd); install_element (CONFIG_NODE, &ip_route_flags_cmd);