diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 380d06522b..f698e62e9c 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -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 { diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index f18679dad3..2ef16bdf80 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -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); diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c index da1bab876a..205382b482 100644 --- a/zebra/zebra_rnh_null.c +++ b/zebra/zebra_rnh_null.c @@ -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; } diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 55f131d61e..6ec28d73a8 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -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", @@ -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);