]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: vrf aware routmap is missing in Zebra #2802(Part 1 of 4)
authorvishaldhingra <vdhingra@vmware.com>
Thu, 11 Oct 2018 17:44:55 +0000 (10:44 -0700)
committervishaldhingra <vdhingra@vmware.com>
Thu, 11 Oct 2018 17:44:55 +0000 (10:44 -0700)
 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
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h
zebra/zebra_vrf.h

index bdcf03a0558c93f6bbf1a41413d4432f1db573fb..53afbdc8fc05fe5e29b00b732497efcbc46baf9f 100644 (file)
@@ -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;
index 622ed5ac05833be2e2b1def29711ee335fee5e5c..e2b28673163ddd9063796544e88ca57c7a65d020 100644 (file)
@@ -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 */
index 7a6bc6684d331d3698fc8d60f26b35937afb8a52..1318c09b572ec4b9030449a06b9ec0e9782a8bf2 100644 (file)
@@ -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);
 
index d33487d7afb68b7dc20a2c9aaf92f510a70b5e4a..62ba8de6709cf00ef649a0ba571f38dbf83ef79e 100644 (file)
@@ -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
index b8664f4ec764ec64e07989edd754e91931a5ab03..b676ff12695c66bcd74dbb0fdc48590281f82012 100644 (file)
@@ -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)
 {