From 8c3433e49033b2ca5b2464288471b58df7b3a805 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 18 Oct 2017 09:34:57 -0400 Subject: [PATCH 1/4] bgpd: Allow peer interface name to match Signed-off-by: Donald Sharp --- bgpd/bgp_routemap.c | 49 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 217916239c..75688e55c2 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -222,7 +222,12 @@ static void route_aspath_free(void *rule) aspath_free(aspath); } -/* 'match peer (A.B.C.D|X:X::X:X)' */ +struct bgp_match_peer_compiled { + char *interface; + union sockunion su; +}; + +/* 'match peer (A.B.C.D|X:X::X:X|WORD)' */ /* Compares the peer specified in the 'match peer' clause with the peer received in bgp_info->peer. If it is the same, or if the peer structure @@ -231,6 +236,7 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, route_map_object_t type, void *object) { + struct bgp_match_peer_compiled *pc; union sockunion *su; union sockunion su_def = { .sin = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY}}; @@ -239,13 +245,24 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, struct listnode *node, *nnode; if (type == RMAP_BGP) { - su = rule; + pc = rule; + su = &pc->su; peer = ((struct bgp_info *)object)->peer; if (!CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IMPORT) && !CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_EXPORT)) return RMAP_NOMATCH; + if (pc->interface) { + if (!peer->conf_if) + return RMAP_NOMATCH; + + if (strcmp(peer->conf_if, pc->interface) == 0) + return RMAP_MATCH; + + return RMAP_NOMATCH; + } + /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK, REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH @@ -283,23 +300,29 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, static void *route_match_peer_compile(const char *arg) { - union sockunion *su; + struct bgp_match_peer_compiled *pc; int ret; - su = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(union sockunion)); + pc = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, + sizeof(struct bgp_match_peer_compiled)); - ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", su); + ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", &pc->su); if (ret < 0) { - XFREE(MTYPE_ROUTE_MAP_COMPILED, su); - return NULL; + pc->interface = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + return pc; } - return su; + return pc; } /* Free route map's compiled `ip address' value. */ static void route_match_peer_free(void *rule) { + struct bgp_match_peer_compiled *pc = rule; + + if (pc->interface) + XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } @@ -3148,11 +3171,12 @@ DEFUN (no_match_evpn_vni, DEFUN (match_peer, match_peer_cmd, - "match peer ", + "match peer ", MATCH_STR "Match peer address\n" "IP address of peer\n" - "IPv6 address of peer\n") + "IPv6 address of peer\n" + "Interface name of peer\n") { int idx_ip = 2; return bgp_route_match_add(vty, "peer", argv[idx_ip]->arg, @@ -3172,13 +3196,14 @@ DEFUN (match_peer_local, DEFUN (no_match_peer, no_match_peer_cmd, - "no match peer []", + "no match peer []", NO_STR MATCH_STR "Match peer address\n" "Static or Redistributed routes\n" "IP address of peer\n" - "IPv6 address of peer\n") + "IPv6 address of peer\n" + "Interface name of peer\n") { int idx_peer = 3; From 7d4aea30071b3b56849614380f1b3c1ae0e47cd5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 18 Oct 2017 08:57:12 -0400 Subject: [PATCH 2/4] bgpd: Allow route-map `match peer...` to have auto-complete The match peer command doees not currently have an auto-complete ability. Let's add it in. Signed-off-by: Donald Sharp --- bgpd/bgp_vty.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 749c9d25d4..18190a4f95 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11334,6 +11334,7 @@ static void bgp_ac_neighbor(vector comps, struct cmd_token *token) static const struct cmd_variable_handler bgp_var_neighbor[] = { {.varname = "neighbor", .completions = bgp_ac_neighbor}, {.varname = "neighbors", .completions = bgp_ac_neighbor}, + {.varname = "peer", .completions = bgp_ac_neighbor}, {.completions = NULL}}; void bgp_vty_init(void) From 7aacfd1b4633e47ef71fff34cf90bbad1e16f8fb Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 18 Oct 2017 10:19:58 -0400 Subject: [PATCH 3/4] bgpd: Allow 'match peer' for all route-map types There are multiple places that we use route-maps in bgp There is no need to limit the route-map 'match peer ...' command to just import and export route-map types. I see need for using this in table-maps as well. Signed-off-by: Donald Sharp --- bgpd/bgp_routemap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 75688e55c2..f26498fb03 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -249,10 +249,6 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, su = &pc->su; peer = ((struct bgp_info *)object)->peer; - if (!CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IMPORT) - && !CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_EXPORT)) - return RMAP_NOMATCH; - if (pc->interface) { if (!peer->conf_if) return RMAP_NOMATCH; From b633926771e2410394ac150bb360794e3b0a77cc Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 25 Oct 2017 10:02:03 -0400 Subject: [PATCH 4/4] doc: Update route-map match section The 'match peer ...' command for bgp did not exist. Add this into the code. Signed-off-by: Donald Sharp --- doc/routemap.texi | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/routemap.texi b/doc/routemap.texi index 33062a7f61..69c07357e7 100644 --- a/doc/routemap.texi +++ b/doc/routemap.texi @@ -5,8 +5,8 @@ Route maps provide a means to both filter and/or apply actions to route, hence allowing policy to be applied to routes. @menu -* Route Map Command:: -* Route Map Match Command:: +* Route Map Command:: +* Route Map Match Command:: * Route Map Set Command:: * Route Map Call Command:: * Route Map Exit Action Command:: @@ -159,6 +159,22 @@ Matches the specified @var{local-preference}. Matches the specified @var{community_list} @end deffn +@deffn {Route-map Command} {match peer @var{ipv4_addr}} {} +This is a BGP specific match command. Matches the peer ip address +if the neighbor was specified in this manner. +@end deffn + +@deffn {Route-map Command} {match peer @var{ipv6_addr}} {} +This is a BGP specific match command. Matches the peer ipv6 +address if the neighbor was specified in this manner. +@end deffn + +@deffn {Route-map Command} {match peer @var{interface_name}} {} +This is a BGP specific match command. Matches the peer +interface name specified if the neighbor was specified +in this manner. +@end deffn + @node Route Map Set Command @section Route Map Set Command