Zebra: Don't resolve routes over default for nexthop tracking

Resolving routes over the default route for NHT can lead to all sorts
of problems. So, we explicitly exclude resolving routes for NHT over the
default route. A knob is provided to allow the route to be resolved over
the default in case of special circumstances.

Signed-off-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
Reviewed-by:   Daniel Walton <dwalton@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-05-19 18:04:16 -07:00
parent c5f7794faa
commit a50b580a0f
5 changed files with 108 additions and 1 deletions

View File

@ -63,6 +63,9 @@ static int compare_state(struct rib *r1, struct rib *r2);
static int send_client(struct rnh *rnh, struct zserv *client);
static void print_rnh(struct route_node *rn, struct vty *vty);
int zebra_rnh_ip_default_route = 0;
int zebra_rnh_ipv6_default_route = 0;
char *
rnh_str (struct rnh *rnh, char *buf, int size)
{
@ -217,6 +220,30 @@ zebra_deregister_rnh_static_nh(struct prefix *nh, struct route_node *static_rn)
zebra_delete_rnh(rnh);
}
static inline int
zebra_rnh_is_default_route(struct prefix *p)
{
if (!p)
return 0;
if (((p->family == AF_INET) && (p->u.prefix4.s_addr == INADDR_ANY))
|| ((p->family == AF_INET6) &&
!memcmp(&p->u.prefix6, &in6addr_any, sizeof (struct in6_addr))))
return 1;
return 0;
}
static inline int
zebra_rnh_resolve_via_default(int family)
{
if (((family == AF_INET) && zebra_rnh_ip_default_route) ||
((family == AF_INET6) && zebra_rnh_ipv6_default_route))
return 1;
else
return 0;
}
static int
zebra_evaluate_rnh_nexthops(int family, struct rib *rib, struct route_node *prn,
int proto)
@ -290,7 +317,8 @@ zebra_evaluate_rnh_table (int vrfid, int family, int force)
at_least_one = 0;
prn = route_node_match(ptable, &nrn->p);
if (!prn)
if (!prn || (zebra_rnh_is_default_route(&prn->p) &&
!zebra_rnh_resolve_via_default(prn->p.family)))
rib = NULL;
else
{

View File

@ -40,6 +40,9 @@ struct rnh
int filtered[ZEBRA_ROUTE_MAX]; /* if this has been filtered for client */
};
extern int zebra_rnh_ip_default_route;
extern int zebra_rnh_ipv6_default_route;
extern struct rnh *zebra_add_rnh(struct prefix *p, u_int32_t vrfid);
extern struct rnh *zebra_lookup_rnh(struct prefix *p, u_int32_t vrfid);
extern void zebra_delete_rnh(struct rnh *rnh);

View File

@ -3,6 +3,9 @@
#include "zebra/zserv.h"
#include "zebra/zebra_rnh.h"
int zebra_rnh_ip_default_route = 0;
int zebra_rnh_ipv6_default_route = 0;
int zebra_evaluate_rnh_table (int vrfid, int family, int force)
{ return 0; }

View File

@ -1558,6 +1558,12 @@ static int 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])

View File

@ -1195,6 +1195,69 @@ DEFUN (show_ipv6_nht,
return CMD_SUCCESS;
}
DEFUN (ip_nht_default_route,
ip_nht_default_route_cmd,
"ip nht resolve-via-default",
IP_STR
"Filter Next Hop tracking route resolution\n"
"Resolve via default route\n")
{
if (zebra_rnh_ip_default_route)
return CMD_SUCCESS;
zebra_rnh_ip_default_route = 1;
zebra_evaluate_rnh_table(0, AF_INET, 1);
return CMD_SUCCESS;
}
DEFUN (no_ip_nht_default_route,
no_ip_nht_default_route_cmd,
"no ip nht resolve-via-default",
NO_STR
IP_STR
"Filter Next Hop tracking route resolution\n"
"Resolve via default route\n")
{
if (!zebra_rnh_ip_default_route)
return CMD_SUCCESS;
zebra_rnh_ip_default_route = 0;
zebra_evaluate_rnh_table(0, AF_INET, 1);
return CMD_SUCCESS;
}
DEFUN (ipv6_nht_default_route,
ipv6_nht_default_route_cmd,
"ipv6 nht resolve-via-default",
IP6_STR
"Filter Next Hop tracking route resolution\n"
"Resolve via default route\n")
{
if (zebra_rnh_ipv6_default_route)
return CMD_SUCCESS;
zebra_rnh_ipv6_default_route = 1;
zebra_evaluate_rnh_table(0, AF_INET6, 1);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_nht_default_route,
no_ipv6_nht_default_route_cmd,
"no ipv6 nht resolve-via-default",
NO_STR
IP6_STR
"Filter Next Hop tracking route resolution\n"
"Resolve via default route\n")
{
if (!zebra_rnh_ipv6_default_route)
return CMD_SUCCESS;
zebra_rnh_ipv6_default_route = 0;
zebra_evaluate_rnh_table(0, AF_INET6, 1);
return CMD_SUCCESS;
}
DEFUN (show_ip_route_tag,
show_ip_route_tag_cmd,
"show ip route tag <1-65535>",
@ -3097,6 +3160,10 @@ zebra_vty_init (void)
install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_tag_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_cmd);
install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_tag_cmd);
install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
install_element (VIEW_NODE, &show_ipv6_route_cmd);
install_element (VIEW_NODE, &show_ipv6_route_tag_cmd);
install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);