]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Add 'match source-instance' to allow finer grained control
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 17 May 2018 14:29:49 +0000 (10:29 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 17 May 2018 14:57:59 +0000 (10:57 -0400)
Add to zebra route-maps the ability to match on a source-instance

route-map FOO deny 55
 match source-instance 5
route-map FOO permit 60

ip protocol any route-map FOO

This will match any protocol route installation with a source-instance of 5.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/redistribute.c
zebra/zebra_rib.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h

index 5a6565aec9cf145c0c6a1f814047a0dd920dcd55..b1387815bad85660d349cd630704ef9d21620760 100644 (file)
@@ -539,8 +539,8 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re,
        afi = family2afi(rn->p.family);
        if (rmap_name)
                ret = zebra_import_table_route_map_check(
-                       afi, re->type, &rn->p, re->ng.nexthop, re->vrf_id,
-                       re->tag, rmap_name);
+                       afi, re->type, re->instance, &rn->p, re->ng.nexthop,
+                       re->vrf_id, re->tag, rmap_name);
 
        if (ret != RMAP_MATCH) {
                UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
index 7ec640164afcc57081cd5ba519379e93bd31d0d3..dec4ed06a97e5bd937d3cb61a087a975df35bef1 100644 (file)
@@ -924,7 +924,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
        memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
 
        /* It'll get set if required inside */
-       ret = zebra_route_map_check(family, re->type, p, nexthop,
+       ret = zebra_route_map_check(family, re->type, re->instance, p, nexthop,
                                    nexthop->vrf_id, re->tag);
        if (ret == RMAP_DENYMATCH) {
                if (IS_ZEBRA_DEBUG_RIB) {
index 013e841a5caa70f0901f57cab772ae8c57d8af00..0382df69a9c414902cdff52b9d68b449158ce157 100644 (file)
@@ -49,6 +49,7 @@ struct nh_rmap_obj {
        struct nexthop *nexthop;
        vrf_id_t vrf_id;
        uint32_t source_protocol;
+       uint8_t instance;
        int metric;
        route_tag_t tag;
 };
@@ -343,6 +344,32 @@ DEFUN (no_match_source_protocol,
                                        RMAP_EVENT_MATCH_DELETED);
 }
 
+DEFUN (match_source_instance,
+       match_source_instance_cmd,
+       "match source-instance (0-255)",
+       MATCH_STR
+       "Match the protocol's instance number\n"
+       "The instance number\n")
+{
+       char *instance = argv[2]->arg;
+
+       return zebra_route_match_add(vty, "source-instance", instance,
+                                    RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_source_instance,
+       no_match_source_instance_cmd,
+       "no match source-instance [(0-255)]",
+       NO_STR MATCH_STR
+       "Match the protocol's instance number\n"
+       "The instance number\n")
+{
+       char *instance = (argc == 4) ? argv[3]->arg : NULL;
+
+       return zebra_route_match_delete(vty, "source-instance", instance,
+                                       RMAP_EVENT_MATCH_ADDED);
+}
+
 /* set functions */
 
 DEFUN (set_src,
@@ -1172,6 +1199,47 @@ static struct route_map_rule_cmd route_match_source_protocol_cmd = {
        "source-protocol", route_match_source_protocol,
        route_match_source_protocol_compile, route_match_source_protocol_free};
 
+/* `source-instance` */
+static route_map_result_t route_match_source_instance(void *rule,
+                                                     struct prefix *prefix,
+                                                     route_map_object_t type,
+                                                     void *object)
+{
+       uint8_t *instance = (uint8_t *)rule;
+       struct nh_rmap_obj *nh_data;
+
+       if (type != RMAP_ZEBRA)
+               return RMAP_NOMATCH;
+
+       nh_data = (struct nh_rmap_obj *)object;
+       if (!nh_data)
+               return RMAP_DENYMATCH;
+
+       return (nh_data->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH;
+}
+
+static void *route_match_source_instance_compile(const char *arg)
+{
+       uint8_t *instance;
+       int i;
+
+       i = atoi(arg);
+       instance = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
+
+       *instance = i;
+
+       return instance;
+}
+
+static void route_match_source_instance_free(void *rule)
+{
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static struct route_map_rule_cmd route_match_source_instance_cmd = {
+       "source-instance", route_match_source_instance,
+       route_match_source_instance_compile, route_match_source_instance_free};
+
 /* `set src A.B.C.D' */
 
 /* Set src. */
@@ -1252,7 +1320,7 @@ void zebra_route_map_write_delay_timer(struct vty *vty)
 }
 
 route_map_result_t zebra_route_map_check(int family, int rib_type,
-                                        struct prefix *p,
+                                        uint8_t instance, struct prefix *p,
                                         struct nexthop *nexthop,
                                         vrf_id_t vrf_id, route_tag_t tag)
 {
@@ -1263,6 +1331,7 @@ route_map_result_t zebra_route_map_check(int family, int rib_type,
        nh_obj.nexthop = nexthop;
        nh_obj.vrf_id = vrf_id;
        nh_obj.source_protocol = rib_type;
+       nh_obj.instance = instance;
        nh_obj.metric = 0;
        nh_obj.tag = tag;
 
@@ -1296,9 +1365,10 @@ void zebra_del_import_table_route_map(afi_t afi, uint32_t table)
 }
 
 route_map_result_t
-zebra_import_table_route_map_check(int family, int re_type, struct prefix *p,
-                                  struct nexthop *nexthop, vrf_id_t vrf_id,
-                                  route_tag_t tag, const char *rmap_name)
+zebra_import_table_route_map_check(int family, int re_type, uint8_t instance,
+                                  struct prefix *p, struct nexthop *nexthop,
+                                  vrf_id_t vrf_id, route_tag_t tag,
+                                  const char *rmap_name)
 {
        struct route_map *rmap = NULL;
        route_map_result_t ret = RMAP_DENYMATCH;
@@ -1307,6 +1377,7 @@ zebra_import_table_route_map_check(int family, int re_type, struct prefix *p,
        nh_obj.nexthop = nexthop;
        nh_obj.vrf_id = vrf_id;
        nh_obj.source_protocol = re_type;
+       nh_obj.instance = instance;
        nh_obj.metric = 0;
        nh_obj.tag = tag;
 
@@ -1331,6 +1402,7 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
        nh_obj.nexthop = nexthop;
        nh_obj.vrf_id = nexthop->vrf_id;
        nh_obj.source_protocol = re->type;
+       nh_obj.instance = re->instance;
        nh_obj.metric = re->metric;
        nh_obj.tag = re->tag;
 
@@ -1471,6 +1543,8 @@ void zebra_route_map_init()
        route_map_install_match(&route_match_ipv6_address_prefix_len_cmd);
        route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd);
        route_map_install_match(&route_match_source_protocol_cmd);
+       route_map_install_match(&route_match_source_instance_cmd);
+
        /* */
        route_map_install_set(&route_set_src_cmd);
        /* */
@@ -1482,6 +1556,9 @@ void zebra_route_map_init()
        install_element(RMAP_NODE, &no_match_ip_address_prefix_len_cmd);
        install_element(RMAP_NODE, &match_source_protocol_cmd);
        install_element(RMAP_NODE, &no_match_source_protocol_cmd);
+       install_element(RMAP_NODE, &match_source_instance_cmd);
+       install_element(RMAP_NODE, &no_match_source_instance_cmd);
+
        /* */
        install_element(RMAP_NODE, &set_src_cmd);
        install_element(RMAP_NODE, &no_set_src_cmd);
index 14c7c58848020a9dbe48e5fc3012d4c826ef943b..20d425a2bcebb81a45844572b937bffb2b70f668 100644 (file)
@@ -34,14 +34,14 @@ extern void zebra_del_import_table_route_map(afi_t afi, uint32_t table);
 extern void zebra_route_map_write_delay_timer(struct vty *);
 
 extern route_map_result_t
-zebra_import_table_route_map_check(int family, int rib_type, struct prefix *p,
-                                  struct nexthop *nexthop, vrf_id_t vrf_id,
-                                  route_tag_t tag, const char *rmap_name);
-extern route_map_result_t zebra_route_map_check(int family, int rib_type,
-                                               struct prefix *p,
-                                               struct nexthop *nexthop,
-                                               vrf_id_t vrf_id,
-                                               route_tag_t tag);
+zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance,
+                                  struct prefix *p, struct nexthop *nexthop,
+                                  vrf_id_t vrf_id, route_tag_t tag,
+                                  const char *rmap_name);
+extern route_map_result_t
+zebra_route_map_check(int family, int rib_type, uint8_t instance,
+                     struct prefix *p, struct nexthop *nexthop,
+                     vrf_id_t vrf_id, route_tag_t tag);
 extern route_map_result_t
 zebra_nht_route_map_check(int family, int client_proto, struct prefix *p,
                          struct route_entry *, struct nexthop *nexthop);