From: vishaldhingra Date: Thu, 11 Oct 2018 17:44:55 +0000 (-0700) Subject: zebra: vrf aware routmap is missing in Zebra #2802(Part 1 of 4) X-Git-Tag: frr-7.1-dev~279^2~3 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=ac6eebce505fa54e27dd5d70ad56f5d96d99bd9d;p=mirror%2Ffrr.git zebra: vrf aware routmap is missing in Zebra #2802(Part 1 of 4) Work to handle the route-maps, namely the header changes in zebra_vrf.h and the mapping of using that everywhere Signed-off-by: vishaldhingra vdhingra@vmware.com --- diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index bdcf03a055..53afbdc8fc 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -886,6 +886,8 @@ static unsigned nexthop_active_check(struct route_node *rn, int family; char buf[SRCDEST2STR_BUFFER]; const struct prefix *p, *src_p; + struct zebra_vrf *zvrf; + srcdest_rnode_prefixes(rn, &p, &src_p); if (rn->p.family == AF_INET) @@ -949,7 +951,8 @@ static unsigned nexthop_active_check(struct route_node *rn, } /* XXX: What exactly do those checks do? Do we support - * e.g. IPv4 routes with IPv6 nexthops or vice versa? */ + * e.g. IPv4 routes with IPv6 nexthops or vice versa? + */ if (RIB_SYSTEM_ROUTE(re) || (family == AFI_IP && p->family != AF_INET) || (family == AFI_IP6 && p->family != AF_INET6)) return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -969,9 +972,16 @@ static unsigned nexthop_active_check(struct route_node *rn, memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); + zvrf = zebra_vrf_lookup_by_id(nexthop->vrf_id); + if (!zvrf) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("\t%s: zvrf is NULL", __PRETTY_FUNCTION__); + return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + } + /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re->type, re->instance, p, nexthop, - nexthop->vrf_id, re->tag); + ret = zebra_route_map_check(family, re->type, re->instance, p, + nexthop, zvrf, re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { srcdest_rnode2str(rn, buf, sizeof(buf)); @@ -1002,6 +1012,7 @@ static int nexthop_active_update(struct route_node *rn, struct route_entry *re, union g_addr prev_src; unsigned int prev_active, new_active, old_num_nh; ifindex_t prev_index; + old_num_nh = re->nexthop_active_num; re->nexthop_active_num = 0; diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 622ed5ac05..e2b2867316 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -302,8 +302,10 @@ static int zebra_rnh_apply_nht_rmap(int family, struct route_node *prn, if (prn && re) { for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) { - ret = zebra_nht_route_map_check(rmap_family, proto, - &prn->p, re, nexthop); + struct zebra_vrf *zvrf = + zebra_vrf_lookup_by_id(nexthop->vrf_id); + ret = zebra_nht_route_map_check( + rmap_family, proto, &prn->p, zvrf, re, nexthop); if (ret != RMAP_DENYMATCH) { SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); at_least_one++; /* at least one valid NH */ diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 7a6bc6684d..1318c09b57 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1309,42 +1309,63 @@ static void zebra_rib_table_rm_update(const char *rmap) { int i = 0; struct route_table *table; + struct vrf *vrf = NULL; + struct zebra_vrf *zvrf = NULL; char *rmap_name; char afi_ip = 0; char afi_ipv6 = 0; - for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { - /* Check for ip routemap table */ - rmap_name = proto_rm[AFI_IP][i]; - if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s : AFI_IP rmap %s, route type %s", - __func__, rmap, zebra_route_string(i)); - /* There is single rib table for all protocols */ - if (afi_ip == 0) { - table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, - VRF_DEFAULT); - if (table) { - afi_ip = 1; - rib_update_table(table, - RIB_UPDATE_RMAP_CHANGE); + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + zvrf = vrf->info; + if (!zvrf) + continue; + for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { + rmap_name = PROTO_RM_NAME(zvrf, AFI_IP, i); + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "%s : AFI_IP rmap %s, route type %s", + __func__, rmap, + zebra_route_string(i)); + + PROTO_RM_MAP(zvrf, AFI_IP, i) = + route_map_lookup_by_name(rmap_name); + /* There is single rib table for all protocols + */ + if (afi_ip == 0) { + table = zvrf->table[AFI_IP] + [SAFI_UNICAST]; + if (table) { + + afi_ip = 1; + rib_update_table( + table, + RIB_UPDATE_RMAP_CHANGE); + } } } - } - - /* Check for ipv6 routemap table */ - rmap_name = proto_rm[AFI_IP6][i]; - if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s : AFI_IP6 rmap %s,route type %s", - __func__, rmap, zebra_route_string(i)); - if (afi_ipv6 == 0) { - table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, - VRF_DEFAULT); - if (table) { - afi_ipv6 = 1; - rib_update_table(table, - RIB_UPDATE_RMAP_CHANGE); + rmap_name = PROTO_RM_NAME(zvrf, AFI_IP6, i); + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "%s : AFI_IP6 rmap %s, route type %s", + __func__, rmap, + zebra_route_string(i)); + + PROTO_RM_MAP(zvrf, AFI_IP6, i) = + route_map_lookup_by_name(rmap_name); + /* There is single rib table for all protocols + */ + if (afi_ipv6 == 0) { + table = zvrf->table[AFI_IP6] + [SAFI_UNICAST]; + if (table) { + + afi_ipv6 = 1; + rib_update_table( + table, + RIB_UPDATE_RMAP_CHANGE); + } } } } @@ -1358,31 +1379,70 @@ static void zebra_rib_table_rm_update(const char *rmap) static void zebra_nht_rm_update(const char *rmap) { int i = 0; + struct route_table *table; + struct vrf *vrf = NULL; + struct zebra_vrf *zvrf = NULL; char *rmap_name; char afi_ip = 0; char afi_ipv6 = 0; - for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { - rmap_name = nht_rm[AFI_IP][i]; - if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s : AFI_IP rmap %s route type %s", - __func__, rmap, zebra_route_string(i)); - if (afi_ip == 0) { - afi_ip = 1; - zebra_evaluate_rnh(0, AF_INET, 1, - RNH_NEXTHOP_TYPE, NULL); + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + zvrf = vrf->info; + if (!zvrf) + continue; + for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { + rmap_name = NHT_RM_NAME(zvrf, AFI_IP, i); + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "%s : AFI_IP rmap %s, route type %s", + __func__, rmap, + zebra_route_string(i)); + + NHT_RM_MAP(zvrf, AFI_IP, i) = + route_map_lookup_by_name(rmap_name); + /* There is single rib table for all protocols + */ + if (afi_ip == 0) { + table = zvrf->table[AFI_IP] + [SAFI_UNICAST]; + if (table) { + + afi_ip = 1; + + zebra_evaluate_rnh( + zvrf->vrf->vrf_id, + AF_INET, 1, + RNH_NEXTHOP_TYPE, NULL); + } + } } - } - rmap_name = nht_rm[AFI_IP6][i]; - if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s : AFI_IP6 rmap %s route type %s", - __func__, rmap, zebra_route_string(i)); - if (afi_ipv6 == 0) { - afi_ipv6 = 1; - zebra_evaluate_rnh(0, AF_INET6, 1, - RNH_NEXTHOP_TYPE, NULL); + + rmap_name = NHT_RM_NAME(zvrf, AFI_IP6, i); + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "%s : AFI_IP6 rmap %s, route type %s", + __func__, rmap, + zebra_route_string(i)); + + NHT_RM_MAP(zvrf, AFI_IP6, i) = + route_map_lookup_by_name(rmap_name); + /* There is single rib table for all protocols + */ + if (afi_ipv6 == 0) { + table = zvrf->table[AFI_IP6] + [SAFI_UNICAST]; + if (table) { + + afi_ipv6 = 1; + + zebra_evaluate_rnh( + zvrf->vrf->vrf_id, + AF_INET, 1, + RNH_NEXTHOP_TYPE, NULL); + } + } } } } @@ -1439,28 +1499,26 @@ void zebra_route_map_write_delay_timer(struct vty *vty) return; } -route_map_result_t zebra_route_map_check(int family, int rib_type, - uint8_t instance, - const struct prefix *p, - struct nexthop *nexthop, - vrf_id_t vrf_id, route_tag_t tag) +route_map_result_t +zebra_route_map_check(int family, int rib_type, uint8_t instance, + const struct prefix *p, struct nexthop *nexthop, + struct zebra_vrf *zvrf, route_tag_t tag) { struct route_map *rmap = NULL; route_map_result_t ret = RMAP_MATCH; struct nh_rmap_obj nh_obj; nh_obj.nexthop = nexthop; - nh_obj.vrf_id = vrf_id; + nh_obj.vrf_id = nexthop->vrf_id; nh_obj.source_protocol = rib_type; nh_obj.instance = instance; nh_obj.metric = 0; nh_obj.tag = tag; if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) - rmap = route_map_lookup_by_name(proto_rm[family][rib_type]); - if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX]) - rmap = route_map_lookup_by_name( - proto_rm[family][ZEBRA_ROUTE_MAX]); + rmap = PROTO_RM_MAP(zvrf, family, rib_type); + if (!rmap && PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_MAX)) + rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX); if (rmap) { ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); } @@ -1514,6 +1572,7 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance, route_map_result_t zebra_nht_route_map_check(int family, int client_proto, const struct prefix *p, + struct zebra_vrf *zvrf, struct route_entry *re, struct nexthop *nexthop) { @@ -1529,10 +1588,9 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto, nh_obj.tag = re->tag; if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) - rmap = route_map_lookup_by_name(nht_rm[family][client_proto]); - if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX]) - rmap = route_map_lookup_by_name( - nht_rm[family][ZEBRA_ROUTE_MAX]); + rmap = NHT_RM_MAP(zvrf, family, client_proto); + if (!rmap && NHT_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX)) + rmap = NHT_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX); if (rmap) ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index d33487d7af..62ba8de670 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -42,10 +42,10 @@ zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance, extern route_map_result_t zebra_route_map_check(int family, int rib_type, uint8_t instance, const struct prefix *p, struct nexthop *nexthop, - vrf_id_t vrf_id, route_tag_t tag); + struct zebra_vrf *zvrf, route_tag_t tag); extern route_map_result_t zebra_nht_route_map_check(int family, int client_proto, const struct prefix *p, - struct route_entry *, struct nexthop *nexthop); - + struct zebra_vrf *zvrf, struct route_entry *, + struct nexthop *nexthop); #endif diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index b8664f4ec7..b676ff1269 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -32,6 +32,11 @@ typedef struct mpls_srgb_t_ { uint32_t end_label; } mpls_srgb_t; +struct zebra_rmap { + char *name; + struct route_map *map; +}; + /* Routing table instance. */ struct zebra_vrf { /* Back pointer */ @@ -92,6 +97,9 @@ struct zebra_vrf { struct zebra_pw_head pseudowires; struct zebra_static_pw_head static_pseudowires; + struct zebra_rmap proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1]; + struct zebra_rmap nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1]; + /* MPLS processing flags */ uint16_t mpls_flags; #define MPLS_FLAG_SCHEDULE_LSPS (1 << 0) @@ -122,6 +130,10 @@ struct zebra_vrf { uint64_t lsp_installs; uint64_t lsp_removals; }; +#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 +#define PROTO_RM_MAP(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].map +#define NHT_RM_MAP(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].map static inline vrf_id_t zvrf_id(struct zebra_vrf *zvrf) {