]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: support for match ip address next-hop address command 5945/head
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 9 Mar 2020 15:13:19 +0000 (16:13 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 17 Mar 2020 20:55:42 +0000 (21:55 +0100)
this command is missing, compared with 'match ipv6 next-hop' command
available. Adding it by taking into account the backward compatible
effect when supposing that some people have configured acls with name
being an ipv4 address.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_routemap.c
doc/user/routemap.rst

index 52b5402737306dd8ed0b494625047ca8efca2771..029570df35684b8fe4f13f0054c0c156129475b7 100644 (file)
@@ -2830,6 +2830,57 @@ static const struct route_map_rule_cmd route_match_ipv6_next_hop_cmd = {
        route_match_ipv6_next_hop_free
 };
 
+/* `match ip next-hop IP_ADDRESS' */
+
+static enum route_map_cmd_result_t
+route_match_ipv4_next_hop(void *rule, const struct prefix *prefix,
+                         route_map_object_t type, void *object)
+{
+       struct in_addr *addr = rule;
+       struct bgp_path_info *path;
+
+       if (type == RMAP_BGP) {
+               path = object;
+
+               if (path->attr->nexthop.s_addr == addr->s_addr ||
+                   (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4 &&
+                    IPV4_ADDR_SAME(&path->attr->mp_nexthop_global_in, addr)))
+                       return RMAP_MATCH;
+
+               return RMAP_NOMATCH;
+       }
+
+       return RMAP_NOMATCH;
+}
+
+static void *route_match_ipv4_next_hop_compile(const char *arg)
+{
+       struct in_addr *address;
+       int ret;
+
+       address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in_addr));
+
+       ret = inet_pton(AF_INET, arg, address);
+       if (!ret) {
+               XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
+               return NULL;
+       }
+
+       return address;
+}
+
+static void route_match_ipv4_next_hop_free(void *rule)
+{
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static const struct route_map_rule_cmd route_match_ipv4_next_hop_cmd = {
+       "ip next-hop address",
+       route_match_ipv4_next_hop,
+       route_match_ipv4_next_hop_compile,
+       route_match_ipv4_next_hop_free
+};
+
 /* `match ipv6 address prefix-list PREFIX_LIST' */
 
 static enum route_map_cmd_result_t
@@ -5110,6 +5161,28 @@ DEFUN (no_match_ipv6_next_hop,
                                      RMAP_EVENT_MATCH_DELETED);
 }
 
+DEFPY (match_ipv4_next_hop,
+       match_ipv4_next_hop_cmd,
+       "[no$no] match ip next-hop address [A.B.C.D]",
+       NO_STR
+       MATCH_STR
+       IP_STR
+       "Match IP next-hop address of route\n"
+       "IP address\n"
+       "IP address of next-hop\n")
+{
+       int idx_ipv4 = 4;
+
+       if (no)
+               return bgp_route_match_delete(vty, "ip next-hop address", NULL,
+                                     RMAP_EVENT_MATCH_DELETED);
+
+       if (argv[idx_ipv4]->arg)
+               return bgp_route_match_add(vty, "ip next-hop address",
+                                          argv[idx_ipv4]->arg,
+                                          RMAP_EVENT_MATCH_ADDED);
+       return CMD_SUCCESS;
+}
 
 DEFUN (set_ipv6_nexthop_peer,
        set_ipv6_nexthop_peer_cmd,
@@ -5563,6 +5636,7 @@ void bgp_route_map_init(void)
 
        route_map_install_match(&route_match_ipv6_address_cmd);
        route_map_install_match(&route_match_ipv6_next_hop_cmd);
+       route_map_install_match(&route_match_ipv4_next_hop_cmd);
        route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
        route_map_install_match(&route_match_ipv6_next_hop_type_cmd);
        route_map_install_set(&route_set_ipv6_nexthop_global_cmd);
@@ -5572,6 +5646,7 @@ void bgp_route_map_init(void)
 
        install_element(RMAP_NODE, &match_ipv6_next_hop_cmd);
        install_element(RMAP_NODE, &no_match_ipv6_next_hop_cmd);
+       install_element(RMAP_NODE, &match_ipv4_next_hop_cmd);
        install_element(RMAP_NODE, &set_ipv6_nexthop_global_cmd);
        install_element(RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
        install_element(RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd);
index 472e2c53ffe355affb3d111e91540c0577f6d15c..f557cbe022b53449b49c85eac198f533c84c464c 100644 (file)
@@ -151,10 +151,15 @@ Route Map Match Command
 
    Matches the specified `prefix-len`. This is a Zebra specific command.
 
-.. index:: match ip next-hop IPV4_ADDR
-.. clicmd:: match ip next-hop IPV4_ADDR
+.. index:: match ip next-hop address IPV4_ADDR
+.. clicmd:: match ip next-hop address IPV4_ADDR
 
-   Matches the specified `ipv4_addr`.
+   This is a BGP specific match command. Matches the specified `ipv4_addr`.
+
+.. index:: match ipv6 next-hop IPV6_ADDR
+.. clicmd:: match ipv6 next-hop IPV6_ADDR
+
+   This is a BGP specific match command. Matches the specified `ipv6_addr`.
 
 .. index:: match as-path AS_PATH
 .. clicmd:: match as-path AS_PATH