From 2d818099f7893ac069587b7b504579a7c9c5cab7 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 21 Jun 2019 18:51:33 +0300 Subject: [PATCH] rmap: Add hooks into zebra,ospf,rip for `match ip next-hop type blackhole` Signed-off-by: Donatas Abraitis --- ospfd/ospf_routemap.c | 38 +++++++++++++++++++++ ripd/rip_routemap.c | 38 +++++++++++++++++++++ zebra/zebra_routemap.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index 30b2a50bb3..8f3add0d07 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -210,6 +210,40 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { route_match_ip_next_hop_prefix_list_compile, route_match_ip_next_hop_prefix_list_free}; +/* `match ip next-hop type ' */ + +static route_map_result_t +route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct external_info *ei = object; + + if (type == RMAP_OSPF && prefix->family == AF_INET) { + ei = (struct external_info *)object; + if (!ei) + return RMAP_DENYMATCH; + + if (ei->nexthop.s_addr == INADDR_ANY && !ei->ifindex) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ip_next_hop_type_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +static void route_match_ip_next_hop_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd = { + "ip next-hop type", route_match_ip_next_hop_type, + route_match_ip_next_hop_type_compile, + route_match_ip_next_hop_type_free}; + /* `match ip address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return zero. */ @@ -566,6 +600,9 @@ void ospf_route_map_init(void) route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); + route_map_match_ip_next_hop_type_hook(generic_match_add); + route_map_no_match_ip_next_hop_type_hook(generic_match_delete); + route_map_match_tag_hook(generic_match_add); route_map_no_match_tag_hook(generic_match_delete); @@ -579,6 +616,7 @@ void ospf_route_map_init(void) route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); route_map_install_match(&route_match_ip_address_cmd); route_map_install_match(&route_match_ip_address_prefix_list_cmd); + route_map_install_match(&route_match_ip_next_hop_type_cmd); route_map_install_match(&route_match_interface_cmd); route_map_install_match(&route_match_tag_cmd); diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c index 3216b8f89f..85d83c61dc 100644 --- a/ripd/rip_routemap.c +++ b/ripd/rip_routemap.c @@ -231,6 +231,40 @@ static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { route_match_ip_next_hop_prefix_list_compile, route_match_ip_next_hop_prefix_list_free}; +/* `match ip next-hop type ' */ + +static route_map_result_t +route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct rip_info *rinfo; + + if (type == RMAP_RIP && prefix->family == AF_INET) { + rinfo = (struct rip_info *)object; + if (!rinfo) + return RMAP_DENYMATCH; + + if (rinfo->nh.type == NEXTHOP_TYPE_BLACKHOLE) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ip_next_hop_type_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +static void route_match_ip_next_hop_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd = { + "ip next-hop type", route_match_ip_next_hop_type, + route_match_ip_next_hop_type_compile, + route_match_ip_next_hop_type_free}; + /* `match ip address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return @@ -537,6 +571,9 @@ void rip_route_map_init(void) route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); + route_map_match_ip_next_hop_type_hook(generic_match_add); + route_map_no_match_ip_next_hop_type_hook(generic_match_delete); + route_map_match_metric_hook(generic_match_add); route_map_no_match_metric_hook(generic_match_delete); @@ -556,6 +593,7 @@ void rip_route_map_init(void) route_map_install_match(&route_match_interface_cmd); route_map_install_match(&route_match_ip_next_hop_cmd); route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); + route_map_install_match(&route_match_ip_next_hop_type_cmd); route_map_install_match(&route_match_ip_address_cmd); route_map_install_match(&route_match_ip_address_prefix_list_cmd); route_map_install_match(&route_match_tag_cmd); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 5d1cbbe781..8adfeb7dfd 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1234,6 +1234,40 @@ static struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = { route_match_address_prefix_list_compile, route_match_address_prefix_list_free}; +/* `match ipv6 next-hop type ' */ + +static route_map_result_t +route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct nh_rmap_obj *nh_data; + + if (type == RMAP_ZEBRA && prefix->family == AF_INET6) { + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data) + return RMAP_DENYMATCH; + + if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ipv6_next_hop_type_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +static void route_match_ipv6_next_hop_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +struct route_map_rule_cmd route_match_ipv6_next_hop_type_cmd = { + "ipv6 next-hop type", route_match_ipv6_next_hop_type, + route_match_ipv6_next_hop_type_compile, + route_match_ipv6_next_hop_type_free}; + /* `match ip address prefix-len PREFIXLEN' */ static route_map_result_t @@ -1325,6 +1359,40 @@ static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = { route_match_address_prefix_len_free /* reuse */ }; +/* `match ip next-hop type ' */ + +static route_map_result_t +route_match_ip_next_hop_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) +{ + struct nh_rmap_obj *nh_data; + + if (type == RMAP_ZEBRA && prefix->family == AF_INET) { + nh_data = (struct nh_rmap_obj *)object; + if (!nh_data) + return RMAP_DENYMATCH; + + if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) + return RMAP_MATCH; + } + return RMAP_NOMATCH; +} + +static void *route_match_ip_next_hop_type_compile(const char *arg) +{ + return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); +} + +static void route_match_ip_next_hop_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd = { + "ip next-hop type", route_match_ip_next_hop_type, + route_match_ip_next_hop_type_compile, + route_match_ip_next_hop_type_free}; + /* `match source-protocol PROTOCOL' */ static route_map_result_t route_match_source_protocol(void *rule, @@ -1908,6 +1976,9 @@ void zebra_route_map_init(void) route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); + route_map_match_ip_next_hop_type_hook(generic_match_add); + route_map_no_match_ip_next_hop_type_hook(generic_match_delete); + route_map_match_tag_hook(generic_match_add); route_map_no_match_tag_hook(generic_match_delete); @@ -1917,6 +1988,9 @@ void zebra_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_ipv6_next_hop_type_hook(generic_match_add); + route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete); + route_map_install_match(&route_match_tag_cmd); route_map_install_match(&route_match_interface_cmd); route_map_install_match(&route_match_ip_next_hop_cmd); @@ -1928,6 +2002,8 @@ void zebra_route_map_init(void) route_map_install_match(&route_match_ip_address_prefix_len_cmd); 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_ip_next_hop_type_cmd); + route_map_install_match(&route_match_ipv6_next_hop_type_cmd); route_map_install_match(&route_match_source_protocol_cmd); route_map_install_match(&route_match_source_instance_cmd); -- 2.39.5