]> git.proxmox.com Git - mirror_frr.git/commitdiff
isisd: added support for routemap match tag in redistribution
authorEmanuele Altomare <emanuele@common-net.org>
Fri, 5 Mar 2021 22:12:00 +0000 (22:12 +0000)
committerEmanuele Altomare <emanuele@common-net.org>
Fri, 5 Mar 2021 22:12:00 +0000 (22:12 +0000)
Now it's possible to filter routes redistributed by another protocol using tag
which comes from zebra daemon.

Example of a possible configuration:

```
!
ipv6 route fd00::/48 blackhole tag 20
ipv6 route fd00::/60 blackhole tag 10
!
interface one
 ipv6 router isis COMMON
 isis circuit-type level-1
!
interface two
 ipv6 router isis COMMON
 isis circuit-type level-2-only
!
router isis COMMON
 net fd.0000.0000.0000.0001.00
 redistribute ipv6 static level-1 route-map static-l1
 redistribute ipv6 static level-2 route-map static-l2
 topology ipv6-unicast
!
route-map static-l1 permit 10
 match tag 10
!
route-map static-l2 permit 10
 match tag 20
!
```

Signed-off-by: Emanuele Altomare <emanuele@common-net.org>
isisd/isis_redist.c
isisd/isis_redist.h
isisd/isis_routemap.c
isisd/isis_zebra.c

index 240be27cf35f34bdf936b2fd25c1817214493ef9..856c47b9b74906dbd89604fe179ec891a3be7237 100644 (file)
@@ -219,7 +219,7 @@ static void isis_redist_ensure_default(struct isis *isis, int family)
 /* Handle notification about route being added */
 void isis_redist_add(struct isis *isis, int type, struct prefix *p,
                     struct prefix_ipv6 *src_p, uint8_t distance,
-                    uint32_t metric)
+                    uint32_t metric, const route_tag_t tag)
 {
        int family = p->family;
        struct route_table *ei_table = get_ext_info(isis, family);
@@ -250,6 +250,7 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
        info->origin = type;
        info->distance = distance;
        info->metric = metric;
+       info->tag = tag;
 
        if (is_default_prefix(p)
            && (!src_p || !src_p->prefixlen)) {
@@ -288,7 +289,7 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
                 * "always" setting will ignore routes with origin
                 * DEFAULT_ROUTE. */
                isis_redist_add(isis, DEFAULT_ROUTE, p, NULL, 254,
-                               MAX_WIDE_PATH_METRIC);
+                               MAX_WIDE_PATH_METRIC, 0);
                return;
        }
 
index afce922240e3e4cbb423c1d745b6b900acf5b1ba..fcc4ceadf49b92e170182855a5c1c44bf490617e 100644 (file)
@@ -31,6 +31,7 @@ struct isis_ext_info {
        int origin;
        uint32_t metric;
        uint8_t distance;
+       route_tag_t tag;
 };
 
 struct isis_redist {
@@ -50,7 +51,7 @@ struct route_table *get_ext_reach(struct isis_area *area, int family,
                                  int level);
 void isis_redist_add(struct isis *isis, int type, struct prefix *p,
                     struct prefix_ipv6 *src_p, uint8_t distance,
-                    uint32_t metric);
+                    uint32_t metric, route_tag_t tag);
 void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
                        struct prefix_ipv6 *src_p);
 int isis_redist_config_write(struct vty *vty, struct isis_area *area,
index db0f2fd8be3fd996fb3a80fa4cf3ed266f45c7a9..626e399e1591f5d6ed931b7a24a9d06b2cb5881b 100644 (file)
@@ -112,6 +112,35 @@ static const struct route_map_rule_cmd
 
 /* ------------------------------------------------------------*/
 
+/* `match tag TAG' */
+/* Match function return 1 if match is success else return zero. */
+static enum route_map_cmd_result_t
+route_match_tag(void *rule, const struct prefix *p, void *object)
+{
+       route_tag_t *tag;
+       struct isis_ext_info *info;
+       route_tag_t info_tag;
+
+       tag = rule;
+       info = object;
+
+       info_tag = info->tag;
+       if (info_tag == *tag)
+               return RMAP_MATCH;
+       else
+               return RMAP_NOMATCH;
+}
+
+/* Route map commands for tag matching. */
+static const struct route_map_rule_cmd route_match_tag_cmd = {
+       "tag",
+       route_match_tag,
+       route_map_rule_tag_compile,
+       route_map_rule_tag_free,
+};
+
+/* ------------------------------------------------------------*/
+
 static enum route_map_cmd_result_t
 route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
 {
@@ -234,6 +263,9 @@ void isis_route_map_init(void)
        route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
        route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
 
+       route_map_match_tag_hook(generic_match_add);
+       route_map_no_match_tag_hook(generic_match_delete);
+
        route_map_set_metric_hook(generic_set_add);
        route_map_no_set_metric_hook(generic_set_delete);
 
@@ -241,5 +273,6 @@ void isis_route_map_init(void)
        route_map_install_match(&route_match_ip_address_prefix_list_cmd);
        route_map_install_match(&route_match_ipv6_address_cmd);
        route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
+       route_map_install_match(&route_match_tag_cmd);
        route_map_install_set(&route_set_metric_cmd);
 }
index 703532234ab55a0ffc1a7da93347e1a484b144d9..cb4dd2569d14f869b5bbee50cde99277b856a708 100644 (file)
@@ -509,7 +509,7 @@ static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
 
        if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
                isis_redist_add(isis, api.type, &api.prefix, &api.src_prefix,
-                               api.distance, api.metric);
+                               api.distance, api.metric, api.tag);
        else
                isis_redist_delete(isis, api.type, &api.prefix,
                                   &api.src_prefix);