From 5a0bdc782c209e4cc57c549f313bfd6d1ca316eb Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 28 Aug 2019 16:01:38 +0200 Subject: [PATCH] zebra: nht resolution default configurable per vrf even if vty commands were available, the default resolution command was working only for the first vrf configured. others were ignored. Also, for nexthop, resolution was working for all vrfs, and not the specific one. Signed-off-by: Philippe Guibert --- zebra/zebra_nhg.c | 7 +++++-- zebra/zebra_rnh.c | 14 ++++++++++---- zebra/zebra_rnh.h | 14 ++------------ zebra/zebra_vrf.c | 11 +++++++++++ zebra/zebra_vrf.h | 3 +++ zebra/zebra_vty.c | 22 ++++++++-------------- 6 files changed, 39 insertions(+), 32 deletions(-) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index f4b86f3cfe..be6fa30ebd 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -120,6 +120,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, struct nexthop *newhop; struct interface *ifp; rib_dest_t *dest; + struct zebra_vrf *zvrf; if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6) @@ -194,7 +195,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re, } /* Lookup table. */ table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id); - if (!table) { + /* get zvrf */ + zvrf = zebra_vrf_lookup_by_id(nexthop->vrf_id); + if (!table || !zvrf) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug("\t%s: Table not found", __PRETTY_FUNCTION__); @@ -224,7 +227,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, /* However, do not resolve over default route unless explicitly * allowed. */ if (is_default_prefix(&rn->p) - && !rnh_resolve_via_default(p.family)) { + && !rnh_resolve_via_default(zvrf, p.family)) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( "\t:%s: Resolved against default route", diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index da2fe4a30c..666ebb70e8 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -62,9 +62,6 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, static void print_rnh(struct route_node *rn, struct vty *vty); static int zebra_client_cleanup_rnh(struct zserv *client); -int zebra_rnh_ip_default_route = 0; -int zebra_rnh_ipv6_default_route = 0; - void zebra_rnh_init(void) { hook_register(zserv_client_close, zebra_client_cleanup_rnh); @@ -656,7 +653,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi, * match route to be exact if so specified */ if (is_default_prefix(&rn->p) - && !rnh_resolve_via_default(rn->p.family)) { + && !rnh_resolve_via_default(zvrf, rn->p.family)) { if (IS_ZEBRA_DEBUG_NHT_DETAILED) zlog_debug( "\tNot allowed to resolve through default prefix"); @@ -1213,3 +1210,12 @@ static int zebra_client_cleanup_rnh(struct zserv *client) return 0; } + +int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family) +{ + if (((family == AF_INET) && zvrf->zebra_rnh_ip_default_route) + || ((family == AF_INET6) && zvrf->zebra_rnh_ipv6_default_route)) + return 1; + else + return 0; +} diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index c7d2c0d298..6e2dab8d9f 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -29,20 +29,8 @@ extern "C" { #endif -extern int zebra_rnh_ip_default_route; -extern int zebra_rnh_ipv6_default_route; - extern void zebra_rnh_init(void); -static inline int 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 inline const char *rnh_type2str(rnh_type_t type) { switch (type) { @@ -72,6 +60,8 @@ extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty, rnh_type_t type, struct prefix *p); extern char *rnh_str(struct rnh *rnh, char *buf, int size); +extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family); + #ifdef __cplusplus } #endif diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index fcc94a7be9..72d0b6866d 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -488,6 +488,11 @@ static int vrf_config_write(struct vty *vty) if (zvrf_id(zvrf) == VRF_DEFAULT) { if (zvrf->l3vni) vty_out(vty, "vni %u\n", zvrf->l3vni); + if (zvrf->zebra_rnh_ip_default_route) + vty_out(vty, "ip nht resolve-via-default\n"); + + if (zvrf->zebra_rnh_ipv6_default_route) + vty_out(vty, "ipv6 nht resolve-via-default\n"); } else { vty_frame(vty, "vrf %s\n", zvrf_name(zvrf)); if (zvrf->l3vni) @@ -497,8 +502,14 @@ static int vrf_config_write(struct vty *vty) ? " prefix-routes-only" : ""); zebra_ns_config_write(vty, (struct ns *)vrf->ns_ctxt); + if (zvrf->zebra_rnh_ip_default_route) + vty_out(vty, " ip nht resolve-via-default\n"); + + if (zvrf->zebra_rnh_ipv6_default_route) + vty_out(vty, " ipv6 nht resolve-via-default\n"); } + zebra_routemap_config_write_protocol(vty, zvrf); if (zvrf_id(zvrf) != VRF_DEFAULT) diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index f92e1a010b..6c80f9bcb4 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -174,6 +174,9 @@ struct zebra_vrf { #if defined(HAVE_RTADV) struct rtadv rtadv; #endif /* HAVE_RTADV */ + + int zebra_rnh_ip_default_route; + int zebra_rnh_ipv6_default_route; }; #define PROTO_RM_NAME(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].name #define NHT_RM_NAME(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].name diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 5c0dc27380..ac28f38121 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1086,10 +1086,10 @@ DEFUN (ip_nht_default_route, if (!zvrf) return CMD_WARNING; - if (zebra_rnh_ip_default_route) + if (zvrf->zebra_rnh_ip_default_route) return CMD_SUCCESS; - zebra_rnh_ip_default_route = 1; + zvrf->zebra_rnh_ip_default_route = 1; zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; @@ -1108,10 +1108,10 @@ DEFUN (no_ip_nht_default_route, if (!zvrf) return CMD_WARNING; - if (!zebra_rnh_ip_default_route) + if (!zvrf->zebra_rnh_ip_default_route) return CMD_SUCCESS; - zebra_rnh_ip_default_route = 0; + zvrf->zebra_rnh_ip_default_route = 0; zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -1128,10 +1128,10 @@ DEFUN (ipv6_nht_default_route, if (!zvrf) return CMD_WARNING; - if (zebra_rnh_ipv6_default_route) + if (zvrf->zebra_rnh_ipv6_default_route) return CMD_SUCCESS; - zebra_rnh_ipv6_default_route = 1; + zvrf->zebra_rnh_ipv6_default_route = 1; zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -1150,10 +1150,10 @@ DEFUN (no_ipv6_nht_default_route, if (!zvrf) return CMD_WARNING; - if (!zebra_rnh_ipv6_default_route) + if (!zvrf->zebra_rnh_ipv6_default_route) return CMD_SUCCESS; - zebra_rnh_ipv6_default_route = 0; + zvrf->zebra_rnh_ipv6_default_route = 0; zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL); return CMD_SUCCESS; } @@ -2625,12 +2625,6 @@ static int config_write_protocol(struct vty *vty) if (allow_delete) vty_out(vty, "allow-external-route-update\n"); - if (zebra_rnh_ip_default_route) - vty_out(vty, "ip nht resolve-via-default\n"); - - if (zebra_rnh_ipv6_default_route) - vty_out(vty, "ipv6 nht resolve-via-default\n"); - if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME) vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold); -- 2.39.5