2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Route map function of bgpd.
|
2017-05-13 10:25:29 +02:00
|
|
|
* Copyright (C) 1998, 1999 Kunihiro Ishiguro
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "routemap.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "plist.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "log.h"
|
2019-05-09 22:08:40 +02:00
|
|
|
#include "frrlua.h"
|
2021-06-20 02:35:19 +02:00
|
|
|
#include "frrscript.h"
|
2022-10-31 21:23:51 +01:00
|
|
|
#ifdef HAVE_LIBPCRE2_POSIX
|
|
|
|
#ifndef _FRR_PCRE2_POSIX
|
|
|
|
#define _FRR_PCRE2_POSIX
|
|
|
|
#include <pcre2posix.h>
|
|
|
|
#endif /* _FRR_PCRE2_POSIX */
|
|
|
|
#elif defined(HAVE_LIBPCREPOSIX)
|
2009-01-12 22:06:12 +01:00
|
|
|
#include <pcreposix.h>
|
2002-12-13 21:15:29 +01:00
|
|
|
#else
|
2016-11-15 05:37:14 +01:00
|
|
|
#include <regex.h>
|
2022-10-31 21:23:51 +01:00
|
|
|
#endif /* HAVE_LIBPCRE2_POSIX */
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "buffer.h"
|
|
|
|
#include "sockunion.h"
|
2015-05-20 02:40:45 +02:00
|
|
|
#include "hash.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "queue.h"
|
2018-06-19 17:59:53 +02:00
|
|
|
#include "frrstr.h"
|
2020-04-17 15:35:15 +02:00
|
|
|
#include "network.h"
|
2020-10-30 08:45:43 +01:00
|
|
|
#include "lib/northbound_cli.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "bgpd/bgpd.h"
|
|
|
|
#include "bgpd/bgp_table.h"
|
|
|
|
#include "bgpd/bgp_attr.h"
|
|
|
|
#include "bgpd/bgp_aspath.h"
|
2015-05-20 02:40:45 +02:00
|
|
|
#include "bgpd/bgp_packet.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "bgpd/bgp_route.h"
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
#include "bgpd/bgp_zebra.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "bgpd/bgp_regex.h"
|
|
|
|
#include "bgpd/bgp_community.h"
|
2021-07-18 11:14:24 +02:00
|
|
|
#include "bgpd/bgp_community_alias.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "bgpd/bgp_clist.h"
|
|
|
|
#include "bgpd/bgp_filter.h"
|
|
|
|
#include "bgpd/bgp_mplsvpn.h"
|
|
|
|
#include "bgpd/bgp_ecommunity.h"
|
2016-11-15 11:00:39 +01:00
|
|
|
#include "bgpd/bgp_lcommunity.h"
|
2008-07-02 15:40:33 +02:00
|
|
|
#include "bgpd/bgp_vty.h"
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
#include "bgpd/bgp_debug.h"
|
2017-06-21 10:02:46 +02:00
|
|
|
#include "bgpd/bgp_evpn.h"
|
|
|
|
#include "bgpd/bgp_evpn_private.h"
|
2017-06-21 17:14:24 +02:00
|
|
|
#include "bgpd/bgp_evpn_vty.h"
|
2018-03-09 21:52:55 +01:00
|
|
|
#include "bgpd/bgp_mplsvpn.h"
|
2019-06-14 12:05:18 +02:00
|
|
|
#include "bgpd/bgp_pbr.h"
|
|
|
|
#include "bgpd/bgp_flowspec_util.h"
|
2019-06-19 23:29:34 +02:00
|
|
|
#include "bgpd/bgp_encap_types.h"
|
2020-03-24 21:57:44 +01:00
|
|
|
#include "bgpd/bgp_mpath.h"
|
2020-11-29 22:01:59 +01:00
|
|
|
#include "bgpd/bgp_script.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-04-01 21:05:26 +02:00
|
|
|
#ifdef ENABLE_BGP_VNC
|
2016-09-29 00:03:43 +02:00
|
|
|
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
|
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN
and Encap SAFIs. This code is currently used to support IETF NVO3 style
operation. In NVO3 terminology it provides the Network Virtualization
Authority (NVA) and the ability to import/export IP prefixes and MAC
addresses from Network Virtualization Edges (NVEs). The code supports
per-NVE tables.
The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2
(L2) forwarding information between NVAs and NVEs is referred to as the
Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For
general background on NVO3 and RFP concepts see [1]. For information on
Openflow see [2].
RFPs are integrated with BGP via the RF API contained in the new "rfapi"
BGP sub-directory. Currently, only a simple example RFP is included in
Quagga. Developers may use this example as a starting point to integrate
Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code
also supports the ability import/export of routing information between
VNC and customer edge routers (CEs) operating within a virtual
network. Import/export may take place between BGP views or to the
default zebera VRF.
BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN
information between NVAs. BGP based IP VPN support is defined in
RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659,
BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use
of both the Encapsulation Subsequent Address Family Identifier (SAFI)
and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation
Subsequent Address Family Identifier (SAFI) and the BGP Tunnel
Encapsulation Attribute, are supported. MAC address distribution does
not follow any standard BGB encoding, although it was inspired by the
early IETF EVPN concepts.
The feature is conditionally compiled and disabled by default.
Use the --enable-bgp-vnc configure option to enable.
The majority of this code was authored by G. Paul Ziemba
<paulz@labn.net>.
[1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req
[2] https://www.opennetworking.org/sdn-resources/technical-library
Now includes changes needed to merge with cmaster-next.
2016-05-07 20:18:56 +02:00
|
|
|
#endif
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2019-02-15 03:07:27 +01:00
|
|
|
#include "bgpd/bgp_routemap_clippy.c"
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Memo of route-map commands.
|
|
|
|
|
|
|
|
o Cisco route-map
|
|
|
|
|
|
|
|
match as-path : Done
|
|
|
|
community : Done
|
2015-05-20 02:40:47 +02:00
|
|
|
interface : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
ip address : Done
|
|
|
|
ip next-hop : Done
|
2005-02-02 17:43:17 +01:00
|
|
|
ip route-source : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
ip prefix-list : Done
|
|
|
|
ipv6 address : Done
|
|
|
|
ipv6 next-hop : Done
|
|
|
|
ipv6 route-source: (This will not be implemented by bgpd)
|
|
|
|
ipv6 prefix-list : Done
|
|
|
|
length : (This will not be implemented by bgpd)
|
|
|
|
metric : Done
|
|
|
|
route-type : (This will not be implemented by bgpd)
|
2015-05-20 02:46:33 +02:00
|
|
|
tag : Done
|
2015-05-20 02:40:40 +02:00
|
|
|
local-preference : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
set as-path prepend : Done
|
|
|
|
as-path tag : Not yet
|
|
|
|
automatic-tag : (This will not be implemented by bgpd)
|
|
|
|
community : Done
|
2016-11-15 11:00:39 +01:00
|
|
|
large-community : Done
|
|
|
|
large-comm-list : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
comm-list : Not yet
|
|
|
|
dampning : Not yet
|
|
|
|
default : (This will not be implemented by bgpd)
|
|
|
|
interface : (This will not be implemented by bgpd)
|
|
|
|
ip default : (This will not be implemented by bgpd)
|
|
|
|
ip next-hop : Done
|
|
|
|
ip precedence : (This will not be implemented by bgpd)
|
|
|
|
ip tos : (This will not be implemented by bgpd)
|
|
|
|
level : (This will not be implemented by bgpd)
|
|
|
|
local-preference : Done
|
|
|
|
metric : Done
|
|
|
|
metric-type : Not yet
|
|
|
|
origin : Done
|
2015-05-20 02:46:33 +02:00
|
|
|
tag : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
weight : Done
|
2019-04-29 15:26:01 +02:00
|
|
|
table : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2014-05-20 07:57:26 +02:00
|
|
|
o Local extensions
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
set ipv6 next-hop global: Done
|
2016-08-03 15:49:09 +02:00
|
|
|
set ipv6 next-hop prefer-global: Done
|
2002-12-13 21:15:29 +01:00
|
|
|
set ipv6 next-hop local : Done
|
2008-04-10 13:47:45 +02:00
|
|
|
set as-path exclude : Done
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-10-18 01:36:21 +02:00
|
|
|
*/
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2015-04-29 08:43:02 +02:00
|
|
|
/* generic value manipulation to be shared in multiple rules */
|
|
|
|
|
|
|
|
#define RMAP_VALUE_SET 0
|
|
|
|
#define RMAP_VALUE_ADD 1
|
|
|
|
#define RMAP_VALUE_SUB 2
|
|
|
|
|
2024-10-08 19:57:49 +02:00
|
|
|
#define RMAP_VALUE_TYPE_RTT 1
|
|
|
|
#define RMAP_VALUE_TYPE_IGP 2
|
|
|
|
|
2015-04-29 08:43:02 +02:00
|
|
|
struct rmap_value {
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t action;
|
|
|
|
uint8_t variable;
|
|
|
|
uint32_t value;
|
2015-04-29 08:43:02 +02:00
|
|
|
};
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static int route_value_match(struct rmap_value *rv, uint32_t value)
|
2015-04-29 08:43:02 +02:00
|
|
|
{
|
2015-04-29 08:43:04 +02:00
|
|
|
if (rv->variable == 0 && value == rv->value)
|
2015-04-29 08:43:02 +02:00
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint32_t route_value_adjust(struct rmap_value *rv, uint32_t current,
|
2024-10-08 19:57:49 +02:00
|
|
|
struct bgp_path_info *bpi)
|
2015-04-29 08:43:02 +02:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t value;
|
2024-10-08 19:57:49 +02:00
|
|
|
struct peer *peer = bpi->peer;
|
2015-04-29 08:43:04 +02:00
|
|
|
|
|
|
|
switch (rv->variable) {
|
2024-10-08 19:57:49 +02:00
|
|
|
case RMAP_VALUE_TYPE_RTT:
|
2015-04-29 08:43:04 +02:00
|
|
|
value = peer->rtt;
|
|
|
|
break;
|
2024-10-08 19:57:49 +02:00
|
|
|
case RMAP_VALUE_TYPE_IGP:
|
|
|
|
value = bpi->extra ? bpi->extra->igpmetric : 0;
|
|
|
|
break;
|
2015-04-29 08:43:04 +02:00
|
|
|
default:
|
|
|
|
value = rv->value;
|
|
|
|
break;
|
|
|
|
}
|
2015-04-29 08:43:02 +02:00
|
|
|
|
|
|
|
switch (rv->action) {
|
|
|
|
case RMAP_VALUE_ADD:
|
|
|
|
if (current > UINT32_MAX - value)
|
|
|
|
return UINT32_MAX;
|
|
|
|
return current + value;
|
|
|
|
case RMAP_VALUE_SUB:
|
|
|
|
if (current <= value)
|
|
|
|
return 0;
|
|
|
|
return current - value;
|
|
|
|
default:
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_value_compile(const char *arg)
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t action = RMAP_VALUE_SET, var = 0;
|
2015-04-29 08:43:04 +02:00
|
|
|
unsigned long larg = 0;
|
2015-04-29 08:43:02 +02:00
|
|
|
char *endptr = NULL;
|
|
|
|
struct rmap_value *rv;
|
|
|
|
|
|
|
|
if (arg[0] == '+') {
|
|
|
|
action = RMAP_VALUE_ADD;
|
|
|
|
arg++;
|
|
|
|
} else if (arg[0] == '-') {
|
|
|
|
action = RMAP_VALUE_SUB;
|
|
|
|
arg++;
|
|
|
|
}
|
|
|
|
|
2015-04-29 08:43:04 +02:00
|
|
|
if (all_digit(arg)) {
|
|
|
|
errno = 0;
|
|
|
|
larg = strtoul(arg, &endptr, 10);
|
|
|
|
if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
|
|
|
|
return NULL;
|
2024-10-08 19:57:49 +02:00
|
|
|
} else if (strmatch(arg, "rtt")) {
|
|
|
|
var = RMAP_VALUE_TYPE_RTT;
|
|
|
|
} else if (strmatch(arg, "igp")) {
|
|
|
|
var = RMAP_VALUE_TYPE_IGP;
|
2015-04-29 08:43:04 +02:00
|
|
|
} else {
|
2024-10-08 19:57:49 +02:00
|
|
|
return NULL;
|
2015-04-29 08:43:04 +02:00
|
|
|
}
|
2015-04-29 08:43:02 +02:00
|
|
|
|
|
|
|
rv = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
|
|
|
|
|
|
|
|
rv->action = action;
|
2015-04-29 08:43:04 +02:00
|
|
|
rv->variable = var;
|
2015-04-29 08:43:02 +02:00
|
|
|
rv->value = larg;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_value_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2014-05-20 08:04:49 +02:00
|
|
|
/* generic as path object to be shared in multiple rules */
|
|
|
|
|
|
|
|
static void *route_aspath_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct aspath *aspath;
|
|
|
|
|
bgpd: aspath list format binds on as-notation format
Each BGP prefix may have an as-path list attached. A forged
string is stored in the BGP attribute and shows the as-path
list output.
Before this commit, the as-path list output was expressed as
a list of AS values in plain format. Now, if a given BGP instance
uses a specific asnotation, then the output is changed:
new output:
router bgp 1.1 asnotation dot
!
address-family ipv4 unicast
network 10.200.0.0/24 route-map rmap
network 10.201.0.0/24 route-map rmap
redistribute connected route-map rmap
exit-address-family
exit
!
route-map rmap permit 1
set as-path prepend 1.1 5433.55 264564564
exit
ubuntu2004# do show bgp ipv4
BGP table version is 2, local router ID is 10.0.2.15, vrf id 0
Default local pref 100, local AS 1.1
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 4.4.4.4/32 0.0.0.0 0 32768 1.1 5433.55 4036.61268 ?
*> 10.0.2.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 ?
10.200.0.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 i
10.201.0.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 i
The changes include:
- the aspath structure has a new field: asnotation type
The ashash list will differentiate 2 aspaths using a different
asnotation.
- 3 new printf extensions display the as number in the wished
format: pASP, pASD, pASE for plain, dot, or dot+ format (extended).
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2022-11-14 15:56:40 +01:00
|
|
|
aspath = aspath_str2aspath(arg, bgp_get_asnotation(NULL));
|
2014-05-20 08:04:49 +02:00
|
|
|
if (!aspath)
|
|
|
|
return NULL;
|
|
|
|
return aspath;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_aspath_free(void *rule)
|
|
|
|
{
|
|
|
|
struct aspath *aspath = rule;
|
|
|
|
aspath_free(aspath);
|
|
|
|
}
|
|
|
|
|
2017-10-18 15:34:57 +02:00
|
|
|
struct bgp_match_peer_compiled {
|
|
|
|
char *interface;
|
|
|
|
union sockunion su;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 'match peer (A.B.C.D|X:X::X:X|WORD)' */
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
|
|
|
|
/* Compares the peer specified in the 'match peer' clause with the peer
|
2018-10-03 00:15:34 +02:00
|
|
|
received in bgp_path_info->peer. If it is the same, or if the peer structure
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
received is a peer_group containing it, returns RMAP_MATCH. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_peer(void *rule, const struct prefix *prefix, void *object)
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
{
|
2017-10-18 15:34:57 +02:00
|
|
|
struct bgp_match_peer_compiled *pc;
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
union sockunion *su;
|
2015-04-21 10:13:07 +02:00
|
|
|
union sockunion su_def = {
|
|
|
|
.sin = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY}};
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
struct peer_group *group;
|
|
|
|
struct peer *peer;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
pc = rule;
|
|
|
|
su = &pc->su;
|
|
|
|
peer = ((struct bgp_path_info *)object)->peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (pc->interface) {
|
2024-09-24 11:27:45 +02:00
|
|
|
if (!peer->conf_if && !peer->group)
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
2017-10-18 15:34:57 +02:00
|
|
|
|
2022-05-31 18:19:27 +02:00
|
|
|
if (peer->conf_if && strcmp(peer->conf_if, pc->interface) == 0)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
if (peer->group &&
|
|
|
|
strcmp(peer->group->name, pc->interface) == 0)
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2017-10-18 15:34:57 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
2017-10-18 15:34:57 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* If su='0.0.0.0' (command 'match peer local'), and it's a
|
|
|
|
NETWORK,
|
|
|
|
REDISTRIBUTE, AGGREGATE-ADDRESS or DEFAULT_GENERATED route
|
|
|
|
=> return RMAP_MATCH
|
|
|
|
*/
|
|
|
|
if (sockunion_same(su, &su_def)) {
|
|
|
|
int ret;
|
|
|
|
if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_NETWORK)
|
|
|
|
|| CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE)
|
|
|
|
|| CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_AGGREGATE)
|
|
|
|
|| CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
|
|
|
|
ret = RMAP_MATCH;
|
|
|
|
else
|
|
|
|
ret = RMAP_NOMATCH;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
2023-09-08 18:02:05 +02:00
|
|
|
if (sockunion_same(su, &peer->connection->su))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
} else {
|
|
|
|
group = peer->group;
|
|
|
|
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
|
2023-09-08 18:02:05 +02:00
|
|
|
if (sockunion_same(su, &peer->connection->su))
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
return RMAP_MATCH;
|
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_peer_compile(const char *arg)
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
{
|
2017-10-18 15:34:57 +02:00
|
|
|
struct bgp_match_peer_compiled *pc;
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
int ret;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-15 01:44:29 +01:00
|
|
|
pc = XCALLOC(MTYPE_ROUTE_MAP_COMPILED,
|
2017-10-18 15:34:57 +02:00
|
|
|
sizeof(struct bgp_match_peer_compiled));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-10-18 15:34:57 +02:00
|
|
|
ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", &pc->su);
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
if (ret < 0) {
|
2017-10-18 15:34:57 +02:00
|
|
|
pc->interface = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
return pc;
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-10-18 15:34:57 +02:00
|
|
|
return pc;
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip address' value. */
|
|
|
|
static void route_match_peer_free(void *rule)
|
|
|
|
{
|
2017-10-18 15:34:57 +02:00
|
|
|
struct bgp_match_peer_compiled *pc = rule;
|
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface);
|
2017-10-18 15:34:57 +02:00
|
|
|
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip address matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_peer_cmd = {
|
|
|
|
"peer",
|
|
|
|
route_match_peer,
|
|
|
|
route_match_peer_compile,
|
|
|
|
route_match_peer_free
|
|
|
|
};
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
|
2020-11-30 23:01:03 +01:00
|
|
|
#ifdef HAVE_SCRIPTING
|
2017-11-07 15:14:32 +01:00
|
|
|
|
2019-08-11 21:23:35 +02:00
|
|
|
enum frrlua_rm_status {
|
2017-11-07 15:14:32 +01:00
|
|
|
/*
|
2020-11-29 22:01:59 +01:00
|
|
|
* Script function run failure. This will translate into a deny
|
2017-11-07 15:14:32 +01:00
|
|
|
*/
|
2019-08-11 21:23:35 +02:00
|
|
|
LUA_RM_FAILURE = 0,
|
2017-11-07 15:14:32 +01:00
|
|
|
/*
|
2019-08-11 21:23:35 +02:00
|
|
|
* No Match was found for the route map function
|
2017-11-07 15:14:32 +01:00
|
|
|
*/
|
2019-08-11 21:23:35 +02:00
|
|
|
LUA_RM_NOMATCH,
|
2017-11-07 15:14:32 +01:00
|
|
|
/*
|
2020-11-29 22:01:59 +01:00
|
|
|
* Match was found but no changes were made to the incoming data.
|
2017-11-07 15:14:32 +01:00
|
|
|
*/
|
2019-08-11 21:23:35 +02:00
|
|
|
LUA_RM_MATCH,
|
|
|
|
/*
|
2020-11-29 22:01:59 +01:00
|
|
|
* Match was found and data was modified, so figure out what changed
|
2019-08-11 21:23:35 +02:00
|
|
|
*/
|
|
|
|
LUA_RM_MATCH_AND_CHANGE,
|
|
|
|
};
|
|
|
|
|
2020-11-29 22:01:59 +01:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_script(void *rule, const struct prefix *prefix, void *object)
|
2019-08-11 21:23:35 +02:00
|
|
|
{
|
2020-11-29 22:01:59 +01:00
|
|
|
const char *scriptname = rule;
|
2021-07-08 19:42:56 +02:00
|
|
|
const char *routematch_function = "route_match";
|
2020-11-29 22:01:59 +01:00
|
|
|
struct bgp_path_info *path = (struct bgp_path_info *)object;
|
|
|
|
|
2021-07-04 17:12:52 +02:00
|
|
|
struct frrscript *fs = frrscript_new(scriptname);
|
2019-08-11 21:23:35 +02:00
|
|
|
|
2021-07-08 19:42:56 +02:00
|
|
|
if (frrscript_load(fs, routematch_function, NULL)) {
|
2021-07-04 17:12:52 +02:00
|
|
|
zlog_err(
|
2021-07-23 10:37:43 +02:00
|
|
|
"Issue loading script or function; defaulting to no match");
|
2020-11-29 22:01:59 +01:00
|
|
|
return RMAP_NOMATCH;
|
2019-08-11 21:23:35 +02:00
|
|
|
}
|
|
|
|
|
2021-06-30 17:15:42 +02:00
|
|
|
struct attr newattr = *path->attr;
|
|
|
|
|
2021-06-20 02:35:19 +02:00
|
|
|
int result = frrscript_call(
|
2021-07-17 15:14:27 +02:00
|
|
|
fs, routematch_function, ("prefix", prefix),
|
|
|
|
("attributes", &newattr), ("peer", path->peer),
|
2021-07-23 10:38:16 +02:00
|
|
|
("RM_FAILURE", LUA_RM_FAILURE), ("RM_NOMATCH", LUA_RM_NOMATCH),
|
|
|
|
("RM_MATCH", LUA_RM_MATCH),
|
|
|
|
("RM_MATCH_AND_CHANGE", LUA_RM_MATCH_AND_CHANGE));
|
2020-11-29 22:01:59 +01:00
|
|
|
|
|
|
|
if (result) {
|
|
|
|
zlog_err("Issue running script rule; defaulting to no match");
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
2019-08-11 21:23:35 +02:00
|
|
|
|
2021-07-18 00:25:54 +02:00
|
|
|
long long *action = frrscript_get_result(fs, routematch_function,
|
|
|
|
"action", lua_tointegerp);
|
2021-07-08 19:42:56 +02:00
|
|
|
|
2020-11-29 22:01:59 +01:00
|
|
|
int status = RMAP_NOMATCH;
|
2017-11-07 15:14:32 +01:00
|
|
|
|
2021-07-08 19:42:56 +02:00
|
|
|
switch (*action) {
|
2017-11-07 15:14:32 +01:00
|
|
|
case LUA_RM_FAILURE:
|
2020-11-29 22:01:59 +01:00
|
|
|
zlog_err(
|
|
|
|
"Executing route-map match script '%s' failed; defaulting to no match",
|
|
|
|
scriptname);
|
|
|
|
status = RMAP_NOMATCH;
|
2017-11-07 15:14:32 +01:00
|
|
|
break;
|
|
|
|
case LUA_RM_NOMATCH:
|
2020-11-29 22:01:59 +01:00
|
|
|
status = RMAP_NOMATCH;
|
2017-11-07 15:14:32 +01:00
|
|
|
break;
|
|
|
|
case LUA_RM_MATCH_AND_CHANGE:
|
2020-11-29 22:01:59 +01:00
|
|
|
status = RMAP_MATCH;
|
|
|
|
zlog_debug("Updating attribute based on script's values");
|
|
|
|
|
|
|
|
uint32_t locpref = 0;
|
|
|
|
|
2021-06-30 17:15:42 +02:00
|
|
|
path->attr->med = newattr.med;
|
2020-11-29 22:01:59 +01:00
|
|
|
|
2018-10-03 02:43:07 +02:00
|
|
|
if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
|
|
|
|
locpref = path->attr->local_pref;
|
2021-06-30 17:15:42 +02:00
|
|
|
if (locpref != newattr.local_pref) {
|
2020-11-29 22:01:59 +01:00
|
|
|
SET_FLAG(path->attr->flag,
|
|
|
|
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF));
|
2021-06-30 17:15:42 +02:00
|
|
|
path->attr->local_pref = newattr.local_pref;
|
2017-11-07 15:14:32 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case LUA_RM_MATCH:
|
|
|
|
status = RMAP_MATCH;
|
|
|
|
break;
|
|
|
|
}
|
2020-11-29 22:01:59 +01:00
|
|
|
|
2021-07-26 17:27:43 +02:00
|
|
|
XFREE(MTYPE_SCRIPT_RES, action);
|
2021-07-08 19:42:56 +02:00
|
|
|
|
2021-07-08 11:51:14 +02:00
|
|
|
frrscript_delete(fs);
|
2020-11-29 22:01:59 +01:00
|
|
|
|
2017-11-07 15:14:32 +01:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2020-11-29 22:01:59 +01:00
|
|
|
static void *route_match_script_compile(const char *arg)
|
2017-11-07 15:14:32 +01:00
|
|
|
{
|
2020-11-29 22:01:59 +01:00
|
|
|
char *scriptname;
|
|
|
|
|
|
|
|
scriptname = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
2017-11-07 15:14:32 +01:00
|
|
|
|
2020-11-29 22:01:59 +01:00
|
|
|
return scriptname;
|
2017-11-07 15:14:32 +01:00
|
|
|
}
|
|
|
|
|
2020-11-29 22:01:59 +01:00
|
|
|
static void route_match_script_free(void *rule)
|
2017-11-07 15:14:32 +01:00
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2020-11-29 22:01:59 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_script_cmd = {
|
|
|
|
"script",
|
|
|
|
route_match_script,
|
|
|
|
route_match_script_compile,
|
|
|
|
route_match_script_free
|
2017-11-07 15:14:32 +01:00
|
|
|
};
|
2020-11-30 23:01:03 +01:00
|
|
|
|
|
|
|
#endif /* HAVE_SCRIPTING */
|
2017-11-07 15:14:32 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match ip address IP_ACCESS_LIST' */
|
|
|
|
|
|
|
|
/* Match function should return 1 if match is success else return
|
|
|
|
zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *alist;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET) {
|
2002-12-13 21:15:29 +01:00
|
|
|
alist = access_list_lookup(AFI_IP, (char *)rule);
|
2023-02-13 15:22:36 +01:00
|
|
|
if (alist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:22:36 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return (access_list_apply(alist, prefix) == FILTER_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip address' match statement. `arg' should be
|
|
|
|
access-list name. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ip_address_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2023-02-12 18:33:49 +01:00
|
|
|
struct access_list *alist;
|
|
|
|
|
|
|
|
alist = access_list_lookup(AFI_IP, arg);
|
|
|
|
if (!alist)
|
|
|
|
zlog_warn(
|
|
|
|
"Access List specified %s does not exist yet, default will be NO_MATCH until it is created",
|
|
|
|
arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip address' value. */
|
|
|
|
static void route_match_ip_address_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip address matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_ip_address_cmd = {
|
|
|
|
"ip address",
|
|
|
|
route_match_ip_address,
|
|
|
|
route_match_ip_address_compile,
|
|
|
|
route_match_ip_address_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2023-02-12 18:33:49 +01:00
|
|
|
/* `match ip next-hop <IP_ADDRESS_ACCESS_LIST_NAME>' */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Match function return 1 if match is success else return zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *alist;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct prefix_ipv4 p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET) {
|
2018-10-03 00:34:03 +02:00
|
|
|
path = object;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
2018-10-03 00:34:03 +02:00
|
|
|
p.prefix = path->attr->nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = IPV4_MAX_BITLEN;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
alist = access_list_lookup(AFI_IP, (char *)rule);
|
2023-02-13 15:22:36 +01:00
|
|
|
if (alist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:22:36 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return (access_list_apply(alist, &p) == FILTER_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip next-hop' match statement. `arg' is
|
|
|
|
access-list name. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ip_next_hop_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip address' value. */
|
|
|
|
static void route_match_ip_next_hop_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip next-hop matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
|
|
|
|
"ip next-hop",
|
|
|
|
route_match_ip_next_hop,
|
|
|
|
route_match_ip_next_hop_compile,
|
|
|
|
route_match_ip_next_hop_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2005-02-02 17:43:17 +01:00
|
|
|
/* `match ip route-source ACCESS-LIST' */
|
|
|
|
|
|
|
|
/* Match function return 1 if match is success else return zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ip_route_source(void *rule, const struct prefix *pfx, void *object)
|
2005-02-02 17:43:17 +01:00
|
|
|
{
|
|
|
|
struct access_list *alist;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2005-02-02 17:43:17 +01:00
|
|
|
struct peer *peer;
|
|
|
|
struct prefix_ipv4 p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (pfx->family == AF_INET) {
|
2018-10-03 00:34:03 +02:00
|
|
|
path = object;
|
|
|
|
peer = path->peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-09-08 18:02:05 +02:00
|
|
|
if (!peer || sockunion_family(&peer->connection->su) != AF_INET)
|
2005-02-02 17:43:17 +01:00
|
|
|
return RMAP_NOMATCH;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-02-02 17:43:17 +01:00
|
|
|
p.family = AF_INET;
|
2023-09-08 18:02:05 +02:00
|
|
|
p.prefix = peer->connection->su.sin.sin_addr;
|
2005-02-02 17:43:17 +01:00
|
|
|
p.prefixlen = IPV4_MAX_BITLEN;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-02-02 17:43:17 +01:00
|
|
|
alist = access_list_lookup(AFI_IP, (char *)rule);
|
2023-02-13 15:22:36 +01:00
|
|
|
if (alist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:22:36 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return (access_list_apply(alist, &p) == FILTER_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2005-02-02 17:43:17 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip route-source' match statement. `arg' is
|
|
|
|
access-list name. */
|
|
|
|
static void *route_match_ip_route_source_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip address' value. */
|
|
|
|
static void route_match_ip_route_source_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip route-source matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_ip_route_source_cmd = {
|
|
|
|
"ip route-source",
|
|
|
|
route_match_ip_route_source,
|
|
|
|
route_match_ip_route_source_compile,
|
|
|
|
route_match_ip_route_source_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_prefix_list_flowspec(afi_t afi, struct prefix_list *plist,
|
|
|
|
const struct prefix *p)
|
2019-06-14 12:05:18 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct bgp_pbr_entry_main api;
|
|
|
|
|
|
|
|
memset(&api, 0, sizeof(api));
|
|
|
|
|
2019-10-14 18:02:22 +02:00
|
|
|
if (family2afi(p->u.prefix_flowspec.family) != afi)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
2019-06-14 12:05:18 +02:00
|
|
|
/* extract match from flowspec entries */
|
|
|
|
ret = bgp_flowspec_match_rules_fill(
|
|
|
|
(uint8_t *)p->u.prefix_flowspec.ptr,
|
2019-10-14 18:02:22 +02:00
|
|
|
p->u.prefix_flowspec.prefixlen, &api,
|
|
|
|
afi);
|
2019-06-14 12:05:18 +02:00
|
|
|
if (ret < 0)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
if (api.match_bitmask & PREFIX_DST_PRESENT ||
|
|
|
|
api.match_bitmask_iprule & PREFIX_DST_PRESENT) {
|
|
|
|
if (family2afi((&api.dst_prefix)->family) != afi)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
return prefix_list_apply(plist, &api.dst_prefix) == PREFIX_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH;
|
|
|
|
} else if (api.match_bitmask & PREFIX_SRC_PRESENT ||
|
|
|
|
api.match_bitmask_iprule & PREFIX_SRC_PRESENT) {
|
|
|
|
if (family2afi((&api.src_prefix)->family) != afi)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
return (prefix_list_apply(plist, &api.src_prefix) == PREFIX_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
|
|
|
}
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-03-10 00:59:09 +01:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_prefix_list_evpn(afi_t afi, struct prefix_list *plist,
|
|
|
|
const struct prefix *p)
|
|
|
|
{
|
|
|
|
/* Convert to match a general plist */
|
|
|
|
struct prefix new;
|
|
|
|
|
|
|
|
if (evpn_prefix2prefix(p, &new))
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
|
|
|
return (prefix_list_apply(plist, &new) == PREFIX_DENY ? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
|
|
|
}
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2019-06-14 12:05:18 +02:00
|
|
|
route_match_address_prefix_list(void *rule, afi_t afi,
|
2020-11-14 01:35:20 +01:00
|
|
|
const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
|
2019-06-14 12:05:18 +02:00
|
|
|
plist = prefix_list_lookup(afi, (char *)rule);
|
2023-02-13 15:26:30 +01:00
|
|
|
if (plist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
|
2024-07-31 12:20:59 +02:00
|
|
|
zlog_debug("%s: Prefix List %s (%s) specified does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule, afi2str(afi));
|
2019-06-14 12:05:18 +02:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:26:30 +01:00
|
|
|
}
|
2019-06-14 12:05:18 +02:00
|
|
|
|
|
|
|
if (prefix->family == AF_FLOWSPEC)
|
|
|
|
return route_match_prefix_list_flowspec(afi, plist,
|
|
|
|
prefix);
|
2021-03-10 00:59:09 +01:00
|
|
|
|
|
|
|
else if (prefix->family == AF_EVPN)
|
|
|
|
return route_match_prefix_list_evpn(afi, plist, prefix);
|
|
|
|
|
2019-06-14 12:05:18 +02:00
|
|
|
return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
|
|
|
}
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2019-06-14 12:05:18 +02:00
|
|
|
route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2019-06-14 12:05:18 +02:00
|
|
|
{
|
2020-11-14 01:35:20 +01:00
|
|
|
return route_match_address_prefix_list(rule, AFI_IP, prefix, object);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ip_address_prefix_list_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ip_address_prefix_list_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ip_address_prefix_list_cmd = {
|
|
|
|
"ip address prefix-list",
|
|
|
|
route_match_ip_address_prefix_list,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_match_ip_address_prefix_list_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_ip_address_prefix_list_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match ip next-hop prefix-list PREFIX_LIST' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2018-07-12 22:05:19 +02:00
|
|
|
route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct prefix_ipv4 p;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET) {
|
2018-10-03 00:34:03 +02:00
|
|
|
path = object;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
2018-10-03 00:34:03 +02:00
|
|
|
p.prefix = path->attr->nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = IPV4_MAX_BITLEN;
|
|
|
|
|
|
|
|
plist = prefix_list_lookup(AFI_IP, (char *)rule);
|
2023-02-13 15:26:30 +01:00
|
|
|
if (plist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:26:30 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:26:30 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return (prefix_list_apply(plist, &p) == PREFIX_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
|
|
|
}
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ip_next_hop_prefix_list_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ip_next_hop_prefix_list_cmd = {
|
|
|
|
"ip next-hop prefix-list",
|
|
|
|
route_match_ip_next_hop_prefix_list,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_match_ip_next_hop_prefix_list_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_ip_next_hop_prefix_list_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2021-11-24 15:28:31 +01:00
|
|
|
/* `match ipv6 next-hop prefix-list PREFIXLIST_NAME' */
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_ipv6_next_hop_prefix_list(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
struct prefix_ipv6 p;
|
|
|
|
|
|
|
|
if (prefix->family == AF_INET6) {
|
|
|
|
path = object;
|
|
|
|
p.family = AF_INET6;
|
|
|
|
p.prefix = path->attr->mp_nexthop_global;
|
|
|
|
p.prefixlen = IPV6_MAX_BITLEN;
|
|
|
|
|
|
|
|
plist = prefix_list_lookup(AFI_IP6, (char *)rule);
|
2023-02-13 15:26:30 +01:00
|
|
|
if (!plist) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:26:30 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
2021-11-24 15:28:31 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:26:30 +01:00
|
|
|
}
|
2021-11-24 15:28:31 +01:00
|
|
|
|
|
|
|
if (prefix_list_apply(plist, &p) == PREFIX_PERMIT)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
if (path->attr->mp_nexthop_len
|
|
|
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
|
|
|
p.prefix = path->attr->mp_nexthop_local;
|
|
|
|
if (prefix_list_apply(plist, &p) == PREFIX_PERMIT)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_ipv6_next_hop_prefix_list_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ipv6_next_hop_prefix_list_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ipv6_next_hop_prefix_list_cmd = {
|
|
|
|
"ipv6 next-hop prefix-list",
|
|
|
|
route_match_ipv6_next_hop_prefix_list,
|
|
|
|
route_match_ipv6_next_hop_prefix_list_compile,
|
|
|
|
route_match_ipv6_next_hop_prefix_list_free
|
|
|
|
};
|
|
|
|
|
2018-09-28 10:51:50 +02:00
|
|
|
/* `match ip next-hop type <blackhole>' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2018-09-28 10:51:50 +02:00
|
|
|
route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2018-09-28 10:51:50 +02:00
|
|
|
{
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-09-28 10:51:50 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET) {
|
2018-10-03 00:34:03 +02:00
|
|
|
path = (struct bgp_path_info *)object;
|
2019-10-16 16:25:19 +02:00
|
|
|
if (!path)
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
return RMAP_NOMATCH;
|
2018-09-28 10:51:50 +02:00
|
|
|
|
|
|
|
/* If nexthop interface's index can't be resolved and nexthop is
|
|
|
|
set to any address then mark it as type `blackhole`.
|
|
|
|
This logic works for matching kernel/static routes like:
|
|
|
|
`ip route add blackhole 10.0.0.1`. */
|
2018-10-03 00:34:03 +02:00
|
|
|
if (path->attr->nexthop.s_addr == INADDR_ANY
|
|
|
|
&& !path->attr->nh_ifindex)
|
2018-09-28 10:51:50 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ip_next_hop_type_cmd = {
|
|
|
|
"ip next-hop type",
|
|
|
|
route_match_ip_next_hop_type,
|
2018-09-28 10:51:50 +02:00
|
|
|
route_match_ip_next_hop_type_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_ip_next_hop_type_free
|
|
|
|
};
|
2018-09-28 10:51:50 +02:00
|
|
|
|
2023-05-10 22:37:47 +02:00
|
|
|
/* `match source-protocol` */
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_source_protocol(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
|
|
|
{
|
|
|
|
struct bgp_path_info *path = object;
|
|
|
|
int *protocol = rule;
|
|
|
|
|
|
|
|
if (!path)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
|
|
|
if (path->type == *protocol)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_source_protocol_compile(const char *arg)
|
|
|
|
{
|
|
|
|
int *protocol;
|
|
|
|
|
|
|
|
protocol = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*protocol));
|
|
|
|
*protocol = proto_name2num(arg);
|
|
|
|
|
|
|
|
return protocol;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_source_protocol_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const 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
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-02-02 17:43:17 +01:00
|
|
|
/* `match ip route-source prefix-list PREFIX_LIST' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ip_route_source_prefix_list(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
2005-02-02 17:43:17 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2005-02-02 17:43:17 +01:00
|
|
|
struct peer *peer;
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET) {
|
2018-10-03 00:34:03 +02:00
|
|
|
path = object;
|
|
|
|
peer = path->peer;
|
2005-02-02 17:43:17 +01:00
|
|
|
|
2023-09-08 18:02:05 +02:00
|
|
|
if (!peer || sockunion_family(&peer->connection->su) != AF_INET)
|
2005-02-02 17:43:17 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
|
|
|
p.family = AF_INET;
|
2023-09-08 18:02:05 +02:00
|
|
|
p.prefix = peer->connection->su.sin.sin_addr;
|
2005-02-02 17:43:17 +01:00
|
|
|
p.prefixlen = IPV4_MAX_BITLEN;
|
|
|
|
|
|
|
|
plist = prefix_list_lookup(AFI_IP, (char *)rule);
|
2023-02-13 15:26:30 +01:00
|
|
|
if (plist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:26:30 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
2005-02-02 17:43:17 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:26:30 +01:00
|
|
|
}
|
2005-02-02 17:43:17 +01:00
|
|
|
|
|
|
|
return (prefix_list_apply(plist, &p) == PREFIX_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
|
|
|
}
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_ip_route_source_prefix_list_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ip_route_source_prefix_list_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ip_route_source_prefix_list_cmd = {
|
|
|
|
"ip route-source prefix-list",
|
|
|
|
route_match_ip_route_source_prefix_list,
|
2005-02-02 17:43:17 +01:00
|
|
|
route_match_ip_route_source_prefix_list_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_ip_route_source_prefix_list_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2018-02-22 07:02:07 +01:00
|
|
|
/* `match evpn default-route' */
|
|
|
|
|
|
|
|
/* Match function should return 1 if match is success else 0 */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_evpn_default_route(void *rule, const struct prefix *p, void *object)
|
2018-02-22 07:02:07 +01:00
|
|
|
{
|
2020-11-14 01:35:20 +01:00
|
|
|
if (is_evpn_prefix_default(p))
|
2018-02-22 07:02:07 +01:00
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for default-route matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_evpn_default_route_cmd = {
|
|
|
|
"evpn default-route",
|
|
|
|
route_match_evpn_default_route,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
};
|
2018-02-22 07:02:07 +01:00
|
|
|
|
2017-06-21 10:02:46 +02:00
|
|
|
/* `match mac address MAC_ACCESS_LIST' */
|
|
|
|
|
|
|
|
/* Match function should return 1 if match is success else return
|
|
|
|
zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_mac_address(void *rule, const struct prefix *prefix, void *object)
|
2017-06-21 10:02:46 +02:00
|
|
|
{
|
|
|
|
struct access_list *alist;
|
2017-08-04 21:55:44 +02:00
|
|
|
struct prefix p;
|
2017-06-21 10:02:46 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
alist = access_list_lookup(AFI_L2VPN, (char *)rule);
|
2023-02-13 15:22:36 +01:00
|
|
|
if (alist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
2017-06-21 10:02:46 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:22:36 +01:00
|
|
|
}
|
|
|
|
if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Prefix %pFX is not a EVPN MAC IP ROUTE defaulting to NO_MATCH",
|
|
|
|
__func__, prefix);
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
2017-06-21 10:02:46 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
p.family = AF_ETHERNET;
|
|
|
|
p.prefixlen = ETH_ALEN * 8;
|
|
|
|
p.u.prefix_eth = prefix->u.prefix_evpn.macip_addr.mac;
|
2017-08-04 21:55:44 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
2017-06-21 10:02:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `mac address' match statement. `arg' should be
|
|
|
|
access-list name. */
|
|
|
|
static void *route_match_mac_address_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip address' value. */
|
|
|
|
static void route_match_mac_address_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for mac address matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_mac_address_cmd = {
|
|
|
|
"mac address",
|
|
|
|
route_match_mac_address,
|
|
|
|
route_match_mac_address_compile,
|
|
|
|
route_match_mac_address_free
|
|
|
|
};
|
2017-06-21 10:02:46 +02:00
|
|
|
|
2019-06-19 23:29:34 +02:00
|
|
|
/*
|
|
|
|
* Match function returns:
|
|
|
|
* ...RMAP_MATCH if match is found.
|
|
|
|
* ...RMAP_NOMATCH if match is not found.
|
|
|
|
* ...RMAP_NOOP to ignore this match check.
|
|
|
|
*/
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_vni(void *rule, const struct prefix *prefix, void *object)
|
2017-06-21 11:00:24 +02:00
|
|
|
{
|
|
|
|
vni_t vni = 0;
|
2024-02-26 10:42:42 +01:00
|
|
|
unsigned int label_cnt;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path = NULL;
|
2019-06-19 23:29:34 +02:00
|
|
|
struct prefix_evpn *evp = (struct prefix_evpn *) prefix;
|
2017-06-21 11:00:24 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
vni = *((vni_t *)rule);
|
|
|
|
path = (struct bgp_path_info *)object;
|
2017-06-21 11:00:24 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/*
|
|
|
|
* This rmap filter is valid for vxlan tunnel type only.
|
|
|
|
* For any other tunnel type, return noop to ignore
|
|
|
|
* this check.
|
|
|
|
*/
|
|
|
|
if (path->attr->encap_tunneltype != BGP_ENCAP_TYPE_VXLAN)
|
|
|
|
return RMAP_NOOP;
|
2019-06-19 23:29:34 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/*
|
|
|
|
* Apply filter to type 1, 2, 5 routes only.
|
|
|
|
* Other route types do not have vni label.
|
|
|
|
*/
|
|
|
|
if (evp
|
|
|
|
&& (evp->prefix.route_type != BGP_EVPN_AD_ROUTE
|
|
|
|
&& evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE
|
|
|
|
&& evp->prefix.route_type != BGP_EVPN_IP_PREFIX_ROUTE))
|
|
|
|
return RMAP_NOOP;
|
2019-06-19 23:29:34 +02:00
|
|
|
|
2024-02-26 10:42:42 +01:00
|
|
|
for (label_cnt = 0; label_cnt < BGP_MAX_LABELS &&
|
2024-08-26 10:23:12 +02:00
|
|
|
label_cnt < BGP_PATH_INFO_NUM_LABELS(path);
|
2020-11-14 01:35:20 +01:00
|
|
|
label_cnt++) {
|
2024-02-26 18:23:11 +01:00
|
|
|
if (vni == label2vni(&path->extra->labels->label[label_cnt]))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2017-06-21 11:00:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `vni' match statement. */
|
|
|
|
static void *route_match_vni_compile(const char *arg)
|
|
|
|
{
|
|
|
|
vni_t *vni = NULL;
|
|
|
|
char *end = NULL;
|
|
|
|
|
|
|
|
vni = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(vni_t));
|
|
|
|
|
|
|
|
*vni = strtoul(arg, &end, 10);
|
2017-08-25 02:43:29 +02:00
|
|
|
if (*end != '\0') {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, vni);
|
2017-06-21 11:00:24 +02:00
|
|
|
return NULL;
|
2017-08-25 02:43:29 +02:00
|
|
|
}
|
2017-06-21 11:00:24 +02:00
|
|
|
|
|
|
|
return vni;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `vni' value. */
|
|
|
|
static void route_match_vni_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for vni matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_evpn_vni_cmd = {
|
|
|
|
"evpn vni",
|
|
|
|
route_match_vni,
|
|
|
|
route_match_vni_compile,
|
|
|
|
route_match_vni_free
|
|
|
|
};
|
2017-06-21 11:00:24 +02:00
|
|
|
|
2018-01-27 02:16:48 +01:00
|
|
|
/* `match evpn route-type' */
|
|
|
|
|
|
|
|
/* Match function should return 1 if match is success else return
|
|
|
|
zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_evpn_route_type(void *rule, const struct prefix *pfx, void *object)
|
2018-01-27 02:16:48 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t route_type = 0;
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
route_type = *((uint8_t *)rule);
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (route_type == pfx->u.prefix_evpn.route_type)
|
|
|
|
return RMAP_MATCH;
|
2018-01-27 02:16:48 +01:00
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `route-type' match statement. */
|
|
|
|
static void *route_match_evpn_route_type_compile(const char *arg)
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *route_type = NULL;
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2022-02-08 21:59:16 +01:00
|
|
|
if (strncmp(arg, "ea", 2) == 0)
|
|
|
|
*route_type = BGP_EVPN_AD_ROUTE;
|
|
|
|
else if (strncmp(arg, "ma", 2) == 0)
|
2018-01-27 02:16:48 +01:00
|
|
|
*route_type = BGP_EVPN_MAC_IP_ROUTE;
|
|
|
|
else if (strncmp(arg, "mu", 2) == 0)
|
|
|
|
*route_type = BGP_EVPN_IMET_ROUTE;
|
2022-02-11 04:35:14 +01:00
|
|
|
else if (strncmp(arg, "es", 2) == 0)
|
|
|
|
*route_type = BGP_EVPN_ES_ROUTE;
|
2018-01-27 02:16:48 +01:00
|
|
|
else
|
|
|
|
*route_type = BGP_EVPN_IP_PREFIX_ROUTE;
|
|
|
|
|
|
|
|
return route_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `route-type' value. */
|
|
|
|
static void route_match_evpn_route_type_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for evpn route-type matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
|
|
|
|
"evpn route-type",
|
|
|
|
route_match_evpn_route_type,
|
|
|
|
route_match_evpn_route_type_compile,
|
|
|
|
route_match_evpn_route_type_free
|
|
|
|
};
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2019-11-13 01:51:24 +01:00
|
|
|
/* `match rd' */
|
|
|
|
|
|
|
|
/* Match function should return 1 if match is success else return zero. */
|
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_rd(void *rule, const struct prefix *prefix, void *object)
|
2019-11-13 01:51:24 +01:00
|
|
|
{
|
|
|
|
struct prefix_rd *prd_rule = NULL;
|
2020-03-22 05:02:18 +01:00
|
|
|
const struct prefix_rd *prd_route = NULL;
|
2019-11-13 01:51:24 +01:00
|
|
|
struct bgp_path_info *path = NULL;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family != AF_EVPN)
|
|
|
|
return RMAP_NOMATCH;
|
2019-11-13 01:51:24 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
prd_rule = (struct prefix_rd *)rule;
|
|
|
|
path = (struct bgp_path_info *)object;
|
2019-11-13 01:51:24 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->net == NULL || path->net->pdest == NULL)
|
|
|
|
return RMAP_NOMATCH;
|
2019-11-13 01:51:24 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
prd_route = (struct prefix_rd *)bgp_dest_get_prefix(path->net->pdest);
|
|
|
|
if (memcmp(prd_route->val, prd_rule->val, ECOMMUNITY_SIZE) == 0)
|
|
|
|
return RMAP_MATCH;
|
2019-11-13 01:51:24 +01:00
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `rd' match statement. */
|
|
|
|
static void *route_match_rd_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct prefix_rd *prd;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
prd = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct prefix_rd));
|
|
|
|
|
|
|
|
ret = str2prefix_rd(arg, prd);
|
|
|
|
if (!ret) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, prd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return prd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `rd' value. */
|
|
|
|
static void route_match_rd_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for rd matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_evpn_rd_cmd = {
|
|
|
|
"evpn rd",
|
|
|
|
route_match_rd,
|
|
|
|
route_match_rd_compile,
|
|
|
|
route_match_rd_free
|
|
|
|
};
|
2019-11-13 01:51:24 +01:00
|
|
|
|
2021-05-21 11:04:00 +02:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_evpn_gateway_ip(void *rule, const struct prefix *prefix, void *object)
|
|
|
|
{
|
|
|
|
struct ipaddr *gw_ip = rule;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
struct prefix_evpn *evp;
|
2024-08-11 12:59:13 +02:00
|
|
|
struct bgp_route_evpn *bre = XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
|
|
|
|
sizeof(struct bgp_route_evpn));
|
2021-05-21 11:04:00 +02:00
|
|
|
|
|
|
|
if (prefix->family != AF_EVPN)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
evp = (struct prefix_evpn *)prefix;
|
|
|
|
if (evp->prefix.route_type != BGP_EVPN_IP_PREFIX_ROUTE)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
if ((is_evpn_prefix_ipaddr_v4(evp) && IPADDRSZ(gw_ip) != 4)
|
|
|
|
|| (is_evpn_prefix_ipaddr_v6(evp) && IPADDRSZ(gw_ip) != 16))
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
path = object;
|
|
|
|
|
|
|
|
/* Set gateway-ip value. */
|
2024-08-11 12:59:13 +02:00
|
|
|
bre->type = OVERLAY_INDEX_GATEWAY_IP;
|
|
|
|
memcpy(&bre->gw_ip, &gw_ip->ip.addr, IPADDRSZ(gw_ip));
|
|
|
|
bgp_attr_set_evpn_overlay(path->attr, bre);
|
2021-05-21 11:04:00 +02:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Route map `evpn gateway-ip' compile function.
|
|
|
|
* Given string is converted to struct ipaddr structure
|
|
|
|
*/
|
|
|
|
static void *route_set_evpn_gateway_ip_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct ipaddr *gw_ip = NULL;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
gw_ip = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct ipaddr));
|
|
|
|
|
|
|
|
ret = str2ipaddr(arg, gw_ip);
|
|
|
|
if (ret < 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, gw_ip);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return gw_ip;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `evpn gateway_ip' value. */
|
|
|
|
static void route_set_evpn_gateway_ip_free(void *rule)
|
|
|
|
{
|
|
|
|
struct ipaddr *gw_ip = rule;
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, gw_ip);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for set evpn gateway-ip ipv4. */
|
|
|
|
struct route_map_rule_cmd route_set_evpn_gateway_ip_ipv4_cmd = {
|
|
|
|
"evpn gateway-ip ipv4", route_set_evpn_gateway_ip,
|
|
|
|
route_set_evpn_gateway_ip_compile, route_set_evpn_gateway_ip_free};
|
|
|
|
|
|
|
|
/* Route map commands for set evpn gateway-ip ipv6. */
|
|
|
|
struct route_map_rule_cmd route_set_evpn_gateway_ip_ipv6_cmd = {
|
|
|
|
"evpn gateway-ip ipv6", route_set_evpn_gateway_ip,
|
|
|
|
route_set_evpn_gateway_ip_compile, route_set_evpn_gateway_ip_free};
|
|
|
|
|
2019-02-15 03:07:27 +01:00
|
|
|
/* Route map commands for VRF route leak with source vrf matching */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2019-02-22 16:50:14 +01:00
|
|
|
route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2019-02-15 03:07:27 +01:00
|
|
|
{
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
char *vrf_name;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
vrf_name = rule;
|
|
|
|
path = (struct bgp_path_info *)object;
|
2019-02-15 03:07:27 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)
|
|
|
|
return RMAP_NOMATCH;
|
2019-02-15 03:07:27 +01:00
|
|
|
|
2023-08-08 12:47:29 +02:00
|
|
|
if (path->extra == NULL || path->extra->vrfleak == NULL ||
|
|
|
|
path->extra->vrfleak->bgp_orig == NULL)
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
2019-02-15 03:07:27 +01:00
|
|
|
|
2023-08-08 12:47:29 +02:00
|
|
|
if (strncmp(vrf_name,
|
|
|
|
vrf_id_to_name(path->extra->vrfleak->bgp_orig->vrf_id),
|
|
|
|
VRF_NAMSIZ) == 0)
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2019-02-15 03:07:27 +01:00
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_vrl_source_vrf_compile(const char *arg)
|
|
|
|
{
|
|
|
|
uint8_t *vrf_name = NULL;
|
|
|
|
|
|
|
|
vrf_name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
|
|
|
|
return vrf_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `route-type' value. */
|
|
|
|
static void route_match_vrl_source_vrf_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_vrl_source_vrf_cmd = {
|
|
|
|
"source-vrf",
|
|
|
|
route_match_vrl_source_vrf,
|
2019-02-15 03:07:27 +01:00
|
|
|
route_match_vrl_source_vrf_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_vrl_source_vrf_free
|
|
|
|
};
|
2019-02-15 03:07:27 +01:00
|
|
|
|
2021-07-18 11:14:24 +02:00
|
|
|
/* `match alias` */
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_alias(void *rule, const struct prefix *prefix, void *object)
|
|
|
|
{
|
|
|
|
char *alias = rule;
|
|
|
|
struct bgp_path_info *path = object;
|
|
|
|
char **communities;
|
|
|
|
int num;
|
2021-08-11 11:21:46 +02:00
|
|
|
bool found;
|
2021-07-18 11:14:24 +02:00
|
|
|
|
2022-02-23 08:05:47 +01:00
|
|
|
if (bgp_attr_get_community(path->attr)) {
|
2021-08-11 11:21:46 +02:00
|
|
|
found = false;
|
2022-02-23 08:05:47 +01:00
|
|
|
frrstr_split(bgp_attr_get_community(path->attr)->str, " ",
|
|
|
|
&communities, &num);
|
2021-07-18 11:14:24 +02:00
|
|
|
for (int i = 0; i < num; i++) {
|
|
|
|
const char *com2alias =
|
|
|
|
bgp_community2alias(communities[i]);
|
2021-08-11 11:21:46 +02:00
|
|
|
if (!found && strcmp(alias, com2alias) == 0)
|
|
|
|
found = true;
|
|
|
|
XFREE(MTYPE_TMP, communities[i]);
|
2021-07-18 11:14:24 +02:00
|
|
|
}
|
2021-08-11 11:21:46 +02:00
|
|
|
XFREE(MTYPE_TMP, communities);
|
|
|
|
if (found)
|
|
|
|
return RMAP_MATCH;
|
2021-07-18 11:14:24 +02:00
|
|
|
}
|
|
|
|
|
2022-02-09 12:44:25 +01:00
|
|
|
if (bgp_attr_get_lcommunity(path->attr)) {
|
2021-08-11 11:21:46 +02:00
|
|
|
found = false;
|
2022-02-09 12:44:25 +01:00
|
|
|
frrstr_split(bgp_attr_get_lcommunity(path->attr)->str, " ",
|
|
|
|
&communities, &num);
|
2021-07-18 11:14:24 +02:00
|
|
|
for (int i = 0; i < num; i++) {
|
|
|
|
const char *com2alias =
|
|
|
|
bgp_community2alias(communities[i]);
|
2021-08-11 11:21:46 +02:00
|
|
|
if (!found && strcmp(alias, com2alias) == 0)
|
2021-08-17 11:19:43 +02:00
|
|
|
found = true;
|
2021-08-11 11:21:46 +02:00
|
|
|
XFREE(MTYPE_TMP, communities[i]);
|
2021-07-18 11:14:24 +02:00
|
|
|
}
|
2021-08-11 11:21:46 +02:00
|
|
|
XFREE(MTYPE_TMP, communities);
|
|
|
|
if (found)
|
|
|
|
return RMAP_MATCH;
|
2021-07-18 11:14:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_alias_compile(const char *arg)
|
|
|
|
{
|
|
|
|
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_alias_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_match_alias_cmd = {
|
|
|
|
"alias", route_match_alias, route_match_alias_compile,
|
|
|
|
route_match_alias_free};
|
|
|
|
|
2015-05-20 02:40:40 +02:00
|
|
|
/* `match local-preference LOCAL-PREF' */
|
|
|
|
|
|
|
|
/* Match function return 1 if match is success else return zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_local_pref(void *rule, const struct prefix *prefix, void *object)
|
2015-05-20 02:40:40 +02:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t *local_pref;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
local_pref = rule;
|
|
|
|
path = object;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->attr->local_pref == *local_pref)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
else
|
|
|
|
return RMAP_NOMATCH;
|
2015-05-20 02:40:40 +02:00
|
|
|
}
|
|
|
|
|
2019-11-13 01:51:24 +01:00
|
|
|
/*
|
|
|
|
* Route map `match local-preference' match statement.
|
|
|
|
* `arg' is local-pref value
|
|
|
|
*/
|
2015-05-20 02:40:40 +02:00
|
|
|
static void *route_match_local_pref_compile(const char *arg)
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t *local_pref;
|
2015-05-20 02:40:40 +02:00
|
|
|
char *endptr = NULL;
|
|
|
|
unsigned long tmpval;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
tmpval = strtoul(arg, &endptr, 10);
|
|
|
|
if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
|
|
|
|
return NULL;
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
local_pref = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
|
2015-05-20 02:40:40 +02:00
|
|
|
|
|
|
|
*local_pref = tmpval;
|
|
|
|
return local_pref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `match local-preference' value. */
|
|
|
|
static void route_match_local_pref_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for metric matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_local_pref_cmd = {
|
|
|
|
"local-preference",
|
|
|
|
route_match_local_pref,
|
|
|
|
route_match_local_pref_compile,
|
|
|
|
route_match_local_pref_free
|
|
|
|
};
|
2015-05-20 02:40:40 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match metric METRIC' */
|
|
|
|
|
|
|
|
/* Match function return 1 if match is success else return zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_metric(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-04-29 08:43:02 +02:00
|
|
|
struct rmap_value *rv;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
rv = rule;
|
|
|
|
path = object;
|
|
|
|
return route_value_match(rv, path->attr->med);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for metric matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_metric_cmd = {
|
|
|
|
"metric",
|
|
|
|
route_match_metric,
|
|
|
|
route_value_compile,
|
|
|
|
route_value_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match as-path ASPATH' */
|
|
|
|
|
|
|
|
/* Match function for as-path match. I assume given object is */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_aspath(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
struct as_list *as_list;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
as_list = as_list_lookup((char *)rule);
|
|
|
|
if (as_list == NULL)
|
|
|
|
return RMAP_NOMATCH;
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Perform match. */
|
|
|
|
return ((as_list_apply(as_list, path->attr->aspath) == AS_FILTER_DENY)
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for as-path match. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_aspath_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for as-path match. */
|
|
|
|
static void route_match_aspath_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for aspath matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_aspath_cmd = {
|
|
|
|
"as-path",
|
|
|
|
route_match_aspath,
|
|
|
|
route_match_aspath_compile,
|
|
|
|
route_match_aspath_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match community COMMUNIY' */
|
|
|
|
struct rmap_community {
|
|
|
|
char *name;
|
2019-01-09 02:23:11 +01:00
|
|
|
uint32_t name_hash;
|
2023-06-27 21:36:01 +02:00
|
|
|
bool exact;
|
|
|
|
bool any;
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Match function for community match. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_community(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct community_list *list;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
|
|
|
rcom = rule;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
|
|
|
|
COMMUNITY_LIST_MASTER);
|
|
|
|
if (!list)
|
|
|
|
return RMAP_NOMATCH;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (rcom->exact) {
|
2022-02-23 08:05:47 +01:00
|
|
|
if (community_list_exact_match(
|
|
|
|
bgp_attr_get_community(path->attr), list))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2023-06-27 21:36:01 +02:00
|
|
|
} else if (rcom->any) {
|
|
|
|
if (!bgp_attr_get_community(path->attr))
|
|
|
|
return RMAP_OKAY;
|
|
|
|
if (community_list_any_match(bgp_attr_get_community(path->attr),
|
|
|
|
list))
|
|
|
|
return RMAP_MATCH;
|
2020-11-14 01:35:20 +01:00
|
|
|
} else {
|
2022-02-23 08:05:47 +01:00
|
|
|
if (community_list_match(bgp_attr_get_community(path->attr),
|
|
|
|
list))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for community match. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_community_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct rmap_community *rcom;
|
|
|
|
int len;
|
|
|
|
char *p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p = strchr(arg, ' ');
|
|
|
|
if (p) {
|
|
|
|
len = p - arg;
|
|
|
|
rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
|
|
|
|
memcpy(rcom->name, arg, len);
|
2023-06-27 21:36:01 +02:00
|
|
|
p++;
|
|
|
|
if (*p == 'e')
|
|
|
|
rcom->exact = true;
|
|
|
|
else
|
|
|
|
rcom->any = true;
|
2002-12-13 21:15:29 +01:00
|
|
|
} else {
|
|
|
|
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
2023-06-27 21:36:01 +02:00
|
|
|
rcom->exact = false;
|
|
|
|
rcom->any = false;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2019-01-09 02:23:11 +01:00
|
|
|
|
|
|
|
rcom->name_hash = bgp_clist_hash_key(rcom->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
return rcom;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for community match. */
|
|
|
|
static void route_match_community_free(void *rule)
|
|
|
|
{
|
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
2016-10-18 01:36:21 +02:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom);
|
|
|
|
}
|
|
|
|
|
2019-08-27 12:45:54 +02:00
|
|
|
/*
|
|
|
|
* In routemap processing there is a need to add the
|
|
|
|
* name as a rule_key in the dependency table. Routemap
|
|
|
|
* lib is unaware of rule_key when exact-match clause
|
|
|
|
* is in use. routemap lib uses the compiled output to
|
|
|
|
* get the rule_key value.
|
|
|
|
*/
|
|
|
|
static void *route_match_get_community_key(void *rule)
|
|
|
|
{
|
|
|
|
struct rmap_community *rcom;
|
|
|
|
|
|
|
|
rcom = rule;
|
|
|
|
return rcom->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Route map commands for community matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_community_cmd = {
|
|
|
|
"community",
|
|
|
|
route_match_community,
|
|
|
|
route_match_community_compile,
|
|
|
|
route_match_community_free,
|
|
|
|
route_match_get_community_key
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
/* Match function for lcommunity match. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_lcommunity(void *rule, const struct prefix *prefix, void *object)
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
|
|
|
struct community_list *list;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
|
|
|
|
LARGE_COMMUNITY_LIST_MASTER);
|
|
|
|
if (!list)
|
|
|
|
return RMAP_NOMATCH;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (rcom->exact) {
|
2022-02-09 12:44:25 +01:00
|
|
|
if (lcommunity_list_exact_match(
|
|
|
|
bgp_attr_get_lcommunity(path->attr), list))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2023-06-27 21:36:01 +02:00
|
|
|
} else if (rcom->any) {
|
|
|
|
if (!bgp_attr_get_lcommunity(path->attr))
|
|
|
|
return RMAP_OKAY;
|
|
|
|
if (lcommunity_list_any_match(bgp_attr_get_lcommunity(path->attr),
|
|
|
|
list))
|
|
|
|
return RMAP_MATCH;
|
2020-11-14 01:35:20 +01:00
|
|
|
} else {
|
2022-02-09 12:44:25 +01:00
|
|
|
if (lcommunity_list_match(bgp_attr_get_lcommunity(path->attr),
|
|
|
|
list))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for community match. */
|
|
|
|
static void *route_match_lcommunity_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_community *rcom;
|
|
|
|
int len;
|
|
|
|
char *p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
p = strchr(arg, ' ');
|
|
|
|
if (p) {
|
|
|
|
len = p - arg;
|
|
|
|
rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
|
|
|
|
memcpy(rcom->name, arg, len);
|
2023-06-27 21:36:01 +02:00
|
|
|
p++;
|
|
|
|
if (*p == 'e')
|
|
|
|
rcom->exact = true;
|
|
|
|
else
|
|
|
|
rcom->any = true;
|
2016-11-15 11:00:39 +01:00
|
|
|
} else {
|
|
|
|
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
2023-06-27 21:36:01 +02:00
|
|
|
rcom->exact = false;
|
|
|
|
rcom->any = false;
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
2019-01-09 02:23:11 +01:00
|
|
|
|
|
|
|
rcom->name_hash = bgp_clist_hash_key(rcom->name);
|
2016-11-15 11:00:39 +01:00
|
|
|
return rcom;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for community match. */
|
|
|
|
static void route_match_lcommunity_free(void *rule)
|
|
|
|
{
|
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom->name);
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for community matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_lcommunity_cmd = {
|
|
|
|
"large-community",
|
|
|
|
route_match_lcommunity,
|
|
|
|
route_match_lcommunity_compile,
|
|
|
|
route_match_lcommunity_free,
|
|
|
|
route_match_get_community_key
|
|
|
|
};
|
2016-11-15 11:00:39 +01:00
|
|
|
|
|
|
|
|
2003-04-19 17:49:49 +02:00
|
|
|
/* Match function for extcommunity match. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ecommunity(void *rule, const struct prefix *prefix, void *object)
|
2003-04-19 17:49:49 +02:00
|
|
|
{
|
|
|
|
struct community_list *list;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
2003-04-19 17:49:49 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
|
|
|
|
EXTCOMMUNITY_LIST_MASTER);
|
|
|
|
if (!list)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
2022-02-04 14:56:20 +01:00
|
|
|
if (ecommunity_list_match(bgp_attr_get_ecommunity(path->attr), list))
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2003-04-19 17:49:49 +02:00
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for extcommunity match. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ecommunity_compile(const char *arg)
|
2003-04-19 17:49:49 +02:00
|
|
|
{
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom;
|
|
|
|
|
|
|
|
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
|
|
|
|
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
2019-01-09 02:23:11 +01:00
|
|
|
rcom->name_hash = bgp_clist_hash_key(rcom->name);
|
2018-12-26 19:01:06 +01:00
|
|
|
|
|
|
|
return rcom;
|
2003-04-19 17:49:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for extcommunity match. */
|
|
|
|
static void route_match_ecommunity_free(void *rule)
|
|
|
|
{
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom->name);
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom);
|
2003-04-19 17:49:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for community matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_ecommunity_cmd = {
|
|
|
|
"extcommunity",
|
|
|
|
route_match_ecommunity,
|
|
|
|
route_match_ecommunity_compile,
|
|
|
|
route_match_ecommunity_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
|
|
|
|
and `address-family vpnv4'. */
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match origin' */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_origin(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *origin;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
origin = rule;
|
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->attr->origin == *origin)
|
|
|
|
return RMAP_MATCH;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_origin_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *origin;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
origin = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (strcmp(arg, "igp") == 0)
|
|
|
|
*origin = 0;
|
|
|
|
else if (strcmp(arg, "egp") == 0)
|
|
|
|
*origin = 1;
|
|
|
|
else
|
|
|
|
*origin = 2;
|
|
|
|
|
|
|
|
return origin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip address' value. */
|
|
|
|
static void route_match_origin_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for origin matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_origin_cmd = {
|
|
|
|
"origin",
|
|
|
|
route_match_origin,
|
|
|
|
route_match_origin_compile,
|
|
|
|
route_match_origin_free
|
|
|
|
};
|
2011-11-22 17:15:10 +01:00
|
|
|
|
|
|
|
/* match probability { */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_probability(void *rule, const struct prefix *prefix, void *object)
|
2011-11-22 17:15:10 +01:00
|
|
|
{
|
2020-04-17 15:35:15 +02:00
|
|
|
long r = frr_weak_random();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-04-19 14:40:02 +02:00
|
|
|
switch (*(long *)rule) {
|
2011-11-22 17:15:10 +01:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case RAND_MAX:
|
|
|
|
return RMAP_MATCH;
|
|
|
|
default:
|
2016-06-05 01:12:18 +02:00
|
|
|
if (r < *(long *)rule) {
|
2011-11-22 17:15:10 +01:00
|
|
|
return RMAP_MATCH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_probability_compile(const char *arg)
|
|
|
|
{
|
2015-04-19 14:40:02 +02:00
|
|
|
long *lobule;
|
2011-11-22 17:15:10 +01:00
|
|
|
unsigned perc;
|
|
|
|
|
|
|
|
perc = atoi(arg);
|
2015-04-19 14:40:02 +02:00
|
|
|
lobule = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(long));
|
2011-11-22 17:15:10 +01:00
|
|
|
|
|
|
|
switch (perc) {
|
|
|
|
case 0:
|
|
|
|
*lobule = 0;
|
|
|
|
break;
|
|
|
|
case 100:
|
|
|
|
*lobule = RAND_MAX;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*lobule = RAND_MAX / 100 * perc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return lobule;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_probability_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_probability_cmd = {
|
|
|
|
"probability",
|
|
|
|
route_match_probability,
|
|
|
|
route_match_probability_compile,
|
|
|
|
route_match_probability_free
|
|
|
|
};
|
2011-11-22 17:15:10 +01:00
|
|
|
|
2015-05-20 02:40:47 +02:00
|
|
|
/* `match interface IFNAME' */
|
|
|
|
/* Match function should return 1 if match is success else return
|
|
|
|
zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_interface(void *rule, const struct prefix *prefix, void *object)
|
2015-05-20 02:40:47 +02:00
|
|
|
{
|
|
|
|
struct interface *ifp;
|
2018-10-03 02:43:07 +02:00
|
|
|
struct bgp_path_info *path;
|
2015-05-20 02:40:47 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2015-05-20 02:40:47 +02:00
|
|
|
|
2021-10-14 20:06:38 +02:00
|
|
|
if (!path || !path->peer || !path->peer->bgp)
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_NOMATCH;
|
2015-05-20 02:40:47 +02:00
|
|
|
|
2021-10-14 20:06:38 +02:00
|
|
|
ifp = if_lookup_by_name((char *)rule, path->peer->bgp->vrf_id);
|
2015-05-20 02:40:47 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (ifp == NULL || ifp->ifindex != path->attr->nh_ifindex)
|
|
|
|
return RMAP_NOMATCH;
|
2015-05-20 02:40:47 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_MATCH;
|
2015-05-20 02:40:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `interface' match statement. `arg' should be
|
|
|
|
interface name. */
|
|
|
|
static void *route_match_interface_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `interface' value. */
|
|
|
|
static void route_match_interface_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip address matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_interface_cmd = {
|
|
|
|
"interface",
|
|
|
|
route_match_interface,
|
|
|
|
route_match_interface_compile,
|
|
|
|
route_match_interface_free
|
|
|
|
};
|
2015-05-20 02:40:47 +02:00
|
|
|
|
2011-11-22 17:15:10 +01:00
|
|
|
/* } */
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set ip next-hop IP_ADDRESS' */
|
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* Match function return 1 if match is success else return zero. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_tag(void *rule, const struct prefix *prefix, void *object)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-10-01 20:42:34 +02:00
|
|
|
route_tag_t *tag;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
tag = rule;
|
|
|
|
path = object;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
return ((path->attr->tag == *tag) ? RMAP_MATCH : RMAP_NOMATCH);
|
2015-05-20 02:46:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Route map commands for tag matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_tag_cmd = {
|
|
|
|
"tag",
|
|
|
|
route_match_tag,
|
|
|
|
route_map_rule_tag_compile,
|
2016-10-01 20:42:34 +02:00
|
|
|
route_map_rule_tag_free,
|
2015-05-20 02:46:33 +02:00
|
|
|
};
|
|
|
|
|
2020-01-28 12:59:57 +01:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_srte_color(void *rule, const struct prefix *prefix, void *object)
|
2020-01-28 12:59:57 +01:00
|
|
|
{
|
|
|
|
uint32_t *srte_color = rule;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
|
|
|
|
path = object;
|
|
|
|
|
|
|
|
path->attr->srte_color = *srte_color;
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `sr-te color' compile function */
|
|
|
|
static void *route_set_srte_color_compile(const char *arg)
|
|
|
|
{
|
|
|
|
uint32_t *color;
|
|
|
|
|
|
|
|
color = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
|
|
|
|
*color = atoi(arg);
|
|
|
|
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `sr-te color' value. */
|
|
|
|
static void route_set_srte_color_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for sr-te color set. */
|
|
|
|
struct route_map_rule_cmd route_set_srte_color_cmd = {
|
|
|
|
"sr-te color", route_set_srte_color, route_set_srte_color_compile,
|
|
|
|
route_set_srte_color_free};
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2022-04-02 13:33:53 +02:00
|
|
|
/* Set nexthop to object. object must be pointer to struct attr. */
|
2003-08-12 07:32:27 +02:00
|
|
|
struct rmap_ip_nexthop_set {
|
|
|
|
struct in_addr *address;
|
|
|
|
int peer_address;
|
2015-05-20 03:03:49 +02:00
|
|
|
int unchanged;
|
2003-08-12 07:32:27 +02:00
|
|
|
};
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_ip_nexthop(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-08-12 07:32:27 +02:00
|
|
|
struct rmap_ip_nexthop_set *rins = rule;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2003-08-12 07:32:27 +02:00
|
|
|
struct peer *peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-20 02:43:47 +02:00
|
|
|
if (prefix->family == AF_INET6)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
2018-10-20 02:38:03 +02:00
|
|
|
path = object;
|
|
|
|
peer = path->peer;
|
|
|
|
|
|
|
|
if (rins->unchanged) {
|
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_NEXTHOP_UNCHANGED);
|
|
|
|
} else if (rins->peer_address) {
|
2024-09-02 14:32:00 +02:00
|
|
|
if ((CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN)) &&
|
|
|
|
peer->su_remote &&
|
|
|
|
sockunion_family(peer->su_remote) == AF_INET) {
|
2018-10-20 02:38:03 +02:00
|
|
|
path->attr->nexthop.s_addr =
|
|
|
|
sockunion2ip(peer->su_remote);
|
2018-10-03 00:34:03 +02:00
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
|
2018-10-20 02:38:03 +02:00
|
|
|
} else if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT)) {
|
|
|
|
/* The next hop value will be set as part of
|
|
|
|
* packet rewrite. Set the flags here to indicate
|
|
|
|
* that rewrite needs to be done.
|
|
|
|
* Also, clear the value.
|
|
|
|
*/
|
2018-10-03 00:34:03 +02:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
2018-10-20 02:38:03 +02:00
|
|
|
BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
|
2020-02-06 07:49:02 +01:00
|
|
|
path->attr->nexthop.s_addr = INADDR_ANY;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2018-10-20 02:38:03 +02:00
|
|
|
} else {
|
|
|
|
/* Set next hop value. */
|
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
|
|
|
|
path->attr->nexthop = *rins->address;
|
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_IPV4_NHOP_CHANGED);
|
|
|
|
/* case for MP-BGP : MPLS VPN */
|
|
|
|
path->attr->mp_nexthop_global_in = *rins->address;
|
|
|
|
path->attr->mp_nexthop_len = sizeof(*rins->address);
|
2003-08-12 07:32:27 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip nexthop' compile function. Given string is converted
|
|
|
|
to struct in_addr structure. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_ip_nexthop_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-08-12 07:32:27 +02:00
|
|
|
struct rmap_ip_nexthop_set *rins;
|
|
|
|
struct in_addr *address = NULL;
|
|
|
|
int peer_address = 0;
|
2015-05-20 03:03:49 +02:00
|
|
|
int unchanged = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
int ret;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-08-12 07:32:27 +02:00
|
|
|
if (strcmp(arg, "peer-address") == 0)
|
|
|
|
peer_address = 1;
|
2015-05-20 03:03:49 +02:00
|
|
|
else if (strcmp(arg, "unchanged") == 0)
|
|
|
|
unchanged = 1;
|
2003-08-12 07:32:27 +02:00
|
|
|
else {
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
|
|
|
|
sizeof(struct in_addr));
|
|
|
|
ret = inet_aton(arg, address);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-08-12 07:32:27 +02:00
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2003-08-12 07:32:27 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
rins = XCALLOC(MTYPE_ROUTE_MAP_COMPILED,
|
|
|
|
sizeof(struct rmap_ip_nexthop_set));
|
2003-08-12 07:32:27 +02:00
|
|
|
|
|
|
|
rins->address = address;
|
|
|
|
rins->peer_address = peer_address;
|
2015-05-20 03:03:49 +02:00
|
|
|
rins->unchanged = unchanged;
|
2003-08-12 07:32:27 +02:00
|
|
|
|
|
|
|
return rins;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip nexthop' value. */
|
|
|
|
static void route_set_ip_nexthop_free(void *rule)
|
|
|
|
{
|
2003-08-12 07:32:27 +02:00
|
|
|
struct rmap_ip_nexthop_set *rins = rule;
|
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rins->address);
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2003-08-12 07:32:27 +02:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rins);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip nexthop set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_ip_nexthop_cmd = {
|
|
|
|
"ip next-hop",
|
|
|
|
route_set_ip_nexthop,
|
|
|
|
route_set_ip_nexthop_compile,
|
|
|
|
route_set_ip_nexthop_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
bgpd: add resolution for l3vpn traffic over gre interfaces
When a route imported from l3vpn is analysed, the nexthop from default
VRF is looked up against a valid MPLS path. Generally, this is done on
backbones with a MPLS signalisation transport layer like LDP. Generally,
the BGP connection is multiple hops away. That scenario is already
working.
There is case where it is possible to run L3VPN over GRE interfaces, and
where there is no LSP path over that GRE interface: GRE is just here to
tunnel MPLS traffic. On that case, the nexthop given in the path does not
have MPLS path, but should be authorized to convey MPLS traffic provided
that the user permits it via a configuration command.
That commit introduces a new command that can be activated in route-map:
> set l3vpn next-hop encapsulation gre
That command authorizes the nexthop tracking engine to accept paths that
o have a GRE interface as output, independently of the presence of an LSP
path or not.
A configuration example is given below. When bgp incoming vpnv4 updates
are received, the nexthop of NLRI is 192.168.0.2. Based on nexthop
tracking service from zebra, BGP knows that the output interface to reach
192.168.0.2 is r1-gre0. Because that interface is not MPLS based, but is
a GRE tunnel, then the update will be using that nexthop to be installed.
interface r1-gre0
ip address 192.168.0.1/24
exit
router bgp 65500
bgp router-id 1.1.1.1
neighbor 192.168.0.2 remote-as 65500
!
address-family ipv4 unicast
no neighbor 192.168.0.2 activate
exit-address-family
!
address-family ipv4 vpn
neighbor 192.168.0.2 activate
neighbor 192.168.0.2 route-map rmap in
exit-address-family
exit
!
router bgp 65500 vrf vrf1
bgp router-id 1.1.1.1
no bgp network import-check
!
address-family ipv4 unicast
network 10.201.0.0/24
redistribute connected
label vpn export 101
rd vpn export 444:1
rt vpn both 52:100
export vpn
import vpn
exit-address-family
exit
!
route-map rmap permit 1
set l3vpn next-hop encapsulation gre
exit
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2021-09-20 11:50:52 +02:00
|
|
|
/* `set l3vpn next-hop encapsulation l3vpn gre' */
|
|
|
|
|
|
|
|
/* Set nexthop to object */
|
|
|
|
struct rmap_l3vpn_nexthop_encapsulation_set {
|
|
|
|
uint8_t protocol;
|
|
|
|
};
|
|
|
|
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_l3vpn_nexthop_encapsulation(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
|
|
|
{
|
|
|
|
struct rmap_l3vpn_nexthop_encapsulation_set *rins = rule;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
|
|
|
|
path = object;
|
|
|
|
|
|
|
|
if (rins->protocol != IPPROTO_GRE)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
SET_FLAG(path->attr->rmap_change_flags, BATTR_RMAP_L3VPN_ACCEPT_GRE);
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `l3vpn nexthop encapsulation' compile function. */
|
|
|
|
static void *route_set_l3vpn_nexthop_encapsulation_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_l3vpn_nexthop_encapsulation_set *rins;
|
|
|
|
|
|
|
|
rins = XCALLOC(MTYPE_ROUTE_MAP_COMPILED,
|
|
|
|
sizeof(struct rmap_l3vpn_nexthop_encapsulation_set));
|
|
|
|
|
|
|
|
/* XXX ALL GRE modes are accepted for now: gre or ip6gre */
|
|
|
|
rins->protocol = IPPROTO_GRE;
|
|
|
|
|
|
|
|
return rins;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip nexthop' value. */
|
|
|
|
static void route_set_l3vpn_nexthop_encapsulation_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for l3vpn next-hop encapsulation set. */
|
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_set_l3vpn_nexthop_encapsulation_cmd = {
|
|
|
|
"l3vpn next-hop encapsulation",
|
|
|
|
route_set_l3vpn_nexthop_encapsulation,
|
|
|
|
route_set_l3vpn_nexthop_encapsulation_compile,
|
|
|
|
route_set_l3vpn_nexthop_encapsulation_free};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set local-preference LOCAL_PREF' */
|
|
|
|
|
|
|
|
/* Set local preference. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_local_pref(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-04-29 08:43:02 +02:00
|
|
|
struct rmap_value *rv;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t locpref = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
rv = rule;
|
|
|
|
path = object;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set local preference value. */
|
2022-06-06 08:49:37 +02:00
|
|
|
if (path->attr->local_pref)
|
2020-11-14 01:35:20 +01:00
|
|
|
locpref = path->attr->local_pref;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
|
2024-10-08 19:57:49 +02:00
|
|
|
path->attr->local_pref = route_value_adjust(rv, locpref, path);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set local preference rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_local_pref_cmd = {
|
|
|
|
"local-preference",
|
|
|
|
route_set_local_pref,
|
|
|
|
route_value_compile,
|
2015-04-29 08:43:02 +02:00
|
|
|
route_value_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set weight WEIGHT' */
|
|
|
|
|
|
|
|
/* Set weight. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_weight(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-04-29 08:43:02 +02:00
|
|
|
struct rmap_value *rv;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
rv = rule;
|
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set weight value. */
|
2024-10-08 19:57:49 +02:00
|
|
|
path->attr->weight = route_value_adjust(rv, 0, path);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set local preference rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_weight_cmd = {
|
|
|
|
"weight",
|
|
|
|
route_set_weight,
|
|
|
|
route_value_compile,
|
|
|
|
route_value_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
/* `set distance DISTANCE */
|
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_distance(void *rule, const struct prefix *prefix, void *object)
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
{
|
|
|
|
struct bgp_path_info *path = object;
|
|
|
|
struct rmap_value *rv = rule;
|
|
|
|
|
|
|
|
path->attr->distance = rv->value;
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set distance rule structure */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_distance_cmd = {
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
"distance",
|
|
|
|
route_set_distance,
|
|
|
|
route_value_compile,
|
|
|
|
route_value_free,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set metric METRIC' */
|
|
|
|
|
|
|
|
/* Set metric to attribute. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_metric(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-04-29 08:43:02 +02:00
|
|
|
struct rmap_value *rv;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t med = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
rv = rule;
|
|
|
|
path = object;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
|
|
|
|
med = path->attr->med;
|
|
|
|
|
2024-10-08 19:57:49 +02:00
|
|
|
bgp_attr_set_med(path->attr, route_value_adjust(rv, med, path));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set metric rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_metric_cmd = {
|
|
|
|
"metric",
|
|
|
|
route_set_metric,
|
|
|
|
route_value_compile,
|
|
|
|
route_value_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2019-04-29 15:26:01 +02:00
|
|
|
/* `set table (1-4294967295)' */
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_table_id(void *rule, const struct prefix *prefix,
|
|
|
|
|
|
|
|
void *object)
|
2019-04-29 15:26:01 +02:00
|
|
|
{
|
|
|
|
struct rmap_value *rv;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
rv = rule;
|
|
|
|
path = object;
|
|
|
|
|
|
|
|
path->attr->rmap_table_id = rv->value;
|
2019-04-29 15:26:01 +02:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set table_id rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_table_id_cmd = {
|
|
|
|
"table",
|
|
|
|
route_set_table_id,
|
|
|
|
route_value_compile,
|
|
|
|
route_value_free
|
2019-04-29 15:26:01 +02:00
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set as-path prepend ASPATH' */
|
|
|
|
|
|
|
|
/* For AS path prepend mechanism. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_aspath_prepend(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct aspath *aspath;
|
|
|
|
struct aspath *new;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->attr->aspath->refcnt)
|
|
|
|
new = aspath_dup(path->attr->aspath);
|
|
|
|
else
|
|
|
|
new = path->attr->aspath;
|
2016-05-26 03:49:34 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if ((uintptr_t)rule > 10) {
|
|
|
|
aspath = rule;
|
|
|
|
aspath_prepend(aspath, new);
|
|
|
|
} else {
|
|
|
|
as_t as = aspath_leftmost(new);
|
2021-08-11 14:45:23 +02:00
|
|
|
if (as)
|
|
|
|
new = aspath_add_seq_n(new, as, (uintptr_t)rule);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path->attr->aspath = new;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
2016-05-26 03:49:34 +02:00
|
|
|
static void *route_set_aspath_prepend_compile(const char *arg)
|
|
|
|
{
|
|
|
|
unsigned int num;
|
|
|
|
|
2017-04-15 02:13:26 +02:00
|
|
|
if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num <= 10)
|
2016-05-26 03:49:34 +02:00
|
|
|
return (void *)(uintptr_t)num;
|
|
|
|
|
|
|
|
return route_aspath_compile(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_set_aspath_prepend_free(void *rule)
|
|
|
|
{
|
|
|
|
if ((uintptr_t)rule > 10)
|
|
|
|
route_aspath_free(rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-20 07:57:26 +02:00
|
|
|
/* Set as-path prepend rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_aspath_prepend_cmd = {
|
|
|
|
"as-path prepend",
|
|
|
|
route_set_aspath_prepend,
|
|
|
|
route_set_aspath_prepend_compile,
|
|
|
|
route_set_aspath_prepend_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2023-06-13 14:53:03 +02:00
|
|
|
static void *route_aspath_exclude_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct aspath_exclude *ase;
|
2024-04-23 11:16:24 +02:00
|
|
|
struct as_list *aux_aslist;
|
2023-06-13 14:53:03 +02:00
|
|
|
const char *str = arg;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
static const char asp_acl[] = "as-path-access-list";
|
2023-06-13 14:53:03 +02:00
|
|
|
|
|
|
|
ase = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct aspath_exclude));
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
if (strmatch(str, "all"))
|
2023-06-13 14:53:03 +02:00
|
|
|
ase->exclude_all = true;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
else if (!strncmp(str, asp_acl, strlen(asp_acl))) {
|
|
|
|
str += strlen(asp_acl);
|
|
|
|
while (*str == ' ')
|
|
|
|
str++;
|
|
|
|
ase->exclude_aspath_acl_name = XSTRDUP(MTYPE_TMP, str);
|
2024-04-23 11:16:24 +02:00
|
|
|
aux_aslist = as_list_lookup(str);
|
|
|
|
if (!aux_aslist)
|
|
|
|
/* new orphan filter */
|
|
|
|
as_exclude_set_orphan(ase);
|
|
|
|
else
|
|
|
|
as_list_list_add_head(&aux_aslist->exclude_rule, ase);
|
|
|
|
|
|
|
|
ase->exclude_aspath_acl = aux_aslist;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
} else
|
|
|
|
ase->aspath = aspath_str2aspath(str, bgp_get_asnotation(NULL));
|
2024-02-16 15:31:14 +01:00
|
|
|
|
2023-06-13 14:53:03 +02:00
|
|
|
return ase;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_aspath_exclude_free(void *rule)
|
|
|
|
{
|
|
|
|
struct aspath_exclude *ase = rule;
|
2024-04-23 11:16:24 +02:00
|
|
|
struct as_list *acl;
|
|
|
|
|
|
|
|
/* manage references to that rule*/
|
|
|
|
if (ase->exclude_aspath_acl) {
|
|
|
|
acl = ase->exclude_aspath_acl;
|
|
|
|
as_list_list_del(&acl->exclude_rule, ase);
|
bgpd: fix as-path exclude modify crash
Fix a crash when modifying a route-map with set as-path exclude without
as-path-access-list:
> router(config)# route-map routemaptest deny 1
> router(config-route-map)# set as-path exclude 33 34 35
> router(config-route-map)# set as-path exclude as-path-access-list test
> #0 raise (sig=<optimized out>) at ../sysdeps/unix/sysv/linux/raise.c:50
> #1 0x00007fb3959327de in core_handler (signo=11, siginfo=0x7ffd122da530, context=0x7ffd122da400) at lib/sigevent.c:258
> #2 <signal handler called>
> #3 0x000055ab2762a1bd in as_list_list_del (h=0x55ab27897680 <as_exclude_list_orphan>, item=0x55ab28204e20) at ./bgpd/bgp_aspath.h:77
> #4 0x000055ab2762d1a8 in as_exclude_remove_orphan (ase=0x55ab28204e20) at bgpd/bgp_aspath.c:1574
> #5 0x000055ab27550538 in route_aspath_exclude_free (rule=0x55ab28204e20) at bgpd/bgp_routemap.c:2366
> #6 0x00007fb39591f00c in route_map_rule_delete (list=0x55ab28203498, rule=0x55ab28204170) at lib/routemap.c:1357
> #7 0x00007fb39591f87c in route_map_add_set (index=0x55ab28203460, set_name=0x55ab276ad2aa "as-path exclude", set_arg=0x55ab281e4f70 "as-path-access-list test") at lib/routemap.c:1674
> #8 0x00007fb39591d3f3 in generic_set_add (index=0x55ab28203460, command=0x55ab276ad2aa "as-path exclude", arg=0x55ab281e4f70 "as-path-access-list test", errmsg=0x7ffd122db870 "",
> errmsg_len=8192) at lib/routemap.c:533
> #9 0x000055ab2755e78e in lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_modify (args=0x7ffd122db290) at bgpd/bgp_routemap_nb_config.c:2427
> #10 0x00007fb3958fe417 in nb_callback_modify (context=0x55ab28205aa0, nb_node=0x55ab27cb31e0, event=NB_EV_APPLY, dnode=0x55ab28202690, resource=0x55ab27c32148, errmsg=0x7ffd122db870 "",
> errmsg_len=8192) at lib/northbound.c:1538
> #11 0x00007fb3958ff0ab in nb_callback_configuration (context=0x55ab28205aa0, event=NB_EV_APPLY, change=0x55ab27c32110, errmsg=0x7ffd122db870 "", errmsg_len=8192) at lib/northbound.c:1888
> #12 0x00007fb3958ff5e4 in nb_transaction_process (event=NB_EV_APPLY, transaction=0x55ab28205aa0, errmsg=0x7ffd122db870 "", errmsg_len=8192) at lib/northbound.c:2016
> #13 0x00007fb3958fddba in nb_candidate_commit_apply (transaction=0x55ab28205aa0, save_transaction=true, transaction_id=0x0, errmsg=0x7ffd122db870 "", errmsg_len=8192)
> at lib/northbound.c:1356
> #14 0x00007fb3958fdef0 in nb_candidate_commit (context=..., candidate=0x55ab27c2c9a0, save_transaction=true, comment=0x0, transaction_id=0x0, errmsg=0x7ffd122db870 "", errmsg_len=8192)
> at lib/northbound.c:1389
> #15 0x00007fb3959045ba in nb_cli_classic_commit (vty=0x55ab281f6680) at lib/northbound_cli.c:57
> #16 0x00007fb395904b5a in nb_cli_apply_changes_internal (vty=0x55ab281f6680, xpath_base=0x7ffd122dfd10 "/frr-route-map:lib/route-map[name='routemaptest']/entry[sequence='1']",
> clear_pending=false) at lib/northbound_cli.c:184
> #17 0x00007fb395904ebf in nb_cli_apply_changes (vty=0x55ab281f6680, xpath_base_fmt=0x0) at lib/northbound_cli.c:240
> --Type <RET> for more, q to quit, c to continue without paging--
> #18 0x000055ab27557d2e in set_aspath_exclude_access_list_magic (self=0x55ab2775c300 <set_aspath_exclude_access_list_cmd>, vty=0x55ab281f6680, argc=5, argv=0x55ab28204c80,
> as_path_filter_name=0x55ab28202040 "test") at bgpd/bgp_routemap.c:6397
> #19 0x000055ab2754bdea in set_aspath_exclude_access_list (self=0x55ab2775c300 <set_aspath_exclude_access_list_cmd>, vty=0x55ab281f6680, argc=5, argv=0x55ab28204c80)
> at ./bgpd/bgp_routemap_clippy.c:856
> #20 0x00007fb39589435d in cmd_execute_command_real (vline=0x55ab281e61f0, vty=0x55ab281f6680, cmd=0x0, up_level=0) at lib/command.c:1003
> #21 0x00007fb3958944be in cmd_execute_command (vline=0x55ab281e61f0, vty=0x55ab281f6680, cmd=0x0, vtysh=0) at lib/command.c:1062
> #22 0x00007fb395894a0c in cmd_execute (vty=0x55ab281f6680, cmd=0x55ab28200f20 "set as-path exclude as-path-access-list test", matched=0x0, vtysh=0) at lib/command.c:1228
> #23 0x00007fb39595242c in vty_command (vty=0x55ab281f6680, buf=0x55ab28200f20 "set as-path exclude as-path-access-list test") at lib/vty.c:625
> #24 0x00007fb3959541c5 in vty_execute (vty=0x55ab281f6680) at lib/vty.c:1388
> #25 0x00007fb3959563db in vtysh_read (thread=0x7ffd122e2bb0) at lib/vty.c:2400
> #26 0x00007fb39594b785 in event_call (thread=0x7ffd122e2bb0) at lib/event.c:1996
> #27 0x00007fb3958d1365 in frr_run (master=0x55ab27b56d70) at lib/libfrr.c:1231
> #28 0x000055ab2747f1cc in main (argc=3, argv=0x7ffd122e2e08) at bgpd/bgp_main.c:555
Fixes: 094dcc3cda ("bgpd: fix "bgp as-pah access-list" with "set aspath exclude" set/unset issues")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
2024-09-10 14:06:38 +02:00
|
|
|
} else if (ase->exclude_aspath_acl_name) {
|
2024-04-23 11:16:24 +02:00
|
|
|
/* no ref to acl, this aspath exclude is orphan */
|
|
|
|
as_exclude_remove_orphan(ase);
|
|
|
|
}
|
2023-06-13 14:53:03 +02:00
|
|
|
|
|
|
|
aspath_free(ase->aspath);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
if (ase->exclude_aspath_acl_name)
|
|
|
|
XFREE(MTYPE_TMP, ase->exclude_aspath_acl_name);
|
2023-06-13 14:53:03 +02:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, ase);
|
|
|
|
}
|
2008-04-10 13:47:45 +02:00
|
|
|
|
|
|
|
/* For ASN exclude mechanism.
|
|
|
|
* Iterate over ASns requested and filter them from the given AS_PATH one by
|
|
|
|
* one.
|
|
|
|
* Make a deep copy of existing AS_PATH, but for the first ASn only.
|
|
|
|
*/
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_aspath_exclude(void *rule, const struct prefix *dummy, void *object)
|
2008-04-10 13:47:45 +02:00
|
|
|
{
|
2023-06-13 14:53:03 +02:00
|
|
|
struct aspath *new_path;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2023-06-13 14:53:03 +02:00
|
|
|
struct aspath_exclude *ase = rule;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2023-06-13 14:53:03 +02:00
|
|
|
|
|
|
|
if (path->peer->sort != BGP_PEER_EBGP) {
|
|
|
|
zlog_warn(
|
|
|
|
"`set as-path exclude` is supported only for EBGP peers");
|
|
|
|
return RMAP_NOOP;
|
|
|
|
}
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->attr->aspath->refcnt)
|
|
|
|
new_path = aspath_dup(path->attr->aspath);
|
|
|
|
else
|
|
|
|
new_path = path->attr->aspath;
|
2023-06-13 14:53:03 +02:00
|
|
|
|
|
|
|
if (ase->aspath)
|
|
|
|
path->attr->aspath =
|
|
|
|
aspath_filter_exclude(new_path, ase->aspath);
|
|
|
|
else if (ase->exclude_all)
|
|
|
|
path->attr->aspath = aspath_filter_exclude_all(new_path);
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2024-04-23 11:16:24 +02:00
|
|
|
else if (ase->exclude_aspath_acl)
|
|
|
|
path->attr->aspath =
|
|
|
|
aspath_filter_exclude_acl(new_path,
|
|
|
|
ase->exclude_aspath_acl);
|
2008-04-10 13:47:45 +02:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
/* Set ASn exclude rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_aspath_exclude_cmd = {
|
|
|
|
"as-path exclude",
|
|
|
|
route_set_aspath_exclude,
|
2023-06-13 14:53:03 +02:00
|
|
|
route_aspath_exclude_compile,
|
|
|
|
route_aspath_exclude_free,
|
2008-04-10 13:47:45 +02:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
/* `set as-path replace AS-PATH` */
|
|
|
|
static void *route_aspath_replace_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_aspath_replace_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_aspath_replace(void *rule, const struct prefix *dummy, void *object)
|
|
|
|
{
|
|
|
|
struct aspath *aspath_new;
|
|
|
|
const char *replace = rule;
|
|
|
|
struct bgp_path_info *path = object;
|
2023-06-19 16:22:55 +02:00
|
|
|
as_t replace_asn = 0;
|
|
|
|
as_t configured_asn;
|
|
|
|
char *buf;
|
|
|
|
char src_asn[ASN_STRING_MAX_SIZE];
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
char *acl_list_name = NULL;
|
|
|
|
uint32_t acl_list_name_len = 0;
|
|
|
|
char *buf_acl_name = NULL;
|
|
|
|
static const char asp_acl[] = "as-path-access-list";
|
|
|
|
struct as_list *aspath_acl = NULL;
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
|
|
|
|
if (path->peer->sort != BGP_PEER_EBGP) {
|
|
|
|
zlog_warn(
|
|
|
|
"`set as-path replace` is supported only for EBGP peers");
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
goto end_ko;
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
}
|
|
|
|
|
2023-06-19 16:22:55 +02:00
|
|
|
buf = strchr(replace, ' ');
|
|
|
|
if (!buf) {
|
|
|
|
configured_asn = path->peer->change_local_as
|
|
|
|
? path->peer->change_local_as
|
|
|
|
: path->peer->local_as;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
} else if (!strncmp(replace, asp_acl, strlen(asp_acl))) {
|
|
|
|
/* its as-path-acl-list command get the access list name */
|
|
|
|
while (*buf == ' ')
|
|
|
|
buf++;
|
|
|
|
buf_acl_name = buf;
|
|
|
|
buf = strchr(buf_acl_name, ' ');
|
|
|
|
if (buf)
|
|
|
|
acl_list_name_len = buf - buf_acl_name;
|
|
|
|
else
|
|
|
|
acl_list_name_len = strlen(buf_acl_name);
|
|
|
|
|
|
|
|
buf_acl_name[acl_list_name_len] = 0;
|
|
|
|
/* get the acl-list */
|
|
|
|
aspath_acl = as_list_lookup(buf_acl_name);
|
|
|
|
if (!aspath_acl) {
|
|
|
|
zlog_warn("`set as-path replace`, invalid as-path-access-list name: %s",
|
|
|
|
buf_acl_name);
|
|
|
|
goto end_ko;
|
|
|
|
}
|
|
|
|
acl_list_name = XSTRDUP(MTYPE_TMP, buf_acl_name);
|
|
|
|
buf_acl_name[acl_list_name_len] = ' ';
|
|
|
|
|
|
|
|
if (!buf) {
|
|
|
|
configured_asn = path->peer->change_local_as
|
|
|
|
? path->peer->change_local_as
|
|
|
|
: path->peer->local_as;
|
|
|
|
} else {
|
|
|
|
while (*buf == ' ')
|
|
|
|
buf++;
|
|
|
|
/* get the configured asn */
|
|
|
|
if (!asn_str2asn(buf, &configured_asn)) {
|
|
|
|
zlog_warn(
|
|
|
|
"`set as-path replace`, invalid configured AS %s",
|
|
|
|
buf);
|
|
|
|
goto end_ko;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
replace = buf;
|
|
|
|
|
2023-06-19 16:22:55 +02:00
|
|
|
} else {
|
|
|
|
memcpy(src_asn, replace, (size_t)(buf - replace));
|
|
|
|
src_asn[(size_t)(buf - replace)] = '\0';
|
|
|
|
replace = src_asn;
|
|
|
|
buf++;
|
|
|
|
if (!asn_str2asn(buf, &configured_asn)) {
|
|
|
|
zlog_warn(
|
|
|
|
"`set as-path replace`, invalid configured AS %s",
|
|
|
|
buf);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
goto end_ko;
|
2023-06-19 16:22:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
if (replace && !strmatch(replace, "any") &&
|
|
|
|
!asn_str2asn(replace, &replace_asn)) {
|
2023-06-19 16:22:55 +02:00
|
|
|
zlog_warn("`set as-path replace`, invalid AS %s", replace);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
goto end_ko;
|
2023-06-19 16:22:55 +02:00
|
|
|
}
|
|
|
|
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
if (path->attr->aspath->refcnt)
|
|
|
|
aspath_new = aspath_dup(path->attr->aspath);
|
|
|
|
else
|
|
|
|
aspath_new = path->attr->aspath;
|
|
|
|
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
if (aspath_acl) {
|
|
|
|
path->attr->aspath = aspath_replace_regex_asn(aspath_new,
|
|
|
|
aspath_acl,
|
|
|
|
configured_asn);
|
|
|
|
} else if (strmatch(replace, "any")) {
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
path->attr->aspath =
|
2023-06-19 16:22:55 +02:00
|
|
|
aspath_replace_all_asn(aspath_new, configured_asn);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
} else {
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
path->attr->aspath = aspath_replace_specific_asn(
|
2023-06-19 16:22:55 +02:00
|
|
|
aspath_new, replace_asn, configured_asn);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
}
|
2022-09-09 22:26:50 +02:00
|
|
|
aspath_free(aspath_new);
|
|
|
|
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
|
|
|
|
if (acl_list_name)
|
|
|
|
XFREE(MTYPE_TMP, acl_list_name);
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
return RMAP_OKAY;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
|
|
|
|
end_ko:
|
|
|
|
if (acl_list_name)
|
|
|
|
XFREE(MTYPE_TMP, acl_list_name);
|
|
|
|
return RMAP_NOOP;
|
|
|
|
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_set_aspath_replace_cmd = {
|
|
|
|
"as-path replace",
|
|
|
|
route_set_aspath_replace,
|
|
|
|
route_aspath_replace_compile,
|
|
|
|
route_aspath_replace_free,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set community COMMUNITY' */
|
|
|
|
struct rmap_com_set {
|
|
|
|
struct community *com;
|
|
|
|
int additive;
|
|
|
|
int none;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* For community set mechanism. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_community(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct rmap_com_set *rcs;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct attr *attr;
|
|
|
|
struct community *new = NULL;
|
|
|
|
struct community *old;
|
|
|
|
struct community *merge;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
rcs = rule;
|
|
|
|
path = object;
|
|
|
|
attr = path->attr;
|
2022-02-23 08:05:47 +01:00
|
|
|
old = bgp_attr_get_community(attr);
|
2020-11-14 01:35:20 +01:00
|
|
|
|
|
|
|
/* "none" case. */
|
|
|
|
if (rcs->none) {
|
2022-02-23 08:05:47 +01:00
|
|
|
bgp_attr_set_community(attr, NULL);
|
2020-11-14 01:35:20 +01:00
|
|
|
/* See the longer comment down below. */
|
|
|
|
if (old && old->refcnt == 0)
|
|
|
|
community_free(&old);
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* "additive" case. */
|
|
|
|
if (rcs->additive && old) {
|
|
|
|
merge = community_merge(community_dup(old), rcs->com);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
new = community_uniq_sort(merge);
|
|
|
|
community_free(&merge);
|
|
|
|
} else
|
|
|
|
new = community_dup(rcs->com);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* HACK: if the old community is not intern'd,
|
|
|
|
* we should free it here, or all reference to it may be
|
|
|
|
* lost.
|
|
|
|
* Really need to cleanup attribute caching sometime.
|
|
|
|
*/
|
|
|
|
if (old && old->refcnt == 0)
|
|
|
|
community_free(&old);
|
2017-08-30 10:27:15 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* will be interned by caller if required */
|
2022-02-23 08:05:47 +01:00
|
|
|
bgp_attr_set_community(attr, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for set community. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_community_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct rmap_com_set *rcs;
|
|
|
|
struct community *com = NULL;
|
|
|
|
char *sp;
|
|
|
|
int additive = 0;
|
|
|
|
int none = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (strcmp(arg, "none") == 0)
|
|
|
|
none = 1;
|
|
|
|
else {
|
|
|
|
sp = strstr(arg, "additive");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (sp && sp > arg) {
|
2017-08-30 10:31:45 +02:00
|
|
|
/* "additive" keyword is included. */
|
2002-12-13 21:15:29 +01:00
|
|
|
additive = 1;
|
|
|
|
*(sp - 1) = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
com = community_str2com(arg);
|
|
|
|
|
|
|
|
if (additive)
|
|
|
|
*(sp - 1) = ' ';
|
|
|
|
|
|
|
|
if (!com)
|
|
|
|
return NULL;
|
|
|
|
}
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_com_set));
|
2011-04-01 16:58:27 +02:00
|
|
|
rcs->com = com;
|
2002-12-13 21:15:29 +01:00
|
|
|
rcs->additive = additive;
|
|
|
|
rcs->none = none;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return rcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free function for set community. */
|
|
|
|
static void route_set_community_free(void *rule)
|
|
|
|
{
|
|
|
|
struct rmap_com_set *rcs = rule;
|
|
|
|
|
|
|
|
if (rcs->com)
|
2018-10-22 21:58:39 +02:00
|
|
|
community_free(&rcs->com);
|
2002-12-13 21:15:29 +01:00
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set community rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_community_cmd = {
|
|
|
|
"community",
|
|
|
|
route_set_community,
|
|
|
|
route_set_community_compile,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_set_community_free,
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
/* `set community COMMUNITY' */
|
|
|
|
struct rmap_lcom_set {
|
|
|
|
struct lcommunity *lcom;
|
|
|
|
int additive;
|
|
|
|
int none;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* For lcommunity set mechanism. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_lcommunity(void *rule, const struct prefix *prefix, void *object)
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
|
|
|
struct rmap_lcom_set *rcs;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2016-11-15 11:00:39 +01:00
|
|
|
struct attr *attr;
|
|
|
|
struct lcommunity *new = NULL;
|
|
|
|
struct lcommunity *old;
|
|
|
|
struct lcommunity *merge;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
rcs = rule;
|
|
|
|
path = object;
|
|
|
|
attr = path->attr;
|
2022-02-09 12:44:25 +01:00
|
|
|
old = bgp_attr_get_lcommunity(attr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* "none" case. */
|
|
|
|
if (rcs->none) {
|
2022-02-09 12:44:25 +01:00
|
|
|
bgp_attr_set_lcommunity(attr, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* See the longer comment down below. */
|
2017-08-30 09:37:19 +02:00
|
|
|
if (old && old->refcnt == 0)
|
|
|
|
lcommunity_free(&old);
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
2017-08-30 09:37:19 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (rcs->additive && old) {
|
|
|
|
merge = lcommunity_merge(lcommunity_dup(old), rcs->lcom);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
new = lcommunity_uniq_sort(merge);
|
|
|
|
lcommunity_free(&merge);
|
|
|
|
} else
|
|
|
|
new = lcommunity_dup(rcs->lcom);
|
|
|
|
|
|
|
|
/* HACK: if the old large-community is not intern'd,
|
|
|
|
* we should free it here, or all reference to it may be
|
|
|
|
* lost.
|
|
|
|
* Really need to cleanup attribute caching sometime.
|
|
|
|
*/
|
|
|
|
if (old && old->refcnt == 0)
|
|
|
|
lcommunity_free(&old);
|
|
|
|
|
|
|
|
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
|
2022-02-09 12:44:25 +01:00
|
|
|
bgp_attr_set_lcommunity(attr, new);
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
return RMAP_OKAY;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2016-11-15 11:00:39 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Compile function for set community. */
|
2016-11-15 11:00:39 +01:00
|
|
|
static void *route_set_lcommunity_compile(const char *arg)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2016-11-15 11:00:39 +01:00
|
|
|
struct rmap_lcom_set *rcs;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct lcommunity *lcom = NULL;
|
2016-11-15 11:00:39 +01:00
|
|
|
char *sp;
|
2002-12-13 21:15:29 +01:00
|
|
|
int additive = 0;
|
2016-11-15 11:00:39 +01:00
|
|
|
int none = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
if (strcmp(arg, "none") == 0)
|
2017-07-17 14:03:14 +02:00
|
|
|
none = 1;
|
|
|
|
else {
|
2016-11-15 11:00:39 +01:00
|
|
|
sp = strstr(arg, "additive");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
if (sp && sp > arg) {
|
2017-01-25 22:29:31 +01:00
|
|
|
/* "additive" keyworkd is included. */
|
|
|
|
additive = 1;
|
|
|
|
*(sp - 1) = '\0';
|
|
|
|
}
|
2016-11-15 11:00:39 +01:00
|
|
|
|
|
|
|
lcom = lcommunity_str2com(arg);
|
|
|
|
|
2017-01-25 22:29:31 +01:00
|
|
|
if (additive)
|
|
|
|
*(sp - 1) = ' ';
|
2016-11-15 11:00:39 +01:00
|
|
|
|
2017-01-25 22:29:31 +01:00
|
|
|
if (!lcom)
|
|
|
|
return NULL;
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_com_set));
|
|
|
|
rcs->lcom = lcom;
|
|
|
|
rcs->additive = additive;
|
|
|
|
rcs->none = none;
|
|
|
|
|
|
|
|
return rcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free function for set lcommunity. */
|
|
|
|
static void route_set_lcommunity_free(void *rule)
|
|
|
|
{
|
|
|
|
struct rmap_lcom_set *rcs = rule;
|
|
|
|
|
|
|
|
if (rcs->lcom) {
|
|
|
|
lcommunity_free(&rcs->lcom);
|
|
|
|
}
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set community rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_lcommunity_cmd = {
|
|
|
|
"large-community",
|
|
|
|
route_set_lcommunity,
|
|
|
|
route_set_lcommunity_compile,
|
2016-11-15 11:00:39 +01:00
|
|
|
route_set_lcommunity_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
|
|
|
|
|
|
|
|
/* For large community set mechanism. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_lcommunity_delete(void *rule, const struct prefix *pfx, void *object)
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
|
|
|
struct community_list *list;
|
|
|
|
struct lcommunity *merge;
|
|
|
|
struct lcommunity *new;
|
|
|
|
struct lcommunity *old;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (!rcom)
|
|
|
|
return RMAP_OKAY;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
|
|
|
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
|
|
|
|
LARGE_COMMUNITY_LIST_MASTER);
|
2022-02-09 12:44:25 +01:00
|
|
|
old = bgp_attr_get_lcommunity(path->attr);
|
2020-11-14 01:35:20 +01:00
|
|
|
|
|
|
|
if (list && old) {
|
|
|
|
merge = lcommunity_list_match_delete(lcommunity_dup(old), list);
|
|
|
|
new = lcommunity_uniq_sort(merge);
|
|
|
|
lcommunity_free(&merge);
|
|
|
|
|
|
|
|
/* HACK: if the old community is not intern'd,
|
|
|
|
* we should free it here, or all reference to it may be
|
|
|
|
* lost.
|
|
|
|
* Really need to cleanup attribute caching sometime.
|
|
|
|
*/
|
|
|
|
if (old->refcnt == 0)
|
|
|
|
lcommunity_free(&old);
|
|
|
|
|
|
|
|
if (new->size == 0) {
|
2022-02-09 12:44:25 +01:00
|
|
|
bgp_attr_set_lcommunity(path->attr, NULL);
|
2020-11-14 01:35:20 +01:00
|
|
|
lcommunity_free(&new);
|
|
|
|
} else {
|
2022-02-09 12:44:25 +01:00
|
|
|
bgp_attr_set_lcommunity(path->attr, new);
|
2017-01-25 22:29:31 +01:00
|
|
|
}
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-11-15 11:00:39 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for set lcommunity. */
|
|
|
|
static void *route_set_lcommunity_delete_compile(const char *arg)
|
|
|
|
{
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom;
|
2019-07-18 14:29:20 +02:00
|
|
|
char **splits;
|
|
|
|
int num;
|
2016-11-15 11:00:39 +01:00
|
|
|
|
2019-07-18 14:29:20 +02:00
|
|
|
frrstr_split(arg, " ", &splits, &num);
|
2018-12-26 19:01:06 +01:00
|
|
|
|
2019-07-18 14:29:20 +02:00
|
|
|
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
|
|
|
|
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, splits[0]);
|
2019-01-09 02:23:11 +01:00
|
|
|
rcom->name_hash = bgp_clist_hash_key(rcom->name);
|
2019-02-24 01:27:09 +01:00
|
|
|
|
2019-07-18 14:29:20 +02:00
|
|
|
for (int i = 0; i < num; i++)
|
|
|
|
XFREE(MTYPE_TMP, splits[i]);
|
|
|
|
XFREE(MTYPE_TMP, splits);
|
|
|
|
|
2018-12-26 19:01:06 +01:00
|
|
|
return rcom;
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free function for set lcommunity. */
|
|
|
|
static void route_set_lcommunity_delete_free(void *rule)
|
|
|
|
{
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom->name);
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set lcommunity rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_lcommunity_delete_cmd = {
|
|
|
|
"large-comm-list",
|
|
|
|
route_set_lcommunity_delete,
|
|
|
|
route_set_lcommunity_delete_compile,
|
|
|
|
route_set_lcommunity_delete_free,
|
2016-11-15 11:00:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-02-02 17:29:31 +01:00
|
|
|
/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* For community set mechanism. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_community_delete(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct community_list *list;
|
|
|
|
struct community *merge;
|
|
|
|
struct community *new;
|
|
|
|
struct community *old;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (!rcom)
|
|
|
|
return RMAP_OKAY;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
|
|
|
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
|
|
|
|
COMMUNITY_LIST_MASTER);
|
2022-02-23 08:05:47 +01:00
|
|
|
old = bgp_attr_get_community(path->attr);
|
2020-11-14 01:35:20 +01:00
|
|
|
|
|
|
|
if (list && old) {
|
|
|
|
merge = community_list_match_delete(community_dup(old), list);
|
|
|
|
new = community_uniq_sort(merge);
|
|
|
|
community_free(&merge);
|
|
|
|
|
|
|
|
/* HACK: if the old community is not intern'd,
|
|
|
|
* we should free it here, or all reference to it may be
|
|
|
|
* lost.
|
|
|
|
* Really need to cleanup attribute caching sometime.
|
|
|
|
*/
|
|
|
|
if (old->refcnt == 0)
|
|
|
|
community_free(&old);
|
|
|
|
|
|
|
|
if (new->size == 0) {
|
2022-02-23 08:05:47 +01:00
|
|
|
bgp_attr_set_community(path->attr, NULL);
|
2020-11-14 01:35:20 +01:00
|
|
|
community_free(&new);
|
|
|
|
} else {
|
2022-02-23 08:05:47 +01:00
|
|
|
bgp_attr_set_community(path->attr, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for set community. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_community_delete_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom;
|
2019-07-19 14:56:58 +02:00
|
|
|
char **splits;
|
|
|
|
int num;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-07-19 14:56:58 +02:00
|
|
|
frrstr_split(arg, " ", &splits, &num);
|
2018-12-26 19:01:06 +01:00
|
|
|
|
2019-07-19 14:56:58 +02:00
|
|
|
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
|
|
|
|
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, splits[0]);
|
2019-01-09 02:23:11 +01:00
|
|
|
rcom->name_hash = bgp_clist_hash_key(rcom->name);
|
2019-02-24 01:27:09 +01:00
|
|
|
|
2019-07-19 14:56:58 +02:00
|
|
|
for (int i = 0; i < num; i++)
|
|
|
|
XFREE(MTYPE_TMP, splits[i]);
|
|
|
|
XFREE(MTYPE_TMP, splits);
|
|
|
|
|
2018-12-26 19:01:06 +01:00
|
|
|
return rcom;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free function for set community. */
|
|
|
|
static void route_set_community_delete_free(void *rule)
|
|
|
|
{
|
2018-12-26 19:01:06 +01:00
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom->name);
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set community rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_community_delete_cmd = {
|
|
|
|
"comm-list",
|
|
|
|
route_set_community_delete,
|
|
|
|
route_set_community_delete_compile,
|
|
|
|
route_set_community_delete_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2023-06-14 16:16:55 +02:00
|
|
|
/* `set extcomm-list (<1-99>|<100-500>|WORD) delete' */
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_ecommunity_delete(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
|
|
|
{
|
|
|
|
struct community_list *list;
|
|
|
|
struct ecommunity *merge;
|
|
|
|
struct ecommunity *new;
|
|
|
|
struct ecommunity *old;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
|
|
|
if (!rcom)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
path = object;
|
|
|
|
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
|
|
|
|
EXTCOMMUNITY_LIST_MASTER);
|
|
|
|
old = bgp_attr_get_ecommunity(path->attr);
|
|
|
|
if (list && old) {
|
|
|
|
merge = ecommunity_list_match_delete(ecommunity_dup(old), list);
|
|
|
|
new = ecommunity_uniq_sort(merge);
|
|
|
|
ecommunity_free(&merge);
|
|
|
|
|
|
|
|
/* HACK: if the old community is not intern'd,
|
|
|
|
* we should free it here, or all reference to it may be
|
|
|
|
* lost.
|
|
|
|
* Really need to cleanup attribute caching sometime.
|
|
|
|
*/
|
|
|
|
if (old->refcnt == 0)
|
|
|
|
ecommunity_free(&old);
|
|
|
|
|
|
|
|
if (new->size == 0) {
|
|
|
|
bgp_attr_set_ecommunity(path->attr, NULL);
|
|
|
|
ecommunity_free(&new);
|
|
|
|
} else {
|
|
|
|
bgp_attr_set_ecommunity(path->attr, new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_set_ecommunity_delete_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_community *rcom;
|
|
|
|
char **splits;
|
|
|
|
int num;
|
|
|
|
|
|
|
|
frrstr_split(arg, " ", &splits, &num);
|
|
|
|
|
|
|
|
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
|
|
|
|
rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, splits[0]);
|
|
|
|
rcom->name_hash = bgp_clist_hash_key(rcom->name);
|
|
|
|
|
|
|
|
for (int i = 0; i < num; i++)
|
|
|
|
XFREE(MTYPE_TMP, splits[i]);
|
|
|
|
XFREE(MTYPE_TMP, splits);
|
|
|
|
|
|
|
|
return rcom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_set_ecommunity_delete_free(void *rule)
|
|
|
|
{
|
|
|
|
struct rmap_community *rcom = rule;
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom->name);
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_set_ecommunity_delete_cmd = {
|
|
|
|
"extended-comm-list",
|
|
|
|
route_set_ecommunity_delete,
|
|
|
|
route_set_ecommunity_delete_compile,
|
|
|
|
route_set_ecommunity_delete_free,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set extcommunity rt COMMUNITY' */
|
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
struct rmap_ecom_set {
|
|
|
|
struct ecommunity *ecom;
|
|
|
|
bool none;
|
|
|
|
};
|
|
|
|
|
2014-06-04 00:58:47 +02:00
|
|
|
/* For community set mechanism. Used by _rt and _soo. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_ecommunity(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-08-02 21:27:55 +02:00
|
|
|
struct rmap_ecom_set *rcs;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ecommunity *new_ecom;
|
|
|
|
struct ecommunity *old_ecom;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2021-08-02 21:27:55 +02:00
|
|
|
struct attr *attr;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
rcs = rule;
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2021-08-02 21:27:55 +02:00
|
|
|
attr = path->attr;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
if (rcs->none) {
|
2022-02-04 14:56:20 +01:00
|
|
|
bgp_attr_set_ecommunity(attr, NULL);
|
2021-08-02 21:27:55 +02:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rcs->ecom)
|
2020-11-14 01:35:20 +01:00
|
|
|
return RMAP_OKAY;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* We assume additive for Extended Community. */
|
2022-02-04 14:56:20 +01:00
|
|
|
old_ecom = bgp_attr_get_ecommunity(path->attr);
|
2020-11-14 01:35:20 +01:00
|
|
|
|
|
|
|
if (old_ecom) {
|
2021-08-02 21:27:55 +02:00
|
|
|
new_ecom =
|
|
|
|
ecommunity_merge(ecommunity_dup(old_ecom), rcs->ecom);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* old_ecom->refcnt = 1 => owned elsewhere, e.g.
|
|
|
|
* bgp_update_receive()
|
|
|
|
* ->refcnt = 0 => set by a previous route-map
|
|
|
|
* statement */
|
|
|
|
if (!old_ecom->refcnt)
|
|
|
|
ecommunity_free(&old_ecom);
|
|
|
|
} else
|
2021-08-02 21:27:55 +02:00
|
|
|
new_ecom = ecommunity_dup(rcs->ecom);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
|
2022-02-04 14:56:20 +01:00
|
|
|
bgp_attr_set_ecommunity(path->attr, new_ecom);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
static void *route_set_ecommunity_none_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_ecom_set *rcs;
|
|
|
|
bool none = false;
|
|
|
|
|
|
|
|
if (strncmp(arg, "none", 4) == 0)
|
|
|
|
none = true;
|
|
|
|
|
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_ecom_set));
|
|
|
|
rcs->ecom = NULL;
|
|
|
|
rcs->none = none;
|
|
|
|
|
|
|
|
return rcs;
|
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_ecommunity_rt_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-08-02 21:27:55 +02:00
|
|
|
struct rmap_ecom_set *rcs;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ecommunity *ecom;
|
|
|
|
|
|
|
|
ecom = ecommunity_str2com(arg, ECOMMUNITY_ROUTE_TARGET, 0);
|
|
|
|
if (!ecom)
|
|
|
|
return NULL;
|
2021-08-02 21:27:55 +02:00
|
|
|
|
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_ecom_set));
|
|
|
|
rcs->ecom = ecommunity_intern(ecom);
|
|
|
|
rcs->none = false;
|
|
|
|
|
|
|
|
return rcs;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2014-06-04 00:58:47 +02:00
|
|
|
/* Free function for set community. Used by _rt and _soo */
|
|
|
|
static void route_set_ecommunity_free(void *rule)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-08-02 21:27:55 +02:00
|
|
|
struct rmap_ecom_set *rcs = rule;
|
|
|
|
|
|
|
|
if (rcs->ecom)
|
|
|
|
ecommunity_unintern(&rcs->ecom);
|
|
|
|
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rcs);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
static const struct route_map_rule_cmd route_set_ecommunity_none_cmd = {
|
|
|
|
"extcommunity",
|
|
|
|
route_set_ecommunity,
|
|
|
|
route_set_ecommunity_none_compile,
|
|
|
|
route_set_ecommunity_free,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set community rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_ecommunity_rt_cmd = {
|
|
|
|
"extcommunity rt",
|
|
|
|
route_set_ecommunity,
|
|
|
|
route_set_ecommunity_rt_compile,
|
|
|
|
route_set_ecommunity_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* `set extcommunity soo COMMUNITY' */
|
|
|
|
|
|
|
|
/* Compile function for set community. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_ecommunity_soo_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-08-02 21:27:55 +02:00
|
|
|
struct rmap_ecom_set *rcs;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ecommunity *ecom;
|
|
|
|
|
|
|
|
ecom = ecommunity_str2com(arg, ECOMMUNITY_SITE_ORIGIN, 0);
|
|
|
|
if (!ecom)
|
|
|
|
return NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_ecom_set));
|
|
|
|
rcs->ecom = ecommunity_intern(ecom);
|
|
|
|
rcs->none = false;
|
|
|
|
|
|
|
|
return rcs;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set community rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_ecommunity_soo_cmd = {
|
|
|
|
"extcommunity soo",
|
|
|
|
route_set_ecommunity,
|
|
|
|
route_set_ecommunity_soo_compile,
|
|
|
|
route_set_ecommunity_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
bgpd: Implement Node Target Extended Communities
kttps://datatracker.ietf.org/doc/html/draft-ietf-idr-node-target-ext-comm
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.2 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.3 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r2 vtysh -c 'show ip bgp 10.10.10.10/32'
% Network not in table
unet> sh r3 vtysh -c 'show ip bgp 10.10.10.10/32'
BGP routing table entry for 10.10.10.10/32, version 1
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.1.1
65001
192.168.1.1 from 192.168.1.1 (192.168.1.1)
Origin IGP, metric 0, valid, external, best (First path received)
Extended Community: NT:192.168.1.3 NT:192.168.1.4
Last update: Tue Apr 11 23:19:33 2023
unet>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-04-05 14:51:45 +02:00
|
|
|
static void *route_set_ecommunity_nt_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_ecom_set *rcs;
|
|
|
|
struct ecommunity *ecom;
|
|
|
|
|
|
|
|
ecom = ecommunity_str2com(arg, ECOMMUNITY_NODE_TARGET, 0);
|
|
|
|
if (!ecom)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_ecom_set));
|
|
|
|
rcs->ecom = ecommunity_intern(ecom);
|
|
|
|
rcs->none = false;
|
|
|
|
|
|
|
|
return rcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_set_ecommunity_nt_cmd = {
|
|
|
|
"extcommunity nt",
|
|
|
|
route_set_ecommunity,
|
|
|
|
route_set_ecommunity_nt_compile,
|
|
|
|
route_set_ecommunity_free,
|
|
|
|
};
|
|
|
|
|
2020-03-24 19:50:44 +01:00
|
|
|
/* `set extcommunity bandwidth' */
|
|
|
|
|
|
|
|
struct rmap_ecomm_lb_set {
|
|
|
|
uint8_t lb_type;
|
|
|
|
#define RMAP_ECOMM_LB_SET_VALUE 1
|
|
|
|
#define RMAP_ECOMM_LB_SET_CUMUL 2
|
|
|
|
#define RMAP_ECOMM_LB_SET_NUM_MPATH 3
|
|
|
|
bool non_trans;
|
2024-04-08 08:22:02 +02:00
|
|
|
uint64_t bw;
|
2020-03-24 19:50:44 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
|
2020-03-24 19:50:44 +01:00
|
|
|
{
|
|
|
|
struct rmap_ecomm_lb_set *rels = rule;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
struct peer *peer;
|
|
|
|
struct ecommunity ecom_lb = {0};
|
2024-04-08 08:22:02 +02:00
|
|
|
uint64_t bw_bytes = 0;
|
2020-03-24 21:57:44 +01:00
|
|
|
uint16_t mpath_count = 0;
|
2020-03-24 19:50:44 +01:00
|
|
|
struct ecommunity *new_ecom;
|
|
|
|
struct ecommunity *old_ecom;
|
|
|
|
as_t as;
|
|
|
|
|
|
|
|
path = object;
|
|
|
|
peer = path->peer;
|
|
|
|
if (!peer || !peer->bgp)
|
|
|
|
return RMAP_ERROR;
|
|
|
|
|
|
|
|
/* Build link bandwidth extended community */
|
|
|
|
as = (peer->bgp->as > BGP_AS_MAX) ? BGP_AS_TRANS : peer->bgp->as;
|
2020-03-24 21:57:44 +01:00
|
|
|
if (rels->lb_type == RMAP_ECOMM_LB_SET_VALUE) {
|
2024-04-08 08:22:02 +02:00
|
|
|
bw_bytes = (rels->bw * 1000 * 1000) / 8;
|
2020-03-24 21:57:44 +01:00
|
|
|
} else if (rels->lb_type == RMAP_ECOMM_LB_SET_CUMUL) {
|
|
|
|
/* process this only for the best path. */
|
|
|
|
if (!CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
2024-04-08 08:22:02 +02:00
|
|
|
bw_bytes = bgp_path_info_mpath_cumbw(path);
|
2020-03-24 21:57:44 +01:00
|
|
|
if (!bw_bytes)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
} else if (rels->lb_type == RMAP_ECOMM_LB_SET_NUM_MPATH) {
|
|
|
|
|
|
|
|
/* process this only for the best path. */
|
|
|
|
if (!CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
2024-04-08 08:22:02 +02:00
|
|
|
bw_bytes = (peer->bgp->lb_ref_bw * 1000 * 1000) / 8;
|
2024-09-30 21:09:42 +02:00
|
|
|
mpath_count = bgp_path_info_mpath_count(path);
|
2020-03-24 21:57:44 +01:00
|
|
|
bw_bytes *= mpath_count;
|
|
|
|
}
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2024-04-10 09:16:01 +02:00
|
|
|
if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_LINK_BANDWIDTH)) {
|
|
|
|
struct ecommunity_val_ipv6 lb_eval;
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2024-04-10 09:16:01 +02:00
|
|
|
encode_lb_extended_extcomm(as, bw_bytes, rels->non_trans,
|
|
|
|
&lb_eval);
|
|
|
|
|
|
|
|
old_ecom = bgp_attr_get_ipv6_ecommunity(path->attr);
|
|
|
|
if (old_ecom) {
|
|
|
|
new_ecom = ecommunity_dup(old_ecom);
|
|
|
|
ecommunity_add_val_ipv6(new_ecom, &lb_eval, true, true);
|
|
|
|
if (!old_ecom->refcnt)
|
|
|
|
ecommunity_free(&old_ecom);
|
|
|
|
} else {
|
|
|
|
ecom_lb.size = 1;
|
|
|
|
ecom_lb.unit_size = IPV6_ECOMMUNITY_SIZE;
|
|
|
|
ecom_lb.val = (uint8_t *)lb_eval.val;
|
|
|
|
new_ecom = ecommunity_dup(&ecom_lb);
|
|
|
|
}
|
|
|
|
|
|
|
|
bgp_attr_set_ipv6_ecommunity(path->attr, new_ecom);
|
2020-03-24 21:53:09 +01:00
|
|
|
} else {
|
2024-04-10 09:16:01 +02:00
|
|
|
struct ecommunity_val lb_eval;
|
|
|
|
|
|
|
|
encode_lb_extcomm(as, bw_bytes, rels->non_trans, &lb_eval,
|
|
|
|
CHECK_FLAG(peer->flags,
|
|
|
|
PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
|
|
|
|
|
|
|
|
old_ecom = bgp_attr_get_ecommunity(path->attr);
|
|
|
|
if (old_ecom) {
|
|
|
|
new_ecom = ecommunity_dup(old_ecom);
|
|
|
|
ecommunity_add_val(new_ecom, &lb_eval, true, true);
|
|
|
|
if (!old_ecom->refcnt)
|
|
|
|
ecommunity_free(&old_ecom);
|
|
|
|
} else {
|
|
|
|
ecom_lb.size = 1;
|
|
|
|
ecom_lb.unit_size = ECOMMUNITY_SIZE;
|
|
|
|
ecom_lb.val = (uint8_t *)lb_eval.val;
|
|
|
|
new_ecom = ecommunity_dup(&ecom_lb);
|
|
|
|
}
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2024-04-10 09:16:01 +02:00
|
|
|
bgp_attr_set_ecommunity(path->attr, new_ecom);
|
|
|
|
}
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2020-03-24 22:25:56 +01:00
|
|
|
/* Mark that route-map has set link bandwidth; used in attribute
|
|
|
|
* setting decisions.
|
|
|
|
*/
|
|
|
|
SET_FLAG(path->attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET);
|
2020-03-24 19:50:44 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_set_ecommunity_lb_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_ecomm_lb_set *rels;
|
|
|
|
uint8_t lb_type;
|
2024-04-08 08:22:02 +02:00
|
|
|
uint64_t bw = 0;
|
2020-03-24 22:41:52 +01:00
|
|
|
char bw_str[40] = {0};
|
|
|
|
char *p, *str;
|
|
|
|
bool non_trans = false;
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2020-03-24 22:41:52 +01:00
|
|
|
str = (char *)arg;
|
|
|
|
p = strchr(arg, ' ');
|
|
|
|
if (p) {
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = p - arg;
|
|
|
|
memcpy(bw_str, arg, len);
|
|
|
|
non_trans = true;
|
|
|
|
str = bw_str;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(str, "cumulative") == 0)
|
2020-03-24 19:50:44 +01:00
|
|
|
lb_type = RMAP_ECOMM_LB_SET_CUMUL;
|
2020-03-24 22:41:52 +01:00
|
|
|
else if (strcmp(str, "num-multipaths") == 0)
|
2020-03-24 19:50:44 +01:00
|
|
|
lb_type = RMAP_ECOMM_LB_SET_NUM_MPATH;
|
|
|
|
else {
|
|
|
|
char *end = NULL;
|
|
|
|
|
2020-03-24 22:41:52 +01:00
|
|
|
bw = strtoul(str, &end, 10);
|
2020-03-24 19:50:44 +01:00
|
|
|
if (*end != '\0')
|
|
|
|
return NULL;
|
|
|
|
lb_type = RMAP_ECOMM_LB_SET_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
rels = XCALLOC(MTYPE_ROUTE_MAP_COMPILED,
|
|
|
|
sizeof(struct rmap_ecomm_lb_set));
|
|
|
|
rels->lb_type = lb_type;
|
|
|
|
rels->bw = bw;
|
2020-03-24 22:41:52 +01:00
|
|
|
rels->non_trans = non_trans;
|
2020-03-24 19:50:44 +01:00
|
|
|
|
|
|
|
return rels;
|
|
|
|
}
|
|
|
|
|
2023-05-22 15:36:06 +02:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_ecommunity_color(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
|
|
|
{
|
|
|
|
route_set_ecommunity(rule, prefix, object);
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_set_ecommunity_color_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct rmap_ecom_set *rcs;
|
|
|
|
struct ecommunity *ecom;
|
|
|
|
|
|
|
|
ecom = ecommunity_str2com(arg, ECOMMUNITY_COLOR, 0);
|
|
|
|
if (!ecom)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
rcs = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_ecom_set));
|
|
|
|
rcs->ecom = ecommunity_intern(ecom);
|
|
|
|
rcs->none = false;
|
|
|
|
|
|
|
|
return rcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_set_ecommunity_color_cmd = {
|
|
|
|
"extcommunity color",
|
|
|
|
route_set_ecommunity_color,
|
|
|
|
route_set_ecommunity_color_compile,
|
|
|
|
route_set_ecommunity_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-03-24 19:50:44 +01:00
|
|
|
static void route_set_ecommunity_lb_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set community rule structure. */
|
|
|
|
struct route_map_rule_cmd route_set_ecommunity_lb_cmd = {
|
|
|
|
"extcommunity bandwidth",
|
|
|
|
route_set_ecommunity_lb,
|
|
|
|
route_set_ecommunity_lb_compile,
|
|
|
|
route_set_ecommunity_lb_free,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set origin ORIGIN' */
|
|
|
|
|
|
|
|
/* For origin set. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_origin(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *origin;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
origin = rule;
|
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path->attr->origin = *origin;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for origin set. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_origin_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *origin;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
origin = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (strcmp(arg, "igp") == 0)
|
2023-02-18 13:24:12 +01:00
|
|
|
*origin = BGP_ORIGIN_IGP;
|
2002-12-13 21:15:29 +01:00
|
|
|
else if (strcmp(arg, "egp") == 0)
|
2023-02-18 13:24:12 +01:00
|
|
|
*origin = BGP_ORIGIN_EGP;
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2023-02-18 13:24:12 +01:00
|
|
|
*origin = BGP_ORIGIN_INCOMPLETE;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return origin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for origin set. */
|
|
|
|
static void route_set_origin_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2014-05-20 07:57:26 +02:00
|
|
|
/* Set origin rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_origin_cmd = {
|
|
|
|
"origin",
|
|
|
|
route_set_origin,
|
|
|
|
route_set_origin_compile,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_set_origin_free,
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set atomic-aggregate' */
|
|
|
|
|
|
|
|
/* For atomic aggregate set. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_atomic_aggregate(void *rule, const struct prefix *pfx, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for atomic aggregate. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_atomic_aggregate_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return (void *)1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for atomic aggregate. */
|
|
|
|
static void route_set_atomic_aggregate_free(void *rule)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set atomic aggregate rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_atomic_aggregate_cmd = {
|
|
|
|
"atomic-aggregate",
|
|
|
|
route_set_atomic_aggregate,
|
|
|
|
route_set_atomic_aggregate_compile,
|
|
|
|
route_set_atomic_aggregate_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2022-10-12 20:06:47 +02:00
|
|
|
/* AIGP TLV Metric */
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_set_aigp_metric(void *rule, const struct prefix *pfx, void *object)
|
|
|
|
{
|
|
|
|
const char *aigp_metric = rule;
|
|
|
|
struct bgp_path_info *path = object;
|
|
|
|
uint32_t aigp = 0;
|
|
|
|
|
|
|
|
if (strmatch(aigp_metric, "igp-metric")) {
|
|
|
|
if (!path->nexthop)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
|
|
|
bgp_attr_set_aigp_metric(path->attr, path->nexthop->metric);
|
|
|
|
} else {
|
|
|
|
aigp = atoi(aigp_metric);
|
|
|
|
bgp_attr_set_aigp_metric(path->attr, aigp);
|
|
|
|
}
|
|
|
|
|
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AIGP);
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_set_aigp_metric_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_set_aigp_metric_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_set_aigp_metric_cmd = {
|
|
|
|
"aigp-metric",
|
|
|
|
route_set_aigp_metric,
|
|
|
|
route_set_aigp_metric_compile,
|
|
|
|
route_set_aigp_metric_free,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set aggregator as AS A.B.C.D' */
|
|
|
|
struct aggregator {
|
|
|
|
as_t as;
|
|
|
|
struct in_addr address;
|
|
|
|
};
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_aggregator_as(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct aggregator *aggregator;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
|
|
|
aggregator = rule;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path->attr->aggregator_as = aggregator->as;
|
|
|
|
path->attr->aggregator_addr = aggregator->address;
|
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_aggregator_as_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct aggregator *aggregator;
|
|
|
|
char as[10];
|
|
|
|
char address[20];
|
2017-06-13 19:10:32 +02:00
|
|
|
int ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
aggregator =
|
|
|
|
XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct aggregator));
|
2017-12-05 02:51:34 +01:00
|
|
|
if (sscanf(arg, "%s %s", as, address) != 2) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, aggregator);
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
aggregator->as = strtoul(as, NULL, 10);
|
2017-06-13 19:10:32 +02:00
|
|
|
ret = inet_aton(address, &aggregator->address);
|
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, aggregator);
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return aggregator;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_set_aggregator_as_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_aggregator_as_cmd = {
|
|
|
|
"aggregator as",
|
|
|
|
route_set_aggregator_as,
|
|
|
|
route_set_aggregator_as_compile,
|
|
|
|
route_set_aggregator_as_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2018-10-02 22:41:30 +02:00
|
|
|
/* Set tag to object. object must be pointer to struct bgp_path_info */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_tag(void *rule, const struct prefix *prefix, void *object)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-10-01 20:42:34 +02:00
|
|
|
route_tag_t *tag;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
tag = rule;
|
|
|
|
path = object;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set tag value */
|
|
|
|
path->attr->tag = *tag;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for tag set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_tag_cmd = {
|
|
|
|
"tag",
|
|
|
|
route_set_tag,
|
|
|
|
route_map_rule_tag_compile,
|
2016-10-01 20:42:34 +02:00
|
|
|
route_map_rule_tag_free,
|
2015-05-20 02:46:33 +02:00
|
|
|
};
|
|
|
|
|
2018-10-02 22:41:30 +02:00
|
|
|
/* Set label-index to object. object must be pointer to struct bgp_path_info */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_label_index(void *rule, const struct prefix *prefix, void *object)
|
2017-06-02 21:22:53 +02:00
|
|
|
{
|
|
|
|
struct rmap_value *rv;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t label_index;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
rv = rule;
|
|
|
|
path = object;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set label-index value. */
|
|
|
|
label_index = rv->value;
|
|
|
|
if (label_index) {
|
|
|
|
path->attr->label_index = label_index;
|
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
|
2017-06-02 21:22:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for label-index set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_label_index_cmd = {
|
|
|
|
"label-index",
|
|
|
|
route_set_label_index,
|
|
|
|
route_value_compile,
|
2017-06-02 21:22:53 +02:00
|
|
|
route_value_free,
|
|
|
|
};
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match ipv6 address IP_ACCESS_LIST' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *alist;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET6) {
|
2002-12-13 21:15:29 +01:00
|
|
|
alist = access_list_lookup(AFI_IP6, (char *)rule);
|
2023-02-13 15:22:36 +01:00
|
|
|
if (alist == NULL) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:22:36 +01:00
|
|
|
}
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return (access_list_apply(alist, prefix) == FILTER_DENY
|
|
|
|
? RMAP_NOMATCH
|
|
|
|
: RMAP_MATCH);
|
|
|
|
}
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ipv6_address_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2023-02-12 18:33:49 +01:00
|
|
|
struct access_list *alist;
|
|
|
|
|
|
|
|
alist = access_list_lookup(AFI_IP6, arg);
|
|
|
|
if (!alist)
|
|
|
|
zlog_warn(
|
|
|
|
"Access List specified %s does not exist yet, default will be NO_MATCH until it is created",
|
|
|
|
arg);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ipv6_address_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip address matching. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_ipv6_address_cmd = {
|
|
|
|
"ipv6 address",
|
|
|
|
route_match_ipv6_address,
|
|
|
|
route_match_ipv6_address_compile,
|
|
|
|
route_match_ipv6_address_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
/* `match ipv6 next-hop ACCESSLIST6_NAME' */
|
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_ipv6_next_hop(void *rule, const struct prefix *prefix, void *object)
|
|
|
|
{
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
struct access_list *alist;
|
|
|
|
struct prefix_ipv6 p;
|
|
|
|
|
|
|
|
if (prefix->family == AF_INET6) {
|
|
|
|
path = object;
|
|
|
|
p.family = AF_INET6;
|
|
|
|
p.prefix = path->attr->mp_nexthop_global;
|
|
|
|
p.prefixlen = IPV6_MAX_BITLEN;
|
|
|
|
|
|
|
|
alist = access_list_lookup(AFI_IP6, (char *)rule);
|
2023-02-13 15:22:36 +01:00
|
|
|
if (!alist) {
|
2023-02-17 21:02:14 +01:00
|
|
|
if (unlikely(CHECK_FLAG(rmap_debug,
|
|
|
|
DEBUG_ROUTEMAP_DETAIL)))
|
2023-02-13 15:22:36 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
|
|
|
|
__func__, (char *)rule);
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
return RMAP_NOMATCH;
|
2023-02-13 15:22:36 +01:00
|
|
|
}
|
2021-11-22 20:26:33 +01:00
|
|
|
|
|
|
|
if (access_list_apply(alist, &p) == FILTER_PERMIT)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
if (path->attr->mp_nexthop_len
|
|
|
|
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
|
|
|
|
p.prefix = path->attr->mp_nexthop_local;
|
|
|
|
if (access_list_apply(alist, &p) == FILTER_PERMIT)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_ipv6_next_hop_compile(const char *arg)
|
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ipv6_next_hop_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_match_ipv6_next_hop_cmd = {
|
|
|
|
"ipv6 next-hop",
|
|
|
|
route_match_ipv6_next_hop,
|
|
|
|
route_match_ipv6_next_hop_compile,
|
|
|
|
route_match_ipv6_next_hop_free
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match ipv6 next-hop IP_ADDRESS' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2021-11-22 20:26:33 +01:00
|
|
|
route_match_ipv6_next_hop_address(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
Fix most compiler warnings in default GCC build.
Fix lots of warnings. Some const and type-pun breaks strict-aliasing
warnings left but much reduced.
* bgp_advertise.h: (struct bgp_advertise_fifo) is functionally identical to
(struct fifo), so just use that. Makes it clearer the beginning of
(struct bgp_advertise) is compatible with with (struct fifo), which seems
to be enough for gcc.
Add a BGP_ADV_FIFO_HEAD macro to contain the right cast to try shut up
type-punning breaks strict aliasing warnings.
* bgp_packet.c: Use BGP_ADV_FIFO_HEAD.
(bgp_route_refresh_receive) fix an interesting logic error in
(!ok || (ret != BLAH)) where ret is only well-defined if ok.
* bgp_vty.c: Peer commands should use bgp_vty_return to set their return.
* jhash.{c,h}: Can take const on * args without adding issues & fix warnings.
* libospf.h: LSA sequence numbers use the unsigned range of values, and
constants need to be set to unsigned, or it causes warnings in ospf6d.
* md5.h: signedness of caddr_t is implementation specific, change to an
explicit (uint_8 *), fix sign/unsigned comparison warnings.
* vty.c: (vty_log_fixed) const on level is well-intentioned, but not going
to fly given iov_base.
* workqueue.c: ALL_LIST_ELEMENTS_RO tests for null pointer, which is always
true for address of static variable. Correct but pointless warning in
this case, but use a 2nd pointer to shut it up.
* ospf6_route.h: Add a comment about the use of (struct prefix) to stuff 2
different 32 bit IDs into in (struct ospf6_route), and the resulting
type-pun strict-alias breakage warnings this causes. Need to use 2
different fields to fix that warning?
general:
* remove unused variables, other than a few cases where they serve a
sufficiently useful documentary purpose (e.g. for code that needs
fixing), or they're required dummies. In those cases, try mark them as
unused.
* Remove dead code that can't be reached.
* Quite a few 'no ...' forms of vty commands take arguments, but do not
check the argument matches the command being negated. E.g., should
'distance X <prefix>' succeed if previously 'distance Y <prefix>' was set?
Or should it be required that the distance match the previously configured
distance for the prefix?
Ultimately, probably better to be strict about this. However, changing
from slack to strict might expose problems in command aliases and tools.
* Fix uninitialised use of variables.
* Fix sign/unsigned comparison warnings by making signedness of types consistent.
* Mark functions as static where their use is restricted to the same compilation
unit.
* Add required headers
* Move constants defined in headers into code.
* remove dead, unused functions that have no debug purpose.
(cherry picked from commit 7aa9dcef80b2ce50ecaa77653d87c8b84e009c49)
Conflicts:
bgpd/bgp_advertise.h
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_packet.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
lib/command.c
lib/if.c
lib/jhash.c
lib/workqueue.c
ospf6d/ospf6_lsa.c
ospf6d/ospf6_neighbor.h
ospf6d/ospf6_spf.c
ospf6d/ospf6_top.c
ospfd/ospf_api.c
zebra/router-id.c
zebra/rt_netlink.c
zebra/rt_netlink.h
2014-09-19 15:42:23 +02:00
|
|
|
struct in6_addr *addr = rule;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (IPV6_ADDR_SAME(&path->attr->mp_nexthop_global, addr))
|
|
|
|
return RMAP_MATCH;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (path->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
|
|
|
|
&& IPV6_ADDR_SAME(&path->attr->mp_nexthop_local, rule))
|
|
|
|
return RMAP_MATCH;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
static void *route_match_ipv6_next_hop_address_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in6_addr *address;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
|
|
|
|
|
|
|
|
ret = inet_pton(AF_INET6, arg, address);
|
|
|
|
if (!ret) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
static void route_match_ipv6_next_hop_address_free(void *rule)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
static const struct route_map_rule_cmd route_match_ipv6_next_hop_address_cmd = {
|
2021-11-19 19:11:52 +01:00
|
|
|
"ipv6 next-hop address",
|
2021-11-22 20:26:33 +01:00
|
|
|
route_match_ipv6_next_hop_address,
|
|
|
|
route_match_ipv6_next_hop_address_compile,
|
|
|
|
route_match_ipv6_next_hop_address_free
|
2019-11-20 17:20:58 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2023-02-12 18:33:49 +01:00
|
|
|
/* `match ip next-hop address IP_ADDRESS' */
|
2020-03-09 16:13:19 +01:00
|
|
|
|
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_match_ipv4_next_hop(void *rule, const struct prefix *prefix, void *object)
|
2020-03-09 16:13:19 +01:00
|
|
|
{
|
|
|
|
struct in_addr *addr = rule;
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path = object;
|
2020-03-09 16:13:19 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
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;
|
2020-03-09 16:13:19 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `match ipv6 address prefix-list PREFIX_LIST' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2018-07-12 22:05:19 +02:00
|
|
|
route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-11-14 01:35:20 +01:00
|
|
|
return route_match_address_prefix_list(rule, AFI_IP6, prefix, object);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_match_ipv6_address_prefix_list_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ipv6_address_prefix_list_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ipv6_address_prefix_list_cmd = {
|
|
|
|
"ipv6 address prefix-list",
|
|
|
|
route_match_ipv6_address_prefix_list,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_match_ipv6_address_prefix_list_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_ipv6_address_prefix_list_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2018-09-28 10:51:50 +02:00
|
|
|
/* `match ipv6 next-hop type <TYPE>' */
|
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2018-09-28 10:51:50 +02:00
|
|
|
route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2018-09-28 10:51:50 +02:00
|
|
|
{
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2018-09-28 10:51:50 +02:00
|
|
|
struct in6_addr *addr = rule;
|
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
if (prefix->family == AF_INET6) {
|
2018-10-03 00:34:03 +02:00
|
|
|
path = (struct bgp_path_info *)object;
|
2019-10-16 16:25:19 +02:00
|
|
|
if (!path)
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
return RMAP_NOMATCH;
|
2018-09-28 10:51:50 +02:00
|
|
|
|
2018-10-03 00:34:03 +02:00
|
|
|
if (IPV6_ADDR_SAME(&path->attr->mp_nexthop_global, addr)
|
|
|
|
&& !path->attr->nh_ifindex)
|
2018-09-28 10:51:50 +02:00
|
|
|
return RMAP_MATCH;
|
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2018-09-28 10:51:50 +02:00
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_ipv6_next_hop_type_compile(const char *arg)
|
|
|
|
{
|
|
|
|
struct in6_addr *address;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
|
|
|
|
|
|
|
|
ret = inet_pton(AF_INET6, "::0", address);
|
|
|
|
if (!ret) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_match_ipv6_next_hop_type_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_match_ipv6_next_hop_type_cmd = {
|
|
|
|
"ipv6 next-hop type",
|
|
|
|
route_match_ipv6_next_hop_type,
|
2018-09-28 10:51:50 +02:00
|
|
|
route_match_ipv6_next_hop_type_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_match_ipv6_next_hop_type_free
|
|
|
|
};
|
2018-09-28 10:51:50 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set ipv6 nexthop global IP_ADDRESS' */
|
|
|
|
|
2022-04-02 13:33:53 +02:00
|
|
|
/* Set nexthop to object. object must be pointer to struct attr. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_ipv6_nexthop_global(void *rule, const struct prefix *p, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in6_addr *address;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
address = rule;
|
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set next hop value. */
|
|
|
|
path->attr->mp_nexthop_global = *address;
|
2015-05-20 03:03:47 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set nexthop length. */
|
|
|
|
if (path->attr->mp_nexthop_len == 0)
|
|
|
|
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
2015-05-20 03:03:47 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip next-hop' compile function. Given string is converted
|
|
|
|
to struct in_addr structure. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_ipv6_nexthop_global_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in6_addr *address;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
|
|
|
|
|
|
|
|
ret = inet_pton(AF_INET6, arg, address);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip next-hop' value. */
|
|
|
|
static void route_set_ipv6_nexthop_global_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip nexthop set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_set_ipv6_nexthop_global_cmd = {
|
|
|
|
"ipv6 next-hop global",
|
|
|
|
route_set_ipv6_nexthop_global,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_set_ipv6_nexthop_global_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_set_ipv6_nexthop_global_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2016-08-03 15:49:09 +02:00
|
|
|
/* Set next-hop preference value. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2018-07-12 22:05:19 +02:00
|
|
|
route_set_ipv6_nexthop_prefer_global(void *rule, const struct prefix *prefix,
|
2020-11-14 01:35:20 +01:00
|
|
|
void *object)
|
2016-08-03 15:49:09 +02:00
|
|
|
{
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2016-08-03 15:49:09 +02:00
|
|
|
struct peer *peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
path = object;
|
|
|
|
peer = path->peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2024-09-02 14:32:00 +02:00
|
|
|
if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN)) {
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set next hop preference to global */
|
2022-04-29 19:41:57 +02:00
|
|
|
SET_FLAG(path->attr->nh_flags, BGP_ATTR_NH_MP_PREFER_GLOBAL);
|
2020-11-14 01:35:20 +01:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
|
|
|
|
} else {
|
2022-04-29 19:41:57 +02:00
|
|
|
UNSET_FLAG(path->attr->nh_flags, BGP_ATTR_NH_MP_PREFER_GLOBAL);
|
2020-11-14 01:35:20 +01:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
|
2016-08-03 15:49:09 +02:00
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
|
2016-08-03 15:49:09 +02:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_set_ipv6_nexthop_prefer_global_compile(const char *arg)
|
|
|
|
{
|
|
|
|
int *rins = NULL;
|
|
|
|
|
|
|
|
rins = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int));
|
|
|
|
*rins = 1;
|
|
|
|
|
|
|
|
return rins;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip next-hop' value. */
|
|
|
|
static void route_set_ipv6_nexthop_prefer_global_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip nexthop set preferred. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_set_ipv6_nexthop_prefer_global_cmd = {
|
|
|
|
"ipv6 next-hop prefer-global",
|
|
|
|
route_set_ipv6_nexthop_prefer_global,
|
2016-08-03 15:49:09 +02:00
|
|
|
route_set_ipv6_nexthop_prefer_global_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_set_ipv6_nexthop_prefer_global_free
|
|
|
|
};
|
2016-08-03 15:49:09 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set ipv6 nexthop local IP_ADDRESS' */
|
|
|
|
|
2022-04-02 13:33:53 +02:00
|
|
|
/* Set nexthop to object. object must be pointer to struct attr. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_ipv6_nexthop_local(void *rule, const struct prefix *p, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in6_addr *address;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2023-02-13 12:18:33 +01:00
|
|
|
struct bgp_dest *dest;
|
|
|
|
struct bgp_table *table = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
address = rule;
|
|
|
|
path = object;
|
2023-02-13 12:18:33 +01:00
|
|
|
dest = path->net;
|
|
|
|
|
|
|
|
if (!dest)
|
|
|
|
return RMAP_OKAY;
|
|
|
|
|
|
|
|
table = bgp_dest_table(dest);
|
|
|
|
if (!table)
|
|
|
|
return RMAP_OKAY;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set next hop value. */
|
|
|
|
path->attr->mp_nexthop_local = *address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set nexthop length. */
|
2023-02-13 12:18:33 +01:00
|
|
|
if (table->safi == SAFI_MPLS_VPN || table->safi == SAFI_ENCAP ||
|
|
|
|
table->safi == SAFI_EVPN)
|
|
|
|
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
|
|
|
|
else
|
2020-11-14 01:35:20 +01:00
|
|
|
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_IPV6_LL_NHOP_CHANGED);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip nexthop' compile function. Given string is converted
|
|
|
|
to struct in_addr structure. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_ipv6_nexthop_local_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in6_addr *address;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
|
|
|
|
|
|
|
|
ret = inet_pton(AF_INET6, arg, address);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip nexthop' value. */
|
|
|
|
static void route_set_ipv6_nexthop_local_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip nexthop set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd
|
|
|
|
route_set_ipv6_nexthop_local_cmd = {
|
|
|
|
"ipv6 next-hop local",
|
|
|
|
route_set_ipv6_nexthop_local,
|
2002-12-13 21:15:29 +01:00
|
|
|
route_set_ipv6_nexthop_local_compile,
|
2019-11-20 17:20:58 +01:00
|
|
|
route_set_ipv6_nexthop_local_free
|
|
|
|
};
|
2015-05-20 02:24:45 +02:00
|
|
|
|
|
|
|
/* `set ipv6 nexthop peer-address' */
|
|
|
|
|
2022-04-02 13:33:53 +02:00
|
|
|
/* Set nexthop to object. object must be pointer to struct attr. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_ipv6_nexthop_peer(void *rule, const struct prefix *pfx, void *object)
|
2015-05-20 02:24:45 +02:00
|
|
|
{
|
|
|
|
struct in6_addr peer_address;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2015-05-20 02:24:45 +02:00
|
|
|
struct peer *peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
path = object;
|
|
|
|
peer = path->peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2024-09-02 14:32:00 +02:00
|
|
|
if ((CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN)) &&
|
|
|
|
peer->su_remote && sockunion_family(peer->su_remote) == AF_INET6) {
|
2020-11-14 01:35:20 +01:00
|
|
|
peer_address = peer->su_remote->sin6.sin6_addr;
|
|
|
|
/* Set next hop value and length in attribute. */
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&peer_address)) {
|
|
|
|
path->attr->mp_nexthop_local = peer_address;
|
|
|
|
if (path->attr->mp_nexthop_len
|
|
|
|
!= BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
|
|
|
|
path->attr->mp_nexthop_len =
|
|
|
|
BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
|
|
|
|
} else {
|
|
|
|
path->attr->mp_nexthop_global = peer_address;
|
|
|
|
if (path->attr->mp_nexthop_len == 0)
|
|
|
|
path->attr->mp_nexthop_len =
|
|
|
|
BGP_ATTR_NHLEN_IPV6_GLOBAL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2020-11-14 01:35:20 +01:00
|
|
|
} else if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT)) {
|
|
|
|
/* The next hop value will be set as part of packet
|
|
|
|
* rewrite.
|
|
|
|
* Set the flags here to indicate that rewrite needs to
|
|
|
|
* be done.
|
|
|
|
* Also, clear the value - we clear both global and
|
|
|
|
* link-local
|
|
|
|
* nexthops, whether we send one or both is determined
|
|
|
|
* elsewhere.
|
|
|
|
*/
|
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
|
|
|
|
/* clear next hop value. */
|
|
|
|
memset(&(path->attr->mp_nexthop_global), 0,
|
|
|
|
sizeof(struct in6_addr));
|
|
|
|
memset(&(path->attr->mp_nexthop_local), 0,
|
|
|
|
sizeof(struct in6_addr));
|
2015-05-20 02:24:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map `ip next-hop' compile function. Given string is converted
|
|
|
|
to struct in_addr structure. */
|
|
|
|
static void *route_set_ipv6_nexthop_peer_compile(const char *arg)
|
|
|
|
{
|
|
|
|
int *rins = NULL;
|
|
|
|
|
|
|
|
rins = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int));
|
|
|
|
*rins = 1;
|
|
|
|
|
|
|
|
return rins;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free route map's compiled `ip next-hop' value. */
|
|
|
|
static void route_set_ipv6_nexthop_peer_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route map commands for ip nexthop set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd = {
|
|
|
|
"ipv6 next-hop peer-address",
|
|
|
|
route_set_ipv6_nexthop_peer,
|
|
|
|
route_set_ipv6_nexthop_peer_compile,
|
|
|
|
route_set_ipv6_nexthop_peer_free
|
|
|
|
};
|
2015-05-20 02:24:45 +02:00
|
|
|
|
2017-07-12 20:02:33 +02:00
|
|
|
/* `set ipv4 vpn next-hop A.B.C.D' */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_vpnv4_nexthop(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr *address;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
address = rule;
|
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set next hop value. */
|
|
|
|
path->attr->mp_nexthop_global_in = *address;
|
|
|
|
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
bgpd: Allow overriding MPLS VPN next-hops via route-maps
Just do not reset next-hop for MPLS VPN routes.
Example of 172.16.255.1/32 (using extended next-hop capability):
```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
*>i10.0.0.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i172.16.255.1/32 2001:db8::1 0 100 0 65000 ?
UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.1.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.2.0/24 2001:db8:1::1 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
*> 10.0.0.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 172.16.255.1/32 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.1.0/24 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.2.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
Displayed 8 routes and 8 total paths
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-11-18 14:47:50 +01:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags, BATTR_RMAP_VPNV4_NHOP_CHANGED);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_vpnv4_nexthop_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in_addr *address;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in_addr));
|
|
|
|
|
|
|
|
ret = inet_aton(arg, address);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2017-07-12 20:02:33 +02:00
|
|
|
/* `set ipv6 vpn next-hop A.B.C.D' */
|
2017-01-18 12:27:52 +01:00
|
|
|
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_vpnv6_nexthop(void *rule, const struct prefix *prefix, void *object)
|
2017-01-18 12:27:52 +01:00
|
|
|
{
|
|
|
|
struct in6_addr *address;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2017-01-18 12:27:52 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Fetch routemap's rule information. */
|
|
|
|
address = rule;
|
|
|
|
path = object;
|
2017-01-18 12:27:52 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
/* Set next hop value. */
|
|
|
|
memcpy(&path->attr->mp_nexthop_global, address,
|
|
|
|
sizeof(struct in6_addr));
|
|
|
|
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL;
|
2017-01-18 12:27:52 +01:00
|
|
|
|
bgpd: Allow overriding MPLS VPN next-hops via route-maps
Just do not reset next-hop for MPLS VPN routes.
Example of 172.16.255.1/32 (using extended next-hop capability):
```
pe2# sh bgp ipv4 vpn
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 192.168.1.2:2
*>i10.0.0.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i172.16.255.1/32 2001:db8::1 0 100 0 65000 ?
UN=2001:db8::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.1.0/24 2001:db8:1::1 0 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
*>i192.168.2.0/24 2001:db8:1::1 100 0 65000 ?
UN=2001:db8:1::1 EC{192.168.1.2:2} label=1111 type=bgp, subtype=0
Route Distinguisher: 192.168.2.2:2
*> 10.0.0.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 172.16.255.1/32 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.1.0/24 192.168.2.1@4< 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
*> 192.168.2.0/24 192.168.2.1@4< 0 50 0 65000 ?
UN=192.168.2.1 EC{192.168.2.2:2} label=2222 type=bgp, subtype=5
Displayed 8 routes and 8 total paths
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-11-18 14:47:50 +01:00
|
|
|
SET_FLAG(path->attr->rmap_change_flags,
|
|
|
|
BATTR_RMAP_VPNV6_GLOBAL_NHOP_CHANGED);
|
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_set_vpnv6_nexthop_compile(const char *arg)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in6_addr *address;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
|
|
|
|
ret = inet_pton(AF_INET6, arg, address);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void route_set_vpn_nexthop_free(void *rule)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2017-07-12 20:02:33 +02:00
|
|
|
/* Route map commands for ipv4 next-hop set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd = {
|
|
|
|
"ipv4 vpn next-hop",
|
|
|
|
route_set_vpnv4_nexthop,
|
|
|
|
route_set_vpnv4_nexthop_compile,
|
|
|
|
route_set_vpn_nexthop_free
|
|
|
|
};
|
2017-01-18 12:27:52 +01:00
|
|
|
|
2017-07-12 20:02:33 +02:00
|
|
|
/* Route map commands for ipv6 next-hop set. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_vpnv6_nexthop_cmd = {
|
|
|
|
"ipv6 vpn next-hop",
|
|
|
|
route_set_vpnv6_nexthop,
|
|
|
|
route_set_vpnv6_nexthop_compile,
|
|
|
|
route_set_vpn_nexthop_free
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* `set originator-id' */
|
|
|
|
|
|
|
|
/* For origin set. */
|
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP
Traditionally route map MATCH rule apis were designed to return
a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH.
(Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR).
Depending on this response, the following statemachine decided the
course of action:
State1:
If match cmd returns RMAP_MATCH then, keep existing behaviour.
If routemap type is PERMIT, execute set cmds or call cmds if applicable,
otherwise PERMIT!
Else If routemap type is DENY, we DENYMATCH right away
State2:
If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there
are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH
We require a 3rd state because of the following situation:
The issue - what if, the rule api needs to abort or ignore a rule?:
"match evpn vni xx" route-map filter can be applied to incoming routes
regardless of whether the tunnel type is vxlan or mpls.
This rule should be N/A for mpls based evpn route, but applicable to only
vxlan based evpn route.
Also, this rule should be applicable for routes with VNI label only, and
not for routes without labels. For example, type 3 and type 4 EVPN routes
do not have labels, so, this match cmd should let them through.
Today, the filter produces either a match or nomatch response regardless of
whether it is mpls/vxlan, resulting in either permitting or denying the
route.. So an mpls evpn route may get filtered out incorrectly.
Eg: "route-map RM1 permit 10 ; match evpn vni 20" or
"route-map RM2 deny 20 ; match vni 20"
With the introduction of the 3rd state, we can abort this rule check safely.
How? The rules api can now return RMAP_NOOP to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
As a result we have a 3rd state:
State3:
If match cmd returned RMAP_NOOP
Then, proceed to other route-map, otherwise if there are no more
rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH.
Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
|
|
|
static enum route_map_cmd_result_t
|
2020-11-14 01:35:20 +01:00
|
|
|
route_set_originator_id(void *rule, const struct prefix *prefix, void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr *address;
|
2018-10-03 00:34:03 +02:00
|
|
|
struct bgp_path_info *path;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
address = rule;
|
|
|
|
path = object;
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-11-14 01:35:20 +01:00
|
|
|
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID);
|
|
|
|
path->attr->originator_id = *address;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return RMAP_OKAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for originator-id set. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static void *route_set_originator_id_compile(const char *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct in_addr *address;
|
|
|
|
|
|
|
|
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in_addr));
|
|
|
|
|
|
|
|
ret = inet_aton(arg, address);
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compile function for originator_id set. */
|
|
|
|
static void route_set_originator_id_free(void *rule)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
|
|
|
}
|
|
|
|
|
2014-05-20 07:57:26 +02:00
|
|
|
/* Set originator-id rule structure. */
|
2019-11-20 17:20:58 +01:00
|
|
|
static const struct route_map_rule_cmd route_set_originator_id_cmd = {
|
|
|
|
"originator-id",
|
|
|
|
route_set_originator_id,
|
|
|
|
route_set_originator_id_compile,
|
|
|
|
route_set_originator_id_free,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2022-08-31 22:00:26 +02:00
|
|
|
static enum route_map_cmd_result_t
|
|
|
|
route_match_rpki_extcommunity(void *rule, const struct prefix *prefix,
|
|
|
|
void *object)
|
|
|
|
{
|
|
|
|
struct bgp_path_info *path;
|
|
|
|
struct ecommunity *ecomm;
|
|
|
|
struct ecommunity_val *ecomm_val;
|
|
|
|
enum rpki_states *rpki_status = rule;
|
|
|
|
enum rpki_states ecomm_rpki_status = RPKI_NOT_BEING_USED;
|
|
|
|
|
|
|
|
path = object;
|
|
|
|
|
|
|
|
ecomm = bgp_attr_get_ecommunity(path->attr);
|
|
|
|
if (!ecomm)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
|
|
|
ecomm_val = ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS,
|
|
|
|
ECOMMUNITY_ORIGIN_VALIDATION_STATE);
|
|
|
|
if (!ecomm_val)
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
|
|
|
|
/* The Origin Validation State is encoded in the last octet of
|
|
|
|
* the extended community.
|
|
|
|
*/
|
|
|
|
switch (ecomm_val->val[7]) {
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID:
|
|
|
|
ecomm_rpki_status = RPKI_VALID;
|
|
|
|
break;
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND:
|
|
|
|
ecomm_rpki_status = RPKI_NOTFOUND;
|
|
|
|
break;
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID:
|
|
|
|
ecomm_rpki_status = RPKI_INVALID;
|
|
|
|
break;
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ecomm_rpki_status == *rpki_status)
|
|
|
|
return RMAP_MATCH;
|
|
|
|
|
|
|
|
return RMAP_NOMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *route_match_extcommunity_compile(const char *arg)
|
|
|
|
{
|
|
|
|
int *rpki_status;
|
|
|
|
|
|
|
|
rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int));
|
|
|
|
|
|
|
|
if (strcmp(arg, "valid") == 0)
|
|
|
|
*rpki_status = RPKI_VALID;
|
|
|
|
else if (strcmp(arg, "invalid") == 0)
|
|
|
|
*rpki_status = RPKI_INVALID;
|
|
|
|
else
|
|
|
|
*rpki_status = RPKI_NOTFOUND;
|
|
|
|
|
|
|
|
return rpki_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct route_map_rule_cmd route_match_rpki_extcommunity_cmd = {
|
|
|
|
"rpki-extcommunity",
|
|
|
|
route_match_rpki_extcommunity,
|
|
|
|
route_match_extcommunity_compile,
|
|
|
|
route_value_free
|
|
|
|
};
|
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
/*
|
2015-11-10 16:29:12 +01:00
|
|
|
* This is the workhorse routine for processing in/out routemap
|
2015-05-20 02:40:45 +02:00
|
|
|
* modifications.
|
|
|
|
*/
|
2015-10-28 20:12:24 +01:00
|
|
|
static void bgp_route_map_process_peer(const char *rmap_name,
|
|
|
|
struct route_map *map, struct peer *peer,
|
|
|
|
int afi, int safi, int route_update)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct bgp_filter *filter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
if (!peer || !rmap_name)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
filter = &peer->filter[afi][safi];
|
|
|
|
/*
|
|
|
|
* in is for non-route-server clients,
|
|
|
|
* out is for all peers
|
|
|
|
*/
|
2019-05-17 13:29:47 +02:00
|
|
|
if (filter->map[RMAP_IN].name
|
|
|
|
&& (strcmp(rmap_name, filter->map[RMAP_IN].name) == 0)) {
|
|
|
|
filter->map[RMAP_IN].map = map;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-08-27 00:11:07 +02:00
|
|
|
if (route_update && peer_established(peer->connection)) {
|
2015-05-20 02:40:45 +02:00
|
|
|
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
|
|
|
PEER_FLAG_SOFT_RECONFIG)) {
|
2015-05-20 03:03:47 +02:00
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 1))
|
2015-05-20 02:40:45 +02:00
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on peer %s (inbound, soft-reconfig)",
|
|
|
|
rmap_name, afi2str(afi),
|
|
|
|
safi2str(safi), peer->host);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
bgp_soft_reconfig_in(peer, afi, safi);
|
2023-07-07 15:01:19 +02:00
|
|
|
} else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_RCV)) {
|
2015-10-28 20:12:24 +01:00
|
|
|
if (bgp_debug_update(peer, NULL, NULL, 1))
|
2015-05-20 02:40:45 +02:00
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on peer %s (inbound, route-refresh)",
|
|
|
|
rmap_name, afi2str(afi),
|
|
|
|
safi2str(safi), peer->host);
|
2020-10-01 22:08:06 +02:00
|
|
|
bgp_route_refresh_send(
|
|
|
|
peer, afi, safi, 0, 0, 0,
|
|
|
|
BGP_ROUTE_REFRESH_NORMAL);
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
/*
|
2015-05-20 03:03:47 +02:00
|
|
|
* For outbound, unsuppress and default-originate map change (content or
|
|
|
|
* map created), merely update the "config" here, the actual route
|
|
|
|
* announcement happens at the group level.
|
2017-07-17 14:03:14 +02:00
|
|
|
*/
|
2015-05-20 02:40:45 +02:00
|
|
|
if (filter->map[RMAP_OUT].name
|
2015-05-20 03:03:47 +02:00
|
|
|
&& (strcmp(rmap_name, filter->map[RMAP_OUT].name) == 0))
|
2015-10-28 20:12:24 +01:00
|
|
|
filter->map[RMAP_OUT].map = map;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
if (filter->usmap.name && (strcmp(rmap_name, filter->usmap.name) == 0))
|
2015-10-28 20:12:24 +01:00
|
|
|
filter->usmap.map = map;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
bgpd: conditional advertisement
Implemented as per the feature description given in the source link.
Descriprion:
The BGP conditional advertisement feature uses the non-exist-map or exist-map
and the advertise-map keywords of the neighbor advertise-map command in order
to track routes by the route prefix.
non-exist-map :
If a route prefix is not present in output of the non-exist-map command, then
the route specified by the advertise-map command is announced.
exist-map :
If a route prefix is present in output of the exist-map command, then the route
specified by the advertise-map command is announced.
The conditional BGP announcements are sent in addition to the normal
announcements that a BGP router sends to its peers.
The conditional advertisement process is triggered by the BGP scanner process,
which runs every 60 seconds. This means that the maximum time for the conditional
advertisement to take effect is 60 seconds. The conditional advertisement can take
effect sooner, depending on when the tracked route is removed from the BGP table
and when the next instance of the BGP scanner occurs.
Sample Configuration on DUT
---------------------------
Router2# show running-config
Building configuration...
Current configuration:
!
frr version 7.6-dev-MyOwnFRRVersion
frr defaults traditional
hostname router
log file /var/log/frr/bgpd.log
log syslog informational
hostname Router2
service integrated-vtysh-config
!
debug bgp updates in
debug bgp updates out
!
debug route-map
!
ip route 200.200.0.0/16 blackhole
ipv6 route 2001:db8::200/128 blackhole
!
interface enp0s9
ip address 10.10.10.2/24
!
interface enp0s10
ip address 10.10.20.2/24
!
interface lo
ip address 2.2.2.2/24
ipv6 address 2001:db8::2/128
!
router bgp 2
bgp log-neighbor-changes
no bgp ebgp-requires-policy
neighbor 10.10.10.1 remote-as 1
neighbor 10.10.20.3 remote-as 3
!
address-family ipv4 unicast
network 2.2.2.0/24
network 200.200.0.0/16
neighbor 10.10.10.1 soft-reconfiguration inbound
neighbor 10.10.10.1 advertise-map ADVERTISE non-exist-map CONDITION
neighbor 10.10.20.3 soft-reconfiguration inbound
exit-address-family
!
address-family ipv6 unicast
network 2001:db8::2/128
network 2001:db8::200/128
neighbor 10.10.10.1 activate
neighbor 10.10.10.1 soft-reconfiguration inbound
neighbor 10.10.10.1 advertise-map ADVERTISE_6 non-exist-map CONDITION_6
neighbor 10.10.20.3 activate
neighbor 10.10.20.3 soft-reconfiguration inbound
exit-address-family
!
access-list CONDITION seq 5 permit 3.3.3.0/24
access-list ADVERTISE seq 5 permit 2.2.2.0/24
access-list ADVERTISE seq 6 permit 200.200.0.0/16
access-list ADVERTISE seq 7 permit 20.20.0.0/16
!
ipv6 access-list ADVERTISE_6 seq 5 permit 2001:db8::2/128
ipv6 access-list CONDITION_6 seq 5 permit 2001:db8::3/128
!
route-map ADVERTISE permit 10
match ip address ADVERTISE
!
route-map CONDITION permit 10
match ip address CONDITION
!
route-map ADVERTISE_6 permit 10
match ipv6 address ADVERTISE_6
!
route-map CONDITION_6 permit 10
match ipv6 address CONDITION_6
!
line vty
!
end
Router2#
Withdraw when non-exist-map prefixes present in BGP table:
----------------------------------------------------------
Router2# show ip bgp all wide
For address family: IPv4 Unicast
BGP table version is 8, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.0/24 10.10.10.1 0 0 1 i
*> 2.2.2.0/24 0.0.0.0 0 32768 i
*> 3.3.3.0/24 10.10.20.3 0 0 3 i
*> 200.200.0.0/16 0.0.0.0 0 32768 i
Displayed 4 routes and 4 total paths
For address family: IPv6 Unicast
BGP table version is 8, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::1/128 fe80::a00:27ff:fecb:ad57 0 0 1 i
*> 2001:db8::2/128 :: 0 32768 i
*> 2001:db8::3/128 fe80::a00:27ff:fe76:6738 0 0 3 i
*> 2001:db8::200/128 :: 0 32768 i
Displayed 4 routes and 4 total paths
Router2#
Router2# show ip bgp neighbors 10.10.10.1
BGP neighbor is 10.10.10.1, remote AS 1, local AS 2, external link
!--- Output suppressed.
For address family: IPv4 Unicast
Update group 9, subgroup 5
Packet Queue length 0
Inbound soft reconfiguration allowed
Community attribute sent to this neighbor(all)
Condition NON_EXIST, Condition-map *CONDITION, Advertise-map *ADVERTISE, status: Withdraw
1 accepted prefixes
For address family: IPv6 Unicast
Update group 10, subgroup 6
Packet Queue length 0
Inbound soft reconfiguration allowed
Community attribute sent to this neighbor(all)
Condition NON_EXIST, Condition-map *CONDITION_6, Advertise-map *ADVERTISE_6, status: Withdraw
1 accepted prefixes
!--- Output suppressed.
Router2#
Here 2.2.2.0/24 & 200.200.0.0/16 (prefixes in advertise-map) are withdrawn
by conditional advertisement scanner as the prefix(3.3.3.0/24) specified
by non-exist-map is present in BGP table.
Router2# show ip bgp all neighbors 10.10.10.1 advertised-routes wide
For address family: IPv4 Unicast
BGP table version is 8, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.0/24 0.0.0.0 0 1 i
*> 3.3.3.0/24 0.0.0.0 0 3 i
Total number of prefixes 2
For address family: IPv6 Unicast
BGP table version is 8, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::1/128 :: 0 1 i
*> 2001:db8::3/128 :: 0 3 i
*> 2001:db8::200/128 :: 0 32768 i
Total number of prefixes 3
Router2#
Advertise when non-exist-map prefixes not present in BGP table:
---------------------------------------------------------------
After Removing 3.3.3.0/24 (prefix present in non-exist-map),
2.2.2.0/24 & 200.200.0.0/16 (prefixes present in advertise-map) are advertised
Router2# show ip bgp all wide
For address family: IPv4 Unicast
BGP table version is 9, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.0/24 10.10.10.1 0 0 1 i
*> 2.2.2.0/24 0.0.0.0 0 32768 i
*> 200.200.0.0/16 0.0.0.0 0 32768 i
Displayed 3 routes and 3 total paths
For address family: IPv6 Unicast
BGP table version is 9, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::1/128 fe80::a00:27ff:fecb:ad57 0 0 1 i
*> 2001:db8::2/128 :: 0 32768 i
*> 2001:db8::200/128 :: 0 32768 i
Displayed 3 routes and 3 total paths
Router2#
Router2# show ip bgp neighbors 10.10.10.1
!--- Output suppressed.
For address family: IPv4 Unicast
Update group 9, subgroup 5
Packet Queue length 0
Inbound soft reconfiguration allowed
Community attribute sent to this neighbor(all)
Condition NON_EXIST, Condition-map *CONDITION, Advertise-map *ADVERTISE, status: Advertise
1 accepted prefixes
For address family: IPv6 Unicast
Update group 10, subgroup 6
Packet Queue length 0
Inbound soft reconfiguration allowed
Community attribute sent to this neighbor(all)
Condition NON_EXIST, Condition-map *CONDITION_6, Advertise-map *ADVERTISE_6, status: Advertise
1 accepted prefixes
!--- Output suppressed.
Router2#
Router2# show ip bgp all neighbors 10.10.10.1 advertised-routes wide
For address family: IPv4 Unicast
BGP table version is 9, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.0/24 0.0.0.0 0 1 i
*> 2.2.2.0/24 0.0.0.0 0 32768 i
*> 200.200.0.0/16 0.0.0.0 0 32768 i
Total number of prefixes 3
For address family: IPv6 Unicast
BGP table version is 9, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::1/128 :: 0 1 i
*> 2001:db8::2/128 :: 0 32768 i
*> 2001:db8::200/128 :: 0 32768 i
Total number of prefixes 3
Router2#
Signed-off-by: Madhuri Kuruganti <k.madhuri@samsung.com>
2020-09-29 11:46:04 +02:00
|
|
|
if (filter->advmap.aname
|
|
|
|
&& (strcmp(rmap_name, filter->advmap.aname) == 0)) {
|
|
|
|
filter->advmap.amap = map;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filter->advmap.cname
|
|
|
|
&& (strcmp(rmap_name, filter->advmap.cname) == 0)) {
|
|
|
|
filter->advmap.cmap = map;
|
|
|
|
}
|
|
|
|
|
2015-10-28 20:12:24 +01:00
|
|
|
if (peer->default_rmap[afi][safi].name
|
2015-05-20 02:40:45 +02:00
|
|
|
&& (strcmp(rmap_name, peer->default_rmap[afi][safi].name) == 0))
|
2015-10-28 20:12:24 +01:00
|
|
|
peer->default_rmap[afi][safi].map = map;
|
bgpd: conditional advertisement - with route-map filter
Sample configuration along with route-map filter
------------------------------------------------
Router2# show running-config
Building configuration...
Current configuration:
!
frr version 7.6-dev-MyOwnFRRVersion
frr defaults traditional
hostname router
log file /var/log/frr/bgpd.log
log syslog informational
hostname Router2
service integrated-vtysh-config
!
debug bgp updates in
debug bgp updates out
!
debug route-map
!
ip route 200.200.0.0/16 blackhole
ipv6 route 2001:db8::200/128 blackhole
!
interface enp0s9
ip address 10.10.10.2/24
!
interface enp0s10
ip address 10.10.20.2/24
!
interface lo
ip address 2.2.2.2/24
ipv6 address 2001:db8::2/128
!
router bgp 2
bgp log-neighbor-changes
no bgp ebgp-requires-policy
neighbor 10.10.10.1 remote-as 1
neighbor 10.10.20.3 remote-as 3
!
address-family ipv4 unicast
network 2.2.2.0/24
network 200.200.0.0/16
neighbor 10.10.10.1 soft-reconfiguration inbound
neighbor 10.10.10.1 route-map RMAP_PERMIT_100 out
neighbor 10.10.10.1 advertise-map ADVERTISE non-exist-map CONDITION
neighbor 10.10.20.3 soft-reconfiguration inbound
exit-address-family
!
address-family ipv6 unicast
network 2001:db8::2/128
network 2001:db8::200/128
neighbor 10.10.10.1 activate
neighbor 10.10.10.1 soft-reconfiguration inbound
neighbor 10.10.10.1 route-map CONDITION_6 out
neighbor 10.10.10.1 advertise-map ADVERTISE_6 non-exist-map CONDITION_6
neighbor 10.10.20.3 activate
neighbor 10.10.20.3 soft-reconfiguration inbound
exit-address-family
!
access-list CONDITION seq 5 permit 3.3.3.0/24
access-list ADVERTISE seq 6 permit 200.200.0.0/16
access-list ADVERTISE seq 7 permit 20.20.0.0/16
access-list ADVERTISE seq 5 permit 2.2.2.0/24
access-list RMAP_PERMIT_100 seq 4 permit 100.100.0.0/16
!
ipv6 access-list ADVERTISE_6 seq 5 permit 2001:db8::2/128
ipv6 access-list CONDITION_6 seq 5 permit 2001:db8::3/128
!
route-map ADVERTISE permit 10
match ip address ADVERTISE
!
route-map CONDITION permit 10
match ip address CONDITION
!
route-map ADVERTISE_6 permit 10
match ipv6 address ADVERTISE_6
!
route-map CONDITION_6 permit 10
match ipv6 address CONDITION_6
!
route-map RMAP_PERMIT_100 permit 10
match ip address RMAP_PERMIT_100
!
line vty
!
end
Sample output when non-exist-map prefixes present in BGP table
--------------------------------------------------------------
Router2# show ip bgp all wide
For address family: IPv4 Unicast
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.0/24 10.10.10.1 0 0 1 i
*> 2.2.2.0/24 0.0.0.0 0 32768 i
*> 3.3.3.0/24 10.10.20.3 0 0 3 i
*> 100.100.0.0/16 10.10.20.3 0 0 3 i
*> 200.200.0.0/16 0.0.0.0 0 32768 i
Displayed 5 routes and 5 total paths
For address family: IPv6 Unicast
BGP table version is 4, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::1/128 fe80::a00:27ff:fecb:ad57 0 0 1 i
*> 2001:db8::2/128 :: 0 32768 i
*> 2001:db8::3/128 fe80::a00:27ff:fe76:6738 0 0 3 i
*> 2001:db8::200/128 :: 0 32768 i
Displayed 4 routes and 4 total paths
Router2#
Router2#
Router2#
Router2#
Router2# show ip bgp all neighbors 10.10.10.1 advertised-routes wide
For address family: IPv4 Unicast
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 100.100.0.0/16 0.0.0.0 0 3 i
Total number of prefixes 1
For address family: IPv6 Unicast
BGP table version is 4, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::3/128 :: 0 3 i
Total number of prefixes 1
Router2#
Sample output when non-exist-map prefixes not present in BGP table
------------------------------------------------------------------
Router2# show ip bgp all wide
For address family: IPv4 Unicast
BGP table version is 6, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.0/24 10.10.10.1 0 0 1 i
*> 2.2.2.0/24 0.0.0.0 0 32768 i
*> 100.100.0.0/16 10.10.20.3 0 0 3 i
*> 200.200.0.0/16 0.0.0.0 0 32768 i
Displayed 4 routes and 4 total paths
For address family: IPv6 Unicast
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::1/128 fe80::a00:27ff:fecb:ad57 0 0 1 i
*> 2001:db8::2/128 :: 0 32768 i
*> 2001:db8::200/128 :: 0 32768 i
Displayed 3 routes and 3 total paths
Router2#
Router2# show ip bgp all neighbors 10.10.10.1 advertised-routes wide
For address family: IPv4 Unicast
BGP table version is 6, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2.2.2.0/24 0.0.0.0 0 32768 i
*> 100.100.0.0/16 0.0.0.0 0 3 i
*> 200.200.0.0/16 0.0.0.0 0 32768 i
Total number of prefixes 3
For address family: IPv6 Unicast
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 2001:db8::2/128 :: 0 32768 i
Total number of prefixes 1
Router2#
Signed-off-by: Madhuri Kuruganti <k.madhuri@samsung.com>
2020-10-01 22:40:48 +02:00
|
|
|
|
|
|
|
/* Notify BGP conditional advertisement scanner percess */
|
bgpd: conditional advertisement - other match rules support
Sample Configuration with prefix-list and community match rules
---------------------------------------------------------------
R1 ------- R2(DUT) ------- R3
Router2# show running-config
Building configuration...
Current configuration:
!
frr version 7.6-dev-MyOwnFRRVersion
frr defaults traditional
hostname router
log file /var/log/frr/bgpd.log
log syslog informational
hostname Router2
service integrated-vtysh-config
!
debug bgp updates in
debug bgp updates out
!
debug route-map
!
ip route 20.20.0.0/16 blackhole
ipv6 route 2001:db8::200/128 blackhole
!
interface enp0s9
ip address 10.10.10.2/24
!
interface enp0s10
ip address 10.10.20.2/24
!
interface lo
ip address 2.2.2.2/32
!
router bgp 2
bgp log-neighbor-changes
no bgp ebgp-requires-policy
neighbor 10.10.10.1 remote-as 1
neighbor 10.10.20.3 remote-as 3
!
address-family ipv4 unicast
neighbor 10.10.10.1 soft-reconfiguration inbound
neighbor 10.10.20.3 soft-reconfiguration inbound
neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP
exit-address-family
!
ip prefix-list DEFAULT seq 5 permit 1.1.1.5/32
ip prefix-list DEFAULT seq 10 permit 1.1.1.1/32
ip prefix-list EXIST seq 5 permit 10.10.10.10/32
ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0
ip prefix-list IP1 seq 5 permit 10.139.224.0/20
ip prefix-list T2 seq 5 permit 1.1.1.5/32
!
bgp community-list standard DC-ROUTES seq 5 permit 64952:3008
bgp community-list standard DC-ROUTES seq 10 permit 64671:501
bgp community-list standard DC-ROUTES seq 15 permit 64950:3009
bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200
!
route-map ADV-MAP permit 10
match ip address prefix-list IP1
!
route-map ADV-MAP permit 20
match community DC-ROUTES
!
route-map EXIST-MAP permit 10
match community DEFAULT-ROUTE
match ip address prefix-list DEFAULT-ROUTE
!
line vty
!
end
Router2#
Router2# show ip bgp 0.0.0.0
BGP routing table entry for 0.0.0.0/0
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
10.10.10.1 10.10.20.3
1
10.10.10.1 from 10.10.10.1 (10.139.224.1)
Origin IGP, metric 0, valid, external, best (First path received)
Community: 64848:3011 65011:200 65013:200
Last update: Tue Oct 6 02:39:42 2020
Router2#
Sample output with non-exist-map when default route present in table
--------------------------------------------------------------------
Router2# show ip bgp
BGP table version is 4, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0/0 10.10.10.1 0 0 1 i
*> 1.1.1.1/32 10.10.10.1 0 0 1 i
*> 1.1.1.5/32 10.10.10.1 0 0 1 i
*> 10.139.224.0/20 10.10.10.1 0 0 1 ?
Displayed 4 routes and 4 total paths
Router2# show ip bgp neighbors 10.10.20.3 advertised-routes
BGP table version is 4, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0/0 0.0.0.0 0 1 i
*> 1.1.1.5/32 0.0.0.0 0 1 i <<<<<<<<< non-exist-map : 0.0.0.0/0 is present so, 10.139.224.0/20 not advertised
Total number of prefixes 2
Sample output with non-exist-map when default route not present in table
------------------------------------------------------------------------
Router2# show ip bgp
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 10.10.10.1 0 0 1 i
*> 1.1.1.5/32 10.10.10.1 0 0 1 i
*> 10.139.224.0/20 10.10.10.1 0 0 1 ?
Displayed 3 routes and 3 total paths
Router2#
Router2#
Router2# show ip bgp neighbors 10.10.20.3 advertised-routes
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 0.0.0.0 0 1 i
*> 1.1.1.5/32 0.0.0.0 0 1 i
*> 10.139.224.0/20 0.0.0.0 0 1 ? <<<<<<<<< non-exist-map : 0.0.0.0/0 is not present so, 10.139.224.0/20 advertised
Total number of prefixes 3
Router2#
Sample output with exist-map when default route present in table
--------------------------------------------------------------------
Router2# show ip bgp
BGP table version is 8, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0/0 10.10.10.1 0 0 1 i
*> 1.1.1.1/32 10.10.10.1 0 0 1 i
*> 1.1.1.5/32 10.10.10.1 0 0 1 i
*> 10.139.224.0/20 10.10.10.1 0 0 1 ?
Displayed 4 routes and 4 total paths
Router2#
Router2#
Router2#
Router2#
Router2# show ip bgp neighbors 10.10.20.3 advertised-routes
BGP table version is 8, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0/0 0.0.0.0 0 1 i
*> 1.1.1.1/32 0.0.0.0 0 1 i
*> 1.1.1.5/32 0.0.0.0 0 1 i
*> 10.139.224.0/20 0.0.0.0 0 1 ? <<<<<<<<< exist-map : 0.0.0.0/0 is present so, 10.139.224.0/20 advertised
Total number of prefixes 4
Router2#
Sample output with exist-map when default route not present in table
--------------------------------------------------------------------
Router2# show ip bgp
BGP table version is 9, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 10.10.10.1 0 0 1 i
*> 1.1.1.5/32 10.10.10.1 0 0 1 i
*> 10.139.224.0/20 10.10.10.1 0 0 1 ?
Displayed 3 routes and 3 total paths
Router2#
Router2#
Router2#
Router2# show ip bgp neighbors 10.10.20.3 advertised-routes
BGP table version is 9, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 2
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.5/32 0.0.0.0 0 1 i <<<<<<<<< exist-map : 0.0.0.0/0 is not present so, 10.139.224.0/20 not advertised
Total number of prefixes 1
Router2#
Signed-off-by: Madhuri Kuruganti <k.madhuri@samsung.com>
2020-10-05 19:40:56 +02:00
|
|
|
peer->advmap_config_change[afi][safi] = true;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2016-03-22 18:46:30 +01:00
|
|
|
static void bgp_route_map_update_peer_group(const char *rmap_name,
|
|
|
|
struct route_map *map,
|
2015-10-28 20:12:24 +01:00
|
|
|
struct bgp *bgp)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2015-05-20 02:40:45 +02:00
|
|
|
struct peer_group *group;
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct bgp_filter *filter;
|
|
|
|
int afi, safi;
|
|
|
|
int direct;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
if (!bgp)
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
/* All the peers have been updated correctly already. This is
|
|
|
|
* just updating the placeholder data. No real update required.
|
2017-07-17 14:03:14 +02:00
|
|
|
*/
|
2017-11-21 19:02:06 +01:00
|
|
|
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
|
|
|
|
FOREACH_AFI_SAFI (afi, safi) {
|
|
|
|
filter = &group->conf->filter[afi][safi];
|
|
|
|
|
|
|
|
for (direct = RMAP_IN; direct < RMAP_MAX; direct++) {
|
|
|
|
if ((filter->map[direct].name)
|
|
|
|
&& (strcmp(rmap_name,
|
|
|
|
filter->map[direct].name)
|
2017-07-17 14:03:14 +02:00
|
|
|
== 0))
|
2017-11-21 19:02:06 +01:00
|
|
|
filter->map[direct].map = map;
|
2024-03-15 12:49:06 +01:00
|
|
|
|
|
|
|
if (group->conf->default_rmap[afi][safi].name &&
|
|
|
|
strmatch(group->conf->default_rmap[afi][safi]
|
|
|
|
.name,
|
|
|
|
rmap_name))
|
|
|
|
group->conf->default_rmap[afi][safi].map =
|
|
|
|
map;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2017-11-21 19:02:06 +01:00
|
|
|
|
|
|
|
if (filter->usmap.name
|
|
|
|
&& (strcmp(rmap_name, filter->usmap.name) == 0))
|
|
|
|
filter->usmap.map = map;
|
2022-04-07 22:01:02 +02:00
|
|
|
|
|
|
|
if (filter->advmap.aname &&
|
|
|
|
(strcmp(rmap_name, filter->advmap.aname) == 0))
|
|
|
|
filter->advmap.amap = map;
|
|
|
|
|
|
|
|
if (filter->advmap.cname &&
|
|
|
|
(strcmp(rmap_name, filter->advmap.cname) == 0))
|
|
|
|
filter->advmap.cmap = map;
|
2017-11-21 19:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
|
|
|
|
2015-10-28 20:12:24 +01:00
|
|
|
/*
|
|
|
|
* Note that if an extreme number (tens of thousands) of route-maps are in use
|
|
|
|
* and if bgp has an extreme number of peers, network statements, etc then this
|
|
|
|
* function can consume a lot of cycles. This is due to this function being
|
|
|
|
* called for each route-map and within this function we walk the list of peers,
|
|
|
|
* network statements, etc looking to see if they use this route-map.
|
|
|
|
*/
|
2016-03-22 18:46:30 +01:00
|
|
|
static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
|
2022-08-05 14:06:00 +02:00
|
|
|
bool route_update)
|
2015-05-20 02:40:45 +02:00
|
|
|
{
|
|
|
|
int i;
|
2020-10-22 02:22:04 +02:00
|
|
|
bool matched;
|
2015-05-20 02:40:45 +02:00
|
|
|
afi_t afi;
|
|
|
|
safi_t safi;
|
|
|
|
struct peer *peer;
|
2020-03-27 00:11:58 +01:00
|
|
|
struct bgp_dest *bn;
|
2015-05-20 02:40:45 +02:00
|
|
|
struct bgp_static *bgp_static;
|
2019-08-21 17:16:05 +02:00
|
|
|
struct bgp_aggregate *aggregate;
|
2015-05-20 02:40:45 +02:00
|
|
|
struct listnode *node, *nnode;
|
2015-10-28 20:12:24 +01:00
|
|
|
struct route_map *map;
|
2015-05-20 02:40:45 +02:00
|
|
|
char buf[INET6_ADDRSTRLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-10-28 20:12:24 +01:00
|
|
|
map = route_map_lookup_by_name(rmap_name);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
/* Ignore dummy peer-group structure */
|
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 19:02:06 +01:00
|
|
|
FOREACH_AFI_SAFI (afi, safi) {
|
|
|
|
/* process in/out/import/export/default-orig
|
|
|
|
* route-maps */
|
|
|
|
bgp_route_map_process_peer(rmap_name, map, peer, afi,
|
|
|
|
safi, route_update);
|
|
|
|
}
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* for outbound/default-orig route-maps, process for groups */
|
|
|
|
update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP, rmap_name,
|
|
|
|
route_update, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:03:47 +02:00
|
|
|
/* update peer-group config (template) */
|
2015-10-28 20:12:24 +01:00
|
|
|
bgp_route_map_update_peer_group(rmap_name, map, bgp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 19:02:06 +01:00
|
|
|
FOREACH_AFI_SAFI (afi, safi) {
|
|
|
|
/* For table route-map updates. */
|
|
|
|
if (!bgp_fibupd_safi(safi))
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 19:02:06 +01:00
|
|
|
if (bgp->table_map[afi][safi].name
|
|
|
|
&& (strcmp(rmap_name, bgp->table_map[afi][safi].name)
|
|
|
|
== 0)) {
|
2019-02-04 14:27:56 +01:00
|
|
|
|
|
|
|
/* bgp->table_map[afi][safi].map is NULL.
|
|
|
|
* i.e Route map creation event.
|
|
|
|
* So update applied_counter.
|
|
|
|
* If it is not NULL, i.e It may be routemap updation or
|
|
|
|
* deletion. so no need to update the counter.
|
|
|
|
*/
|
|
|
|
if (!bgp->table_map[afi][safi].map)
|
|
|
|
route_map_counter_increment(map);
|
2017-11-21 19:02:06 +01:00
|
|
|
bgp->table_map[afi][safi].map = map;
|
|
|
|
|
|
|
|
if (BGP_DEBUG(zebra, ZEBRA))
|
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on table map",
|
|
|
|
rmap_name, afi2str(afi),
|
|
|
|
safi2str(safi));
|
2017-11-21 19:02:06 +01:00
|
|
|
if (route_update)
|
|
|
|
bgp_zebra_announce_table(bgp, afi, safi);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 19:02:06 +01:00
|
|
|
/* For network route-map updates. */
|
|
|
|
for (bn = bgp_table_top(bgp->route[afi][safi]); bn;
|
2018-09-26 13:51:49 +02:00
|
|
|
bn = bgp_route_next(bn)) {
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_static = bgp_dest_get_bgp_static_info(bn);
|
2018-10-12 14:44:15 +02:00
|
|
|
if (!bgp_static)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!bgp_static->rmap.name
|
|
|
|
|| (strcmp(rmap_name, bgp_static->rmap.name) != 0))
|
|
|
|
continue;
|
|
|
|
|
2019-02-04 14:27:56 +01:00
|
|
|
if (!bgp_static->rmap.map)
|
|
|
|
route_map_counter_increment(map);
|
|
|
|
|
2018-10-12 14:44:15 +02:00
|
|
|
bgp_static->rmap.map = map;
|
|
|
|
|
|
|
|
if (route_update && !bgp_static->backdoor) {
|
2020-03-22 05:02:18 +01:00
|
|
|
const struct prefix *bn_p =
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_dest_get_prefix(bn);
|
2020-03-22 05:02:18 +01:00
|
|
|
|
|
|
|
if (bgp_debug_zebra(bn_p))
|
2018-10-12 14:44:15 +02:00
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on static route %s",
|
|
|
|
rmap_name, afi2str(afi),
|
|
|
|
safi2str(safi),
|
2020-03-22 05:02:18 +01:00
|
|
|
inet_ntop(bn_p->family,
|
|
|
|
&bn_p->u.prefix, buf,
|
2022-11-29 09:23:20 +01:00
|
|
|
sizeof(buf)));
|
2020-03-22 05:02:18 +01:00
|
|
|
bgp_static_update(bgp, bn_p, bgp_static, afi,
|
2018-10-12 14:44:15 +02:00
|
|
|
safi);
|
2017-11-21 19:02:06 +01:00
|
|
|
}
|
2018-09-26 13:51:49 +02:00
|
|
|
}
|
2019-08-21 17:16:05 +02:00
|
|
|
|
|
|
|
/* For aggregate-address route-map updates. */
|
|
|
|
for (bn = bgp_table_top(bgp->aggregate[afi][safi]); bn;
|
|
|
|
bn = bgp_route_next(bn)) {
|
2020-03-27 00:11:58 +01:00
|
|
|
aggregate = bgp_dest_get_bgp_aggregate_info(bn);
|
2019-08-21 17:16:05 +02:00
|
|
|
if (!aggregate)
|
|
|
|
continue;
|
|
|
|
|
2020-10-22 02:22:04 +02:00
|
|
|
matched = false;
|
2019-08-21 17:16:05 +02:00
|
|
|
|
2020-10-19 00:17:02 +02:00
|
|
|
/* Update suppress map pointer. */
|
|
|
|
if (aggregate->suppress_map_name
|
|
|
|
&& strmatch(aggregate->suppress_map_name,
|
|
|
|
rmap_name)) {
|
2020-10-22 02:22:04 +02:00
|
|
|
if (aggregate->rmap.map == NULL)
|
2020-10-19 00:17:02 +02:00
|
|
|
route_map_counter_increment(map);
|
2019-08-21 17:16:05 +02:00
|
|
|
|
2020-10-19 00:17:02 +02:00
|
|
|
aggregate->suppress_map = map;
|
2020-10-22 02:22:04 +02:00
|
|
|
|
|
|
|
bgp_aggregate_toggle_suppressed(
|
|
|
|
aggregate, bgp, bgp_dest_get_prefix(bn),
|
|
|
|
afi, safi, false);
|
|
|
|
|
|
|
|
matched = true;
|
2020-10-19 00:17:02 +02:00
|
|
|
}
|
|
|
|
|
2020-10-22 02:22:04 +02:00
|
|
|
if (aggregate->rmap.name
|
|
|
|
&& strmatch(rmap_name, aggregate->rmap.name)) {
|
|
|
|
if (aggregate->rmap.map == NULL)
|
|
|
|
route_map_counter_increment(map);
|
2019-08-21 17:16:05 +02:00
|
|
|
|
2020-10-22 02:22:04 +02:00
|
|
|
aggregate->rmap.map = map;
|
2024-01-30 14:44:38 +01:00
|
|
|
aggregate->rmap.changed = true;
|
2019-08-21 17:16:05 +02:00
|
|
|
|
2020-10-22 02:22:04 +02:00
|
|
|
matched = true;
|
|
|
|
}
|
2019-08-21 17:16:05 +02:00
|
|
|
|
2020-10-22 02:22:04 +02:00
|
|
|
if (matched && route_update) {
|
2020-03-22 05:02:18 +01:00
|
|
|
const struct prefix *bn_p =
|
2020-03-27 00:11:58 +01:00
|
|
|
bgp_dest_get_prefix(bn);
|
2020-03-22 05:02:18 +01:00
|
|
|
|
|
|
|
if (bgp_debug_zebra(bn_p))
|
2019-08-21 17:16:05 +02:00
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on aggregate-address route %s",
|
|
|
|
rmap_name, afi2str(afi),
|
|
|
|
safi2str(safi),
|
2020-03-22 05:02:18 +01:00
|
|
|
inet_ntop(bn_p->family,
|
|
|
|
&bn_p->u.prefix, buf,
|
2022-11-29 09:23:20 +01:00
|
|
|
sizeof(buf)));
|
2023-03-13 21:26:09 +01:00
|
|
|
(void)bgp_aggregate_route(bgp, bn_p, afi, safi,
|
|
|
|
aggregate);
|
2019-08-21 17:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
2017-11-21 19:02:06 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* For redistribute route-map updates. */
|
2015-05-20 02:40:45 +02:00
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
struct list *red_list;
|
|
|
|
struct bgp_redist *red;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
red_list = bgp->redist[afi][i];
|
|
|
|
if (!red_list)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
|
2018-10-12 14:44:15 +02:00
|
|
|
if (!red->rmap.name
|
|
|
|
|| (strcmp(rmap_name, red->rmap.name) != 0))
|
|
|
|
continue;
|
|
|
|
|
2019-02-04 14:27:56 +01:00
|
|
|
if (!red->rmap.map)
|
|
|
|
route_map_counter_increment(map);
|
|
|
|
|
2018-10-12 14:44:15 +02:00
|
|
|
red->rmap.map = map;
|
|
|
|
|
|
|
|
if (!route_update)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (BGP_DEBUG(zebra, ZEBRA))
|
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on redistributed routes",
|
|
|
|
rmap_name, afi2str(afi),
|
|
|
|
safi2str(safi));
|
2018-10-12 14:44:15 +02:00
|
|
|
|
|
|
|
bgp_redistribute_resend(bgp, afi, i,
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
red->instance);
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2018-02-09 10:09:20 +01:00
|
|
|
|
|
|
|
/* for type5 command route-maps */
|
|
|
|
FOREACH_AFI_SAFI (afi, safi) {
|
2018-10-12 14:44:15 +02:00
|
|
|
if (!bgp->adv_cmd_rmap[afi][safi].name
|
|
|
|
|| strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name)
|
|
|
|
!= 0)
|
|
|
|
continue;
|
|
|
|
|
2019-01-24 10:43:48 +01:00
|
|
|
/* Make sure the route-map is populated here if not already done */
|
|
|
|
bgp->adv_cmd_rmap[afi][safi].map = map;
|
|
|
|
|
2018-10-12 14:44:15 +02:00
|
|
|
if (BGP_DEBUG(zebra, ZEBRA))
|
|
|
|
zlog_debug(
|
2021-01-21 15:14:27 +01:00
|
|
|
"Processing route_map %s(%s:%s) update on advertise type5 route command",
|
|
|
|
rmap_name, afi2str(afi), safi2str(safi));
|
2019-01-24 10:43:48 +01:00
|
|
|
|
2019-03-05 19:40:26 +01:00
|
|
|
if (route_update && advertise_type5_routes(bgp, afi)) {
|
2019-01-24 10:43:48 +01:00
|
|
|
bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
|
|
|
|
bgp_evpn_advertise_type5_routes(bgp, afi, safi);
|
|
|
|
}
|
2018-02-09 10:09:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 03:18:33 +02:00
|
|
|
static void bgp_route_map_process_update_cb(char *rmap_name)
|
2015-05-20 02:40:45 +02:00
|
|
|
{
|
2016-03-22 18:46:30 +01:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct bgp *bgp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-09 21:52:55 +01:00
|
|
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
|
2022-08-05 14:06:00 +02:00
|
|
|
bgp_route_map_process_update(bgp, rmap_name, true);
|
2016-03-22 18:46:30 +01:00
|
|
|
|
2020-04-01 21:05:26 +02:00
|
|
|
#ifdef ENABLE_BGP_VNC
|
2018-03-09 21:52:55 +01:00
|
|
|
vnc_routemap_update(bgp, __func__);
|
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN
and Encap SAFIs. This code is currently used to support IETF NVO3 style
operation. In NVO3 terminology it provides the Network Virtualization
Authority (NVA) and the ability to import/export IP prefixes and MAC
addresses from Network Virtualization Edges (NVEs). The code supports
per-NVE tables.
The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2
(L2) forwarding information between NVAs and NVEs is referred to as the
Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For
general background on NVO3 and RFP concepts see [1]. For information on
Openflow see [2].
RFPs are integrated with BGP via the RF API contained in the new "rfapi"
BGP sub-directory. Currently, only a simple example RFP is included in
Quagga. Developers may use this example as a starting point to integrate
Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code
also supports the ability import/export of routing information between
VNC and customer edge routers (CEs) operating within a virtual
network. Import/export may take place between BGP views or to the
default zebera VRF.
BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN
information between NVAs. BGP based IP VPN support is defined in
RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659,
BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use
of both the Encapsulation Subsequent Address Family Identifier (SAFI)
and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation
Subsequent Address Family Identifier (SAFI) and the BGP Tunnel
Encapsulation Attribute, are supported. MAC address distribution does
not follow any standard BGB encoding, although it was inspired by the
early IETF EVPN concepts.
The feature is conditionally compiled and disabled by default.
Use the --enable-bgp-vnc configure option to enable.
The majority of this code was authored by G. Paul Ziemba
<paulz@labn.net>.
[1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req
[2] https://www.opennetworking.org/sdn-resources/technical-library
Now includes changes needed to merge with cmaster-next.
2016-05-07 20:18:56 +02:00
|
|
|
#endif
|
2018-03-09 21:52:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vpn_policy_routemap_event(rmap_name);
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
|
|
|
|
2022-03-01 22:18:12 +01:00
|
|
|
void bgp_route_map_update_timer(struct event *thread)
|
2015-05-20 02:40:45 +02:00
|
|
|
{
|
2016-03-22 18:46:30 +01:00
|
|
|
route_map_walk_update_list(bgp_route_map_process_update_cb);
|
2015-05-20 02:40:45 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:12:17 +02:00
|
|
|
static void bgp_route_map_mark_update(const char *rmap_name)
|
2015-05-20 02:40:45 +02:00
|
|
|
{
|
2019-08-11 13:24:15 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct bgp *bgp;
|
|
|
|
|
|
|
|
/* If new update is received before the current timer timed out,
|
|
|
|
* turn it off and start a new timer.
|
|
|
|
*/
|
2022-12-25 16:26:52 +01:00
|
|
|
EVENT_OFF(bm->t_rmap_update);
|
2019-08-11 13:24:15 +02:00
|
|
|
|
|
|
|
/* rmap_update_timer of 0 means don't do route updates */
|
|
|
|
if (bm->rmap_update_timer) {
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(bm->master, bgp_route_map_update_timer, NULL,
|
|
|
|
bm->rmap_update_timer, &bm->t_rmap_update);
|
2019-08-11 13:24:15 +02:00
|
|
|
|
|
|
|
/* Signal the groups that a route-map update event has
|
|
|
|
* started */
|
|
|
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
|
2022-08-05 14:06:00 +02:00
|
|
|
update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP,
|
|
|
|
rmap_name, true, 1);
|
2019-08-11 13:24:15 +02:00
|
|
|
} else {
|
2021-06-10 19:21:51 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
|
2022-08-05 14:06:00 +02:00
|
|
|
bgp_route_map_process_update(bgp, rmap_name, false);
|
2020-04-01 21:05:26 +02:00
|
|
|
#ifdef ENABLE_BGP_VNC
|
2021-06-10 19:21:51 +02:00
|
|
|
vnc_routemap_update(bgp, __func__);
|
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN
and Encap SAFIs. This code is currently used to support IETF NVO3 style
operation. In NVO3 terminology it provides the Network Virtualization
Authority (NVA) and the ability to import/export IP prefixes and MAC
addresses from Network Virtualization Edges (NVEs). The code supports
per-NVE tables.
The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2
(L2) forwarding information between NVAs and NVEs is referred to as the
Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For
general background on NVO3 and RFP concepts see [1]. For information on
Openflow see [2].
RFPs are integrated with BGP via the RF API contained in the new "rfapi"
BGP sub-directory. Currently, only a simple example RFP is included in
Quagga. Developers may use this example as a starting point to integrate
Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code
also supports the ability import/export of routing information between
VNC and customer edge routers (CEs) operating within a virtual
network. Import/export may take place between BGP views or to the
default zebera VRF.
BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN
information between NVAs. BGP based IP VPN support is defined in
RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659,
BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use
of both the Encapsulation Subsequent Address Family Identifier (SAFI)
and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation
Subsequent Address Family Identifier (SAFI) and the BGP Tunnel
Encapsulation Attribute, are supported. MAC address distribution does
not follow any standard BGB encoding, although it was inspired by the
early IETF EVPN concepts.
The feature is conditionally compiled and disabled by default.
Use the --enable-bgp-vnc configure option to enable.
The majority of this code was authored by G. Paul Ziemba
<paulz@labn.net>.
[1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req
[2] https://www.opennetworking.org/sdn-resources/technical-library
Now includes changes needed to merge with cmaster-next.
2016-05-07 20:18:56 +02:00
|
|
|
#endif
|
2021-06-10 19:21:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
vpn_policy_routemap_event(rmap_name);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
static void bgp_route_map_add(const char *rmap_name)
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
{
|
2018-06-20 02:44:15 +02:00
|
|
|
if (route_map_mark_updated(rmap_name) == 0)
|
2015-05-20 02:40:45 +02:00
|
|
|
bgp_route_map_mark_update(rmap_name);
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
}
|
2015-05-20 02:40:45 +02:00
|
|
|
|
|
|
|
static void bgp_route_map_delete(const char *rmap_name)
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
{
|
2018-06-20 02:44:15 +02:00
|
|
|
if (route_map_mark_updated(rmap_name) == 0)
|
2015-05-20 02:40:45 +02:00
|
|
|
bgp_route_map_mark_update(rmap_name);
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
}
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2023-09-28 17:05:43 +02:00
|
|
|
bool bgp_route_map_has_extcommunity_rt(const struct route_map *map)
|
|
|
|
{
|
|
|
|
struct route_map_index *index = NULL;
|
|
|
|
struct route_map_rule *set = NULL;
|
|
|
|
|
|
|
|
assert(map);
|
|
|
|
|
|
|
|
for (index = map->head; index; index = index->next) {
|
|
|
|
for (set = index->set_list.head; set; set = set->next) {
|
|
|
|
if (set->cmd && set->cmd->str &&
|
|
|
|
(strmatch(set->cmd->str, "extcommunity rt") ||
|
|
|
|
strmatch(set->cmd->str, "extended-comm-list")))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-05-09 05:19:55 +02:00
|
|
|
static void bgp_route_map_event(const char *rmap_name)
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
{
|
2018-06-20 02:44:15 +02:00
|
|
|
if (route_map_mark_updated(rmap_name) == 0)
|
2015-05-20 02:40:45 +02:00
|
|
|
bgp_route_map_mark_update(rmap_name);
|
|
|
|
|
|
|
|
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_mac_address,
|
|
|
|
match_mac_address_cmd,
|
2021-10-21 21:52:14 +02:00
|
|
|
"match mac address ACCESSLIST_MAC_NAME",
|
2020-10-30 08:45:43 +01:00
|
|
|
MATCH_STR
|
|
|
|
"mac address\n"
|
|
|
|
"Match address of route\n"
|
|
|
|
"MAC Access-list name\n")
|
2017-06-21 10:02:46 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:mac-address-list']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-06-21 10:02:46 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_mac_address,
|
|
|
|
no_match_mac_address_cmd,
|
2021-10-21 21:52:14 +02:00
|
|
|
"no match mac address ACCESSLIST_MAC_NAME",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"mac\n"
|
|
|
|
"Match address of route\n"
|
|
|
|
"MAC acess-list name\n")
|
2017-06-21 10:02:46 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:mac-address-list']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-06-21 10:02:46 +02:00
|
|
|
}
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
|
2020-10-13 22:12:14 +02:00
|
|
|
/*
|
|
|
|
* Helper to handle the case of the user passing in a number or type string
|
|
|
|
*/
|
|
|
|
static const char *parse_evpn_rt_type(const char *num_rt_type)
|
|
|
|
{
|
|
|
|
switch (num_rt_type[0]) {
|
|
|
|
case '1':
|
|
|
|
return "ead";
|
|
|
|
case '2':
|
|
|
|
return "macip";
|
|
|
|
case '3':
|
|
|
|
return "multicast";
|
|
|
|
case '4':
|
|
|
|
return "es";
|
|
|
|
case '5':
|
|
|
|
return "prefix";
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Was already full type string */
|
|
|
|
return num_rt_type;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_evpn_route_type,
|
|
|
|
match_evpn_route_type_cmd,
|
2022-02-11 04:35:14 +01:00
|
|
|
"match evpn route-type <ead|1|macip|2|multicast|3|es|4|prefix|5>",
|
2020-10-30 08:45:43 +01:00
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
EVPN_TYPE_HELP_STR
|
2022-02-08 21:59:16 +01:00
|
|
|
EVPN_TYPE_1_HELP_STR
|
|
|
|
EVPN_TYPE_1_HELP_STR
|
2020-10-30 08:45:43 +01:00
|
|
|
EVPN_TYPE_2_HELP_STR
|
|
|
|
EVPN_TYPE_2_HELP_STR
|
|
|
|
EVPN_TYPE_3_HELP_STR
|
|
|
|
EVPN_TYPE_3_HELP_STR
|
2022-02-11 04:35:14 +01:00
|
|
|
EVPN_TYPE_4_HELP_STR
|
|
|
|
EVPN_TYPE_4_HELP_STR
|
2020-10-30 08:45:43 +01:00
|
|
|
EVPN_TYPE_5_HELP_STR
|
|
|
|
EVPN_TYPE_5_HELP_STR)
|
2020-10-13 22:12:14 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-route-type']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:evpn-route-type",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
parse_evpn_rt_type(argv[3]->arg));
|
2018-01-27 02:16:48 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_match_evpn_route_type,
|
|
|
|
no_match_evpn_route_type_cmd,
|
2022-02-11 04:35:14 +01:00
|
|
|
"no match evpn route-type <ead|1|macip|2|multicast|3|es|4|prefix|5>",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
EVPN_TYPE_HELP_STR
|
2022-02-08 21:59:16 +01:00
|
|
|
EVPN_TYPE_1_HELP_STR
|
|
|
|
EVPN_TYPE_1_HELP_STR
|
2020-10-30 08:45:43 +01:00
|
|
|
EVPN_TYPE_2_HELP_STR
|
|
|
|
EVPN_TYPE_2_HELP_STR
|
|
|
|
EVPN_TYPE_3_HELP_STR
|
|
|
|
EVPN_TYPE_3_HELP_STR
|
2022-02-11 04:35:14 +01:00
|
|
|
EVPN_TYPE_4_HELP_STR
|
|
|
|
EVPN_TYPE_4_HELP_STR
|
2020-10-30 08:45:43 +01:00
|
|
|
EVPN_TYPE_5_HELP_STR
|
|
|
|
EVPN_TYPE_5_HELP_STR)
|
2017-06-21 11:00:24 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-route-type']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-06-21 11:00:24 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
DEFUN_YANG (match_evpn_vni,
|
|
|
|
match_evpn_vni_cmd,
|
|
|
|
"match evpn vni " CMD_VNI_RANGE,
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Match VNI\n"
|
|
|
|
"VNI ID\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-vni']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:evpn-vni", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_match_evpn_vni,
|
|
|
|
no_match_evpn_vni_cmd,
|
|
|
|
"no match evpn vni " CMD_VNI_RANGE,
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Match VNI\n"
|
|
|
|
"VNI ID\n")
|
2017-06-21 11:00:24 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-vni']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:evpn-vni", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, argv[3]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-06-21 11:00:24 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_evpn_default_route,
|
|
|
|
match_evpn_default_route_cmd,
|
|
|
|
"match evpn default-route",
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"default EVPN type-5 route\n")
|
2018-02-22 07:02:07 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-default-route']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:evpn-default-route",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, NULL);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2018-02-22 07:02:07 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_evpn_default_route,
|
|
|
|
no_match_evpn_default_route_cmd,
|
|
|
|
"no match evpn default-route",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"default EVPN type-5 route\n")
|
2018-02-22 07:02:07 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-default-route']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2018-02-22 07:02:07 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_evpn_rd,
|
|
|
|
match_evpn_rd_cmd,
|
|
|
|
"match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Route Distinguisher\n"
|
|
|
|
"ASN:XX or A.B.C.D:XX\n")
|
2019-11-13 01:51:24 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-rd']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:route-distinguisher",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2019-11-13 01:51:24 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_evpn_rd,
|
|
|
|
no_match_evpn_rd_cmd,
|
|
|
|
"no match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Route Distinguisher\n"
|
|
|
|
"ASN:XX or A.B.C.D:XX\n")
|
2019-11-13 01:51:24 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:evpn-rd']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2019-11-13 01:51:24 +01:00
|
|
|
}
|
|
|
|
|
2021-05-21 11:04:00 +02:00
|
|
|
DEFUN_YANG (set_evpn_gw_ip_ipv4,
|
|
|
|
set_evpn_gw_ip_ipv4_cmd,
|
|
|
|
"set evpn gateway-ip ipv4 A.B.C.D",
|
|
|
|
SET_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Set gateway IP for prefix advertisement route\n"
|
|
|
|
"IPv4 address\n"
|
|
|
|
"Gateway IP address in IPv4 format\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
union sockunion su;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv4']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
ret = str2sockunion(argv[4]->arg, &su);
|
|
|
|
if (ret < 0) {
|
|
|
|
vty_out(vty, "%% Malformed gateway IP\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
2022-06-06 09:47:27 +02:00
|
|
|
if (su.sin.sin_addr.s_addr == 0 ||
|
|
|
|
!ipv4_unicast_valid(&su.sin.sin_addr)) {
|
2021-05-21 11:04:00 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"%% Gateway IP cannot be 0.0.0.0, multicast or reserved\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:evpn-gateway-ip-ipv4",
|
|
|
|
xpath);
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[4]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_set_evpn_gw_ip_ipv4,
|
|
|
|
no_set_evpn_gw_ip_ipv4_cmd,
|
|
|
|
"no set evpn gateway-ip ipv4 A.B.C.D",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Set gateway IP for prefix advertisement route\n"
|
|
|
|
"IPv4 address\n"
|
|
|
|
"Gateway IP address in IPv4 format\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
union sockunion su;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv4']";
|
|
|
|
|
|
|
|
ret = str2sockunion(argv[5]->arg, &su);
|
|
|
|
if (ret < 0) {
|
|
|
|
vty_out(vty, "%% Malformed gateway IP\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
2022-06-06 09:47:27 +02:00
|
|
|
if (su.sin.sin_addr.s_addr == 0 ||
|
|
|
|
!ipv4_unicast_valid(&su.sin.sin_addr)) {
|
2021-05-21 11:04:00 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"%% Gateway IP cannot be 0.0.0.0, multicast or reserved\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (set_evpn_gw_ip_ipv6,
|
|
|
|
set_evpn_gw_ip_ipv6_cmd,
|
|
|
|
"set evpn gateway-ip ipv6 X:X::X:X",
|
|
|
|
SET_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Set gateway IP for prefix advertisement route\n"
|
|
|
|
"IPv6 address\n"
|
|
|
|
"Gateway IP address in IPv6 format\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
union sockunion su;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv6']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
ret = str2sockunion(argv[4]->arg, &su);
|
|
|
|
if (ret < 0) {
|
|
|
|
vty_out(vty, "%% Malformed gateway IP\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr)
|
|
|
|
|| IN6_IS_ADDR_MULTICAST(&su.sin6.sin6_addr)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% Gateway IP cannot be a linklocal or multicast address\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:evpn-gateway-ip-ipv6",
|
|
|
|
xpath);
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[4]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_set_evpn_gw_ip_ipv6,
|
|
|
|
no_set_evpn_gw_ip_ipv6_cmd,
|
|
|
|
"no set evpn gateway-ip ipv6 X:X::X:X",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
EVPN_HELP_STR
|
|
|
|
"Set gateway IP for prefix advertisement route\n"
|
|
|
|
"IPv4 address\n"
|
|
|
|
"Gateway IP address in IPv4 format\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
union sockunion su;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-evpn-gateway-ip-ipv6']";
|
|
|
|
|
|
|
|
ret = str2sockunion(argv[5]->arg, &su);
|
|
|
|
if (ret < 0) {
|
|
|
|
vty_out(vty, "%% Malformed gateway IP\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr)
|
|
|
|
|| IN6_IS_ADDR_MULTICAST(&su.sin6.sin6_addr)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"%% Gateway IP cannot be a linklocal or multicast address\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG(match_vrl_source_vrf,
|
2019-02-15 03:07:27 +01:00
|
|
|
match_vrl_source_vrf_cmd,
|
|
|
|
"match source-vrf NAME$vrf_name",
|
|
|
|
MATCH_STR
|
|
|
|
"source vrf\n"
|
|
|
|
"The VRF name\n")
|
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:source-vrf']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:source-vrf", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, vrf_name);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2019-02-15 03:07:27 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG(no_match_vrl_source_vrf,
|
2019-02-15 03:07:27 +01:00
|
|
|
no_match_vrl_source_vrf_cmd,
|
|
|
|
"no match source-vrf NAME$vrf_name",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR MATCH_STR
|
2019-02-15 03:07:27 +01:00
|
|
|
"source vrf\n"
|
|
|
|
"The VRF name\n")
|
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:source-vrf']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2019-02-15 03:07:27 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (match_peer,
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
match_peer_cmd,
|
2020-10-30 08:45:43 +01:00
|
|
|
"match peer <A.B.C.D$addrv4|X:X::X:X$addrv6|WORD$intf>",
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
MATCH_STR
|
|
|
|
"Match peer address\n"
|
2016-05-11 14:26:39 +02:00
|
|
|
"IP address of peer\n"
|
2017-10-18 15:34:57 +02:00
|
|
|
"IPv6 address of peer\n"
|
2022-05-31 18:19:27 +02:00
|
|
|
"Interface name of peer or peer group name\n")
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:peer']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
2024-05-16 19:49:56 +02:00
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value,
|
|
|
|
addrv4_str ? NB_OP_MODIFY : NB_OP_DESTROY,
|
|
|
|
addrv4_str);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value,
|
|
|
|
addrv6_str ? NB_OP_MODIFY : NB_OP_DESTROY,
|
|
|
|
addrv6_str);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:peer-interface",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value,
|
|
|
|
intf ? NB_OP_MODIFY : NB_OP_DESTROY, intf);
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_peer_local,
|
|
|
|
match_peer_local_cmd,
|
|
|
|
"match peer local",
|
|
|
|
MATCH_STR
|
|
|
|
"Match peer address\n"
|
|
|
|
"Static or Redistributed routes\n")
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:peer']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:peer-local", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_peer,
|
|
|
|
no_match_peer_cmd,
|
|
|
|
"no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Match peer address\n"
|
|
|
|
"Static or Redistributed routes\n"
|
|
|
|
"IP address of peer\n"
|
|
|
|
"IPv6 address of peer\n"
|
|
|
|
"Interface name of peer\n")
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:peer']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
}
|
|
|
|
|
2020-11-30 23:01:03 +01:00
|
|
|
#ifdef HAVE_SCRIPTING
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_script,
|
|
|
|
match_script_cmd,
|
|
|
|
"[no] match script WORD",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Execute script to determine match\n"
|
|
|
|
"The script name to run, without .lua; e.g. 'myroutemap' to run myroutemap.lua\n")
|
2017-11-07 15:14:32 +01:00
|
|
|
{
|
2020-11-29 22:01:59 +01:00
|
|
|
bool no = strmatch(argv[0]->text, "no");
|
|
|
|
int i = 0;
|
|
|
|
argv_find(argv, argc, "WORD", &i);
|
|
|
|
const char *script = argv[i]->arg;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-script']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2020-11-29 22:01:59 +01:00
|
|
|
|
|
|
|
if (no) {
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:script",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
|
|
|
|
script);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2020-11-29 22:01:59 +01:00
|
|
|
}
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:script",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
script);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-11-07 15:14:32 +01:00
|
|
|
}
|
2020-11-30 23:01:03 +01:00
|
|
|
#endif /* HAVE_SCRIPTING */
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
/* match probability */
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_probability,
|
|
|
|
match_probability_cmd,
|
|
|
|
"match probability (0-100)",
|
|
|
|
MATCH_STR
|
|
|
|
"Match portion of routes defined by percentage value\n"
|
|
|
|
"Percentage of routes\n")
|
2011-11-22 17:15:10 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_number = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:probability']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:probability",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2011-11-22 17:15:10 +01:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_probability,
|
|
|
|
no_match_probability_cmd,
|
|
|
|
"no match probability [(1-99)]",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Match portion of routes defined by percentage value\n"
|
|
|
|
"Percentage of routes\n")
|
2011-11-22 17:15:10 +01:00
|
|
|
{
|
2016-09-27 07:05:12 +02:00
|
|
|
int idx_number = 3;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:probability']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
if (argc <= idx_number)
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:probability",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2011-11-22 17:15:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (match_ip_route_source,
|
2005-02-02 17:43:17 +01:00
|
|
|
match_ip_route_source_cmd,
|
2021-10-21 21:52:14 +02:00
|
|
|
"match ip route-source ACCESSLIST4_NAME",
|
2005-02-02 17:43:17 +01:00
|
|
|
MATCH_STR
|
|
|
|
IP_STR
|
|
|
|
"Match advertising source address of route\n"
|
2021-10-01 17:35:11 +02:00
|
|
|
"IP Access-list name\n")
|
2005-02-02 17:43:17 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ip-route-source']";
|
|
|
|
char xpath_value[XPATH_MAXLEN + 32];
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_acl = 3;
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_acl]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2005-02-02 17:43:17 +01:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_ip_route_source,
|
|
|
|
no_match_ip_route_source_cmd,
|
2021-10-21 21:52:14 +02:00
|
|
|
"no match ip route-source [ACCESSLIST4_NAME]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
IP_STR
|
|
|
|
"Match advertising source address of route\n"
|
2021-10-01 17:35:11 +02:00
|
|
|
"IP Access-list name\n")
|
2005-02-02 17:43:17 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ip-route-source']";
|
2005-02-02 17:43:17 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
2005-02-02 17:43:17 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_ip_route_source_prefix_list,
|
|
|
|
match_ip_route_source_prefix_list_cmd,
|
2021-10-21 21:38:31 +02:00
|
|
|
"match ip route-source prefix-list PREFIXLIST_NAME",
|
2020-10-30 08:45:43 +01:00
|
|
|
MATCH_STR
|
|
|
|
IP_STR
|
|
|
|
"Match advertising source address of route\n"
|
|
|
|
"Match entries of prefix-lists\n"
|
|
|
|
"IP prefix-list name\n")
|
2005-02-02 17:43:17 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_word = 4;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ip-route-source-prefix-list']";
|
|
|
|
char xpath_value[XPATH_MAXLEN + 32];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_word]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2005-02-02 17:43:17 +01:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_ip_route_source_prefix_list,
|
|
|
|
no_match_ip_route_source_prefix_list_cmd,
|
2021-10-21 21:38:31 +02:00
|
|
|
"no match ip route-source prefix-list [PREFIXLIST_NAME]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
IP_STR
|
|
|
|
"Match advertising source address of route\n"
|
|
|
|
"Match entries of prefix-lists\n"
|
|
|
|
"IP prefix-list name\n")
|
2005-02-02 17:43:17 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ip-route-source-prefix-list']";
|
2005-02-02 17:43:17 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
2005-02-02 17:43:17 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_local_pref,
|
|
|
|
match_local_pref_cmd,
|
|
|
|
"match local-preference (0-4294967295)",
|
|
|
|
MATCH_STR
|
|
|
|
"Match local-preference of route\n"
|
|
|
|
"Metric value\n")
|
2015-05-20 02:40:40 +02:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_number = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-local-preference']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:local-preference",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2015-05-20 02:40:40 +02:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_local_pref,
|
|
|
|
no_match_local_pref_cmd,
|
|
|
|
"no match local-preference [(0-4294967295)]",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Match local preference of route\n"
|
|
|
|
"Local preference value\n")
|
2015-05-20 02:40:40 +02:00
|
|
|
{
|
2016-09-27 07:05:12 +02:00
|
|
|
int idx_localpref = 3;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-local-preference']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
if (argc <= idx_localpref)
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:local-preference",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
|
|
|
|
argv[idx_localpref]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2015-05-20 02:40:40 +02:00
|
|
|
}
|
|
|
|
|
2021-07-18 11:14:24 +02:00
|
|
|
DEFUN_YANG(match_alias, match_alias_cmd, "match alias ALIAS_NAME",
|
|
|
|
MATCH_STR
|
|
|
|
"Match BGP community alias name\n"
|
|
|
|
"BGP community alias name\n")
|
|
|
|
{
|
|
|
|
const char *alias = argv[2]->arg;
|
|
|
|
struct community_alias ca1;
|
|
|
|
struct community_alias *lookup_alias;
|
|
|
|
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-alias']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
memset(&ca1, 0, sizeof(ca1));
|
|
|
|
strlcpy(ca1.alias, alias, sizeof(ca1.alias));
|
|
|
|
lookup_alias = bgp_ca_alias_lookup(&ca1);
|
|
|
|
if (!lookup_alias) {
|
|
|
|
vty_out(vty, "%% BGP alias name '%s' does not exist\n", alias);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:alias", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, alias);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN_YANG(no_match_alias, no_match_alias_cmd, "no match alias [ALIAS_NAME]",
|
|
|
|
NO_STR MATCH_STR
|
|
|
|
"Match BGP community alias name\n"
|
|
|
|
"BGP community alias name\n")
|
|
|
|
{
|
|
|
|
int idx_alias = 3;
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-alias']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
|
|
|
if (argc <= idx_alias)
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:alias", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
|
|
|
|
argv[idx_alias]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
2015-05-20 02:40:40 +02:00
|
|
|
|
2023-06-27 21:36:01 +02:00
|
|
|
DEFPY_YANG(
|
|
|
|
match_community, match_community_cmd,
|
|
|
|
"match community <(1-99)|(100-500)|COMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]",
|
|
|
|
MATCH_STR "Match BGP community list\n"
|
|
|
|
"Community-list number (standard)\n"
|
|
|
|
"Community-list number (expanded)\n"
|
|
|
|
"Community-list name\n"
|
|
|
|
"Do exact matching of communities\n"
|
|
|
|
"Do matching of any community\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-community']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
char xpath_match[XPATH_MAXLEN];
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_comm_list = 2;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_comm_list]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2023-06-27 21:36:01 +02:00
|
|
|
snprintf(xpath_match, sizeof(xpath_match),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
|
|
|
|
xpath);
|
|
|
|
if (exact)
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
|
|
|
|
"true");
|
2023-06-27 21:36:01 +02:00
|
|
|
else
|
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
|
|
|
|
|
|
|
|
snprintf(xpath_match, sizeof(xpath_match),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any",
|
|
|
|
xpath);
|
|
|
|
if (any)
|
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true");
|
|
|
|
else
|
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2023-06-27 21:36:01 +02:00
|
|
|
DEFUN_YANG(
|
|
|
|
no_match_community, no_match_community_cmd,
|
|
|
|
"no match community [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]]",
|
|
|
|
NO_STR MATCH_STR "Match BGP community list\n"
|
|
|
|
"Community-list number (standard)\n"
|
|
|
|
"Community-list number (expanded)\n"
|
|
|
|
"Community-list name\n"
|
|
|
|
"Do exact matching of communities\n"
|
|
|
|
"Do matching of any community\n")
|
2020-10-30 08:45:43 +01:00
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-community']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2023-06-27 21:36:01 +02:00
|
|
|
DEFPY_YANG(
|
|
|
|
match_lcommunity, match_lcommunity_cmd,
|
|
|
|
"match large-community <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]",
|
|
|
|
MATCH_STR "Match BGP large community list\n"
|
|
|
|
"Large Community-list number (standard)\n"
|
|
|
|
"Large Community-list number (expanded)\n"
|
|
|
|
"Large Community-list name\n"
|
|
|
|
"Do exact matching of communities\n"
|
|
|
|
"Do matching of any community\n")
|
2020-10-30 08:45:43 +01:00
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-large-community']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
char xpath_match[XPATH_MAXLEN];
|
2019-05-06 11:45:32 +02:00
|
|
|
int idx_lcomm_list = 2;
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
2019-05-06 11:45:32 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_lcomm_list]->arg);
|
2019-05-06 11:45:32 +02:00
|
|
|
|
2023-06-27 21:36:01 +02:00
|
|
|
snprintf(xpath_match, sizeof(xpath_match),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
|
|
|
|
xpath);
|
|
|
|
if (exact)
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
|
|
|
|
"true");
|
2023-06-27 21:36:01 +02:00
|
|
|
else
|
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
|
|
|
|
|
|
|
|
snprintf(xpath_match, sizeof(xpath_match),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any",
|
|
|
|
xpath);
|
|
|
|
if (any)
|
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true");
|
|
|
|
else
|
|
|
|
nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false");
|
2019-05-06 11:45:32 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2023-06-27 21:36:01 +02:00
|
|
|
DEFUN_YANG(
|
|
|
|
no_match_lcommunity, no_match_lcommunity_cmd,
|
|
|
|
"no match large-community [<(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [<exact-match|any>]]",
|
|
|
|
NO_STR MATCH_STR "Match BGP large community list\n"
|
|
|
|
"Large Community-list number (standard)\n"
|
|
|
|
"Large Community-list number (expanded)\n"
|
|
|
|
"Large Community-list name\n"
|
|
|
|
"Do exact matching of communities\n"
|
|
|
|
"Do matching of any community\n")
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-large-community']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (match_ecommunity,
|
|
|
|
match_ecommunity_cmd,
|
2021-10-19 14:14:19 +02:00
|
|
|
"match extcommunity <(1-99)|(100-500)|EXTCOMMUNITY_LIST_NAME>",
|
2020-10-30 08:45:43 +01:00
|
|
|
MATCH_STR
|
|
|
|
"Match BGP/VPN extended community list\n"
|
|
|
|
"Extended community-list number (standard)\n"
|
|
|
|
"Extended community-list number (expanded)\n"
|
|
|
|
"Extended community-list name\n")
|
2003-04-19 17:49:49 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-extcommunity']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_comm_list = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_comm_list]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2003-04-19 17:49:49 +02:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_ecommunity,
|
|
|
|
no_match_ecommunity_cmd,
|
2021-10-19 14:14:19 +02:00
|
|
|
"no match extcommunity [<(1-99)|(100-500)|EXTCOMMUNITY_LIST_NAME>]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Match BGP/VPN extended community list\n"
|
|
|
|
"Extended community-list number (standard)\n"
|
|
|
|
"Extended community-list number (expanded)\n"
|
|
|
|
"Extended community-list name\n")
|
2003-04-19 17:49:49 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-extcommunity']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2003-04-19 17:49:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-06-14 16:16:55 +02:00
|
|
|
DEFPY_YANG (set_ecommunity_delete,
|
|
|
|
set_ecommunity_delete_cmd,
|
|
|
|
"set extended-comm-list " EXTCOMM_LIST_CMD_STR " delete",
|
|
|
|
SET_STR
|
|
|
|
"set BGP extended community list (for deletion)\n"
|
|
|
|
EXTCOMM_STD_LIST_NUM_STR
|
|
|
|
EXTCOMM_EXP_LIST_NUM_STR
|
|
|
|
EXTCOMM_LIST_NAME_STR
|
|
|
|
"Delete matching extended communities\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:extended-comm-list-delete']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
int idx_comm_list = 2;
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_comm_list]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFPY_YANG (no_set_ecommunity_delete,
|
|
|
|
no_set_ecommunity_delete_cmd,
|
|
|
|
"no set extended-comm-list [" EXTCOMM_LIST_CMD_STR "] delete",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"set BGP extended community list (for deletion)\n"
|
|
|
|
EXTCOMM_STD_LIST_NUM_STR
|
|
|
|
EXTCOMM_EXP_LIST_NUM_STR
|
|
|
|
EXTCOMM_LIST_NAME_STR
|
|
|
|
"Delete matching extended communities\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:extended-comm-list-delete']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (match_aspath,
|
|
|
|
match_aspath_cmd,
|
2021-10-19 14:31:39 +02:00
|
|
|
"match as-path AS_PATH_FILTER_NAME",
|
2020-10-30 08:45:43 +01:00
|
|
|
MATCH_STR
|
|
|
|
"Match BGP AS path list\n"
|
|
|
|
"AS path access-list name\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_word = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:as-path-list']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_word]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_aspath,
|
|
|
|
no_match_aspath_cmd,
|
2021-10-19 14:31:39 +02:00
|
|
|
"no match as-path [AS_PATH_FILTER_NAME]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Match BGP AS path list\n"
|
|
|
|
"AS path access-list name\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:as-path-list']";
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (match_origin,
|
|
|
|
match_origin_cmd,
|
|
|
|
"match origin <egp|igp|incomplete>",
|
|
|
|
MATCH_STR
|
|
|
|
"BGP origin code\n"
|
|
|
|
"remote EGP\n"
|
|
|
|
"local IGP\n"
|
|
|
|
"unknown heritage\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_origin = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *origin_type;
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-origin']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
2016-09-23 21:45:50 +02:00
|
|
|
if (strncmp(argv[idx_origin]->arg, "igp", 2) == 0)
|
2020-10-30 08:45:43 +01:00
|
|
|
origin_type = "igp";
|
|
|
|
else if (strncmp(argv[idx_origin]->arg, "egp", 1) == 0)
|
|
|
|
origin_type = "egp";
|
|
|
|
else if (strncmp(argv[idx_origin]->arg, "incomplete", 2) == 0)
|
|
|
|
origin_type = "incomplete";
|
|
|
|
else {
|
|
|
|
vty_out(vty, "%% Invalid match origin type\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:origin", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, origin_type);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_match_origin,
|
|
|
|
no_match_origin_cmd,
|
|
|
|
"no match origin [<egp|igp|incomplete>]",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"BGP origin code\n"
|
|
|
|
"remote EGP\n"
|
|
|
|
"local IGP\n"
|
|
|
|
"unknown heritage\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:match-origin']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_table_id,
|
|
|
|
set_table_id_cmd,
|
|
|
|
"set table (1-4294967295)",
|
|
|
|
SET_STR
|
|
|
|
"export route to non-main kernel table\n"
|
|
|
|
"Kernel routing table id\n")
|
2019-04-29 15:26:01 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
int idx_number = 2;
|
|
|
|
const char *xpath = "./set-action[action='frr-bgp-route-map:table']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:table", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_set_table_id,
|
|
|
|
no_set_table_id_cmd,
|
2024-05-03 07:58:21 +02:00
|
|
|
"no set table [(1-4294967295)]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
2024-05-03 07:58:21 +02:00
|
|
|
"export route to non-main kernel table\n"
|
|
|
|
"Kernel routing table id\n")
|
2020-10-30 08:45:43 +01:00
|
|
|
{
|
|
|
|
const char *xpath = "./set-action[action='frr-bgp-route-map:table']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (set_ip_nexthop_peer,
|
|
|
|
set_ip_nexthop_peer_cmd,
|
|
|
|
"[no] set ip next-hop peer-address",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
IP_STR
|
|
|
|
"Next hop address\n"
|
|
|
|
"Use peer address (for BGP only)\n")
|
|
|
|
{
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-ipv4-nexthop']";
|
|
|
|
|
|
|
|
if (strmatch(argv[0]->text, "no"))
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
else {
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
"peer-address");
|
|
|
|
}
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2019-04-29 15:26:01 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_ip_nexthop_unchanged,
|
|
|
|
set_ip_nexthop_unchanged_cmd,
|
|
|
|
"[no] set ip next-hop unchanged",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
IP_STR
|
|
|
|
"Next hop address\n"
|
|
|
|
"Don't modify existing Next hop address\n")
|
2019-04-29 15:26:01 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-ipv4-nexthop']";
|
2019-04-29 15:26:01 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
if (strmatch(argv[0]->text, "no"))
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
else {
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
"unchanged");
|
|
|
|
}
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2019-04-29 15:26:01 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_distance,
|
|
|
|
set_distance_cmd,
|
2023-03-21 21:08:16 +01:00
|
|
|
"set distance (1-255)",
|
2020-10-30 08:45:43 +01:00
|
|
|
SET_STR
|
|
|
|
"BGP Administrative Distance to use\n"
|
|
|
|
"Distance value\n")
|
2003-11-02 08:24:40 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
int idx_number = 2;
|
|
|
|
const char *xpath = "./set-action[action='frr-bgp-route-map:distance']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2017-08-10 18:31:47 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:distance", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2003-11-02 08:24:40 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_distance,
|
|
|
|
no_set_distance_cmd,
|
2023-03-21 21:08:16 +01:00
|
|
|
"no set distance [(1-255)]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR SET_STR
|
|
|
|
"BGP Administrative Distance to use\n"
|
|
|
|
"Distance value\n")
|
2015-05-20 03:03:49 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath = "./set-action[action='frr-bgp-route-map:distance']";
|
2017-08-10 18:55:32 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
bgpd: add resolution for l3vpn traffic over gre interfaces
When a route imported from l3vpn is analysed, the nexthop from default
VRF is looked up against a valid MPLS path. Generally, this is done on
backbones with a MPLS signalisation transport layer like LDP. Generally,
the BGP connection is multiple hops away. That scenario is already
working.
There is case where it is possible to run L3VPN over GRE interfaces, and
where there is no LSP path over that GRE interface: GRE is just here to
tunnel MPLS traffic. On that case, the nexthop given in the path does not
have MPLS path, but should be authorized to convey MPLS traffic provided
that the user permits it via a configuration command.
That commit introduces a new command that can be activated in route-map:
> set l3vpn next-hop encapsulation gre
That command authorizes the nexthop tracking engine to accept paths that
o have a GRE interface as output, independently of the presence of an LSP
path or not.
A configuration example is given below. When bgp incoming vpnv4 updates
are received, the nexthop of NLRI is 192.168.0.2. Based on nexthop
tracking service from zebra, BGP knows that the output interface to reach
192.168.0.2 is r1-gre0. Because that interface is not MPLS based, but is
a GRE tunnel, then the update will be using that nexthop to be installed.
interface r1-gre0
ip address 192.168.0.1/24
exit
router bgp 65500
bgp router-id 1.1.1.1
neighbor 192.168.0.2 remote-as 65500
!
address-family ipv4 unicast
no neighbor 192.168.0.2 activate
exit-address-family
!
address-family ipv4 vpn
neighbor 192.168.0.2 activate
neighbor 192.168.0.2 route-map rmap in
exit-address-family
exit
!
router bgp 65500 vrf vrf1
bgp router-id 1.1.1.1
no bgp network import-check
!
address-family ipv4 unicast
network 10.201.0.0/24
redistribute connected
label vpn export 101
rd vpn export 444:1
rt vpn both 52:100
export vpn
import vpn
exit-address-family
exit
!
route-map rmap permit 1
set l3vpn next-hop encapsulation gre
exit
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2021-09-20 11:50:52 +02:00
|
|
|
DEFPY_YANG(set_l3vpn_nexthop_encapsulation, set_l3vpn_nexthop_encapsulation_cmd,
|
|
|
|
"[no] set l3vpn next-hop encapsulation gre",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"L3VPN operations\n"
|
|
|
|
"Next hop Information\n"
|
|
|
|
"Encapsulation options (for BGP only)\n"
|
|
|
|
"Accept L3VPN traffic over GRE encapsulation\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-l3vpn-nexthop-encapsulation']";
|
|
|
|
const char *xpath_value =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-l3vpn-nexthop-encapsulation']/rmap-set-action/frr-bgp-route-map:l3vpn-nexthop-encapsulation";
|
|
|
|
enum nb_operation operation;
|
|
|
|
|
|
|
|
if (no)
|
|
|
|
operation = NB_OP_DESTROY;
|
|
|
|
else
|
|
|
|
operation = NB_OP_CREATE;
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, operation, NULL);
|
|
|
|
if (operation == NB_OP_DESTROY)
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "gre");
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_local_pref,
|
|
|
|
set_local_pref_cmd,
|
|
|
|
"set local-preference WORD",
|
|
|
|
SET_STR
|
|
|
|
"BGP local preference path attribute\n"
|
|
|
|
"Preference value (0-4294967295)\n")
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
{
|
|
|
|
int idx_number = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-local-preference']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:local-pref", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_local_pref,
|
|
|
|
no_set_local_pref_cmd,
|
|
|
|
"no set local-preference [WORD]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP local preference path attribute\n"
|
|
|
|
"Preference value (0-4294967295)\n")
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-local-preference']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_weight,
|
|
|
|
set_weight_cmd,
|
|
|
|
"set weight (0-4294967295)",
|
|
|
|
SET_STR
|
|
|
|
"BGP weight for routing table\n"
|
|
|
|
"Weight value\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_number = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath = "./set-action[action='frr-bgp-route-map:weight']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:weight", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_weight,
|
|
|
|
no_set_weight_cmd,
|
|
|
|
"no set weight [(0-4294967295)]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP weight for routing table\n"
|
|
|
|
"Weight value\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath = "./set-action[action='frr-bgp-route-map:weight']";
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_label_index,
|
|
|
|
set_label_index_cmd,
|
|
|
|
"set label-index (0-1048560)",
|
|
|
|
SET_STR
|
|
|
|
"Label index to associate with the prefix\n"
|
|
|
|
"Label index value\n")
|
2017-06-02 21:22:53 +02:00
|
|
|
{
|
|
|
|
int idx_number = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:label-index']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:label-index", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-06-02 21:22:53 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_label_index,
|
|
|
|
no_set_label_index_cmd,
|
|
|
|
"no set label-index [(0-1048560)]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"Label index to associate with the prefix\n"
|
|
|
|
"Label index value\n")
|
2017-06-02 21:22:53 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:label-index']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-06-02 21:22:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_aspath_prepend_asn,
|
|
|
|
set_aspath_prepend_asn_cmd,
|
2022-11-02 18:17:21 +01:00
|
|
|
"set as-path prepend ASNUM...",
|
2020-10-30 08:45:43 +01:00
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Prepend to the as-path\n"
|
2022-11-02 18:17:21 +01:00
|
|
|
AS_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-30 02:16:31 +02:00
|
|
|
int idx_asn = 3;
|
2002-12-13 21:15:29 +01:00
|
|
|
int ret;
|
|
|
|
char *str;
|
2022-11-02 18:17:21 +01:00
|
|
|
struct aspath *aspath;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-30 02:16:31 +02:00
|
|
|
str = argv_concat(argv, argc, idx_asn);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
2022-11-02 18:17:21 +01:00
|
|
|
aspath = route_aspath_compile(str);
|
|
|
|
if (!aspath) {
|
|
|
|
vty_out(vty, "%% Invalid AS path value %s\n", str);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
route_aspath_free(aspath);
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:prepend-as-path", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
|
|
|
XFREE(MTYPE_TMP, str);
|
2002-12-13 21:15:29 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_aspath_prepend_lastas,
|
|
|
|
set_aspath_prepend_lastas_cmd,
|
|
|
|
"set as-path prepend last-as (1-10)",
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Prepend to the as-path\n"
|
2021-08-11 14:45:23 +02:00
|
|
|
"Use the last AS-number in the as-path\n"
|
2020-10-30 08:45:43 +01:00
|
|
|
"Number of times to insert\n")
|
2016-10-04 21:21:45 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
int idx_num = 4;
|
|
|
|
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:last-as", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_num]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-10-04 21:21:45 +02:00
|
|
|
}
|
2016-05-26 03:49:34 +02:00
|
|
|
|
2023-06-19 16:22:55 +02:00
|
|
|
DEFPY_YANG(set_aspath_replace_asn, set_aspath_replace_asn_cmd,
|
|
|
|
"set as-path replace <any|ASNUM>$replace [<ASNUM>$configured_asn]",
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Replace AS number to local or configured AS number\n"
|
|
|
|
"Replace any AS number to local or configured AS number\n"
|
|
|
|
"Replace a specific AS number to local or configured AS number\n"
|
|
|
|
"Define the configured AS number\n")
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-replace']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2023-06-19 16:22:55 +02:00
|
|
|
as_t as_value, as_configured_value;
|
|
|
|
char replace_value[ASN_STRING_MAX_SIZE * 2];
|
2022-11-02 18:17:21 +01:00
|
|
|
|
|
|
|
if (!strmatch(replace, "any") && !asn_str2asn(replace, &as_value)) {
|
|
|
|
vty_out(vty, "%% Invalid AS value %s\n", replace);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2023-06-19 16:22:55 +02:00
|
|
|
if (configured_asn_str &&
|
|
|
|
!asn_str2asn(configured_asn_str, &as_configured_value)) {
|
|
|
|
vty_out(vty, "%% Invalid AS configured value %s\n",
|
|
|
|
configured_asn_str);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:replace-as-path", xpath);
|
2023-06-19 16:22:55 +02:00
|
|
|
snprintf(replace_value, sizeof(replace_value), "%s%s%s", replace,
|
|
|
|
configured_asn_str ? " " : "",
|
|
|
|
configured_asn_str ? configured_asn_str : "");
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, replace_value);
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2023-06-19 16:22:55 +02:00
|
|
|
DEFPY_YANG(no_set_aspath_replace_asn, no_set_aspath_replace_asn_cmd,
|
|
|
|
"no set as-path replace [<any|ASNUM>] [<ASNUM>$configured_asn]",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Replace AS number to local or configured AS number\n"
|
|
|
|
"Replace any AS number to local or configured AS number\n"
|
|
|
|
"Replace a specific AS number to local or configured AS number\n"
|
|
|
|
"Define the configured AS number\n")
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-replace']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
DEFPY_YANG(
|
|
|
|
set_aspath_replace_access_list, set_aspath_replace_access_list_cmd,
|
|
|
|
"set as-path replace as-path-access-list AS_PATH_FILTER_NAME$aspath_filter_name [<ASNUM>$configured_asn]",
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS-path attribute\n"
|
|
|
|
"Replace AS number to local or configured AS number\n"
|
|
|
|
"Specify an as path access list name\n"
|
|
|
|
"AS path access list name\n"
|
|
|
|
"Define the configured AS number\n")
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-replace']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
as_t as_configured_value;
|
|
|
|
char replace_value[ASN_STRING_MAX_SIZE * 2];
|
2023-08-17 18:42:11 +02:00
|
|
|
int ret;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
|
|
|
|
if (configured_asn_str &&
|
|
|
|
!asn_str2asn(configured_asn_str, &as_configured_value)) {
|
|
|
|
vty_out(vty, "%% Invalid AS configured value %s\n",
|
|
|
|
configured_asn_str);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
str = argv_concat(argv, argc, 3);
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(replace_value, sizeof(replace_value), "%s %s", aspath_filter_name, str);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:replace-as-path", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
|
2023-08-17 18:42:11 +02:00
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG(
|
|
|
|
no_set_aspath_replace_access_list, no_set_aspath_replace_access_list_cmd,
|
|
|
|
"no set as-path replace as-path-access-list [AS_PATH_FILTER_NAME] [<ASNUM>$configured_asn]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Replace AS number to local or configured AS number\n"
|
|
|
|
"Specify an as path access list name\n"
|
|
|
|
"AS path access list name\n"
|
|
|
|
"Define the configured AS number\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-replace']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_aspath_prepend,
|
2024-05-02 22:07:19 +02:00
|
|
|
no_set_aspath_prepend_last_as_cmd,
|
|
|
|
"no set as-path prepend [last-as [(1-10)]]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Prepend to the as-path\n"
|
|
|
|
"Use the peers AS-number\n"
|
|
|
|
"Number of times to insert\n")
|
bgpd: Add 'no set as-path prepend last-as X' command
The `set as-path prepend last-as X` command had no, 'no' form
of the command. Add this into the cli.
Testing:
!
route-map BLARBLE permit 10
set as-path prepend last-as 3
!
!
router bgp 9999
neighbor 10.50.12.118 remote-as external
neighbor 10.50.12.118 ebgp-multihop 30
!
address-family ipv4 unicast
neighbor 10.50.12.118 route-map BLARBLE in
!
!
eva# show bgp ipv4 uni 4.4.4.4
BGP routing table entry for 4.4.4.4/32
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
10.50.12.118
999 999 999 999
10.50.12.118 from 10.50.12.118 (10.50.12.118)
Origin incomplete, metric 0, valid, external, best (First path received)
Last update: Mon Aug 26 09:47:17 2019
eva# conf
eva(config)# route-map BLARBLE permit 10
eva(config-route-map)# no set as-path prepend last-as 3
eva(config-route-map)# end
eva# clear bgp ipv4 uni *
eva# show bgp ipv4 uni 4.4.4.4
BGP routing table entry for 4.4.4.4/32
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
10.50.12.118
999
10.50.12.118 from 10.50.12.118 (10.50.12.118)
Origin incomplete, metric 0, valid, external, best (First path received)
Last update: Mon Aug 26 09:48:31 2019
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-08-26 15:49:18 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
bgpd: Add 'no set as-path prepend last-as X' command
The `set as-path prepend last-as X` command had no, 'no' form
of the command. Add this into the cli.
Testing:
!
route-map BLARBLE permit 10
set as-path prepend last-as 3
!
!
router bgp 9999
neighbor 10.50.12.118 remote-as external
neighbor 10.50.12.118 ebgp-multihop 30
!
address-family ipv4 unicast
neighbor 10.50.12.118 route-map BLARBLE in
!
!
eva# show bgp ipv4 uni 4.4.4.4
BGP routing table entry for 4.4.4.4/32
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
10.50.12.118
999 999 999 999
10.50.12.118 from 10.50.12.118 (10.50.12.118)
Origin incomplete, metric 0, valid, external, best (First path received)
Last update: Mon Aug 26 09:47:17 2019
eva# conf
eva(config)# route-map BLARBLE permit 10
eva(config-route-map)# no set as-path prepend last-as 3
eva(config-route-map)# end
eva# clear bgp ipv4 uni *
eva# show bgp ipv4 uni 4.4.4.4
BGP routing table entry for 4.4.4.4/32
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
10.50.12.118
999
10.50.12.118 from 10.50.12.118 (10.50.12.118)
Origin incomplete, metric 0, valid, external, best (First path received)
Last update: Mon Aug 26 09:48:31 2019
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-08-26 15:49:18 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2024-05-02 22:07:19 +02:00
|
|
|
ALIAS_YANG (no_set_aspath_prepend,
|
|
|
|
no_set_aspath_prepend_as_cmd,
|
|
|
|
"no set as-path prepend ASNUM...",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Prepend to the as-path\n"
|
|
|
|
AS_STR)
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_aspath_exclude,
|
|
|
|
set_aspath_exclude_cmd,
|
2022-11-02 18:17:21 +01:00
|
|
|
"set as-path exclude ASNUM...",
|
2020-10-30 08:45:43 +01:00
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS-path attribute\n"
|
|
|
|
"Exclude from the as-path\n"
|
2022-11-02 18:17:21 +01:00
|
|
|
AS_STR)
|
2008-04-10 13:47:45 +02:00
|
|
|
{
|
2016-09-30 02:16:31 +02:00
|
|
|
int idx_asn = 3;
|
2008-04-10 13:47:45 +02:00
|
|
|
int ret;
|
|
|
|
char *str;
|
2022-11-02 18:17:21 +01:00
|
|
|
struct aspath *aspath;
|
2008-04-10 13:47:45 +02:00
|
|
|
|
2016-09-30 02:16:31 +02:00
|
|
|
str = argv_concat(argv, argc, idx_asn);
|
2020-10-30 08:45:43 +01:00
|
|
|
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
2022-11-02 18:17:21 +01:00
|
|
|
aspath = route_aspath_compile(str);
|
|
|
|
if (!aspath) {
|
|
|
|
vty_out(vty, "%% Invalid AS path value %s\n", str);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
route_aspath_free(aspath);
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:exclude-as-path", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
2008-04-10 13:47:45 +02:00
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2023-06-13 14:53:03 +02:00
|
|
|
DEFPY_YANG(set_aspath_exclude_all, set_aspath_exclude_all_cmd,
|
|
|
|
"[no$no] set as-path exclude all$all",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"Transform BGP AS-path attribute\n"
|
|
|
|
"Exclude from the as-path\n"
|
|
|
|
"Exclude all AS numbers from the as-path\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
if (no)
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
else {
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:exclude-as-path",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, all);
|
|
|
|
}
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_aspath_exclude,
|
|
|
|
no_set_aspath_exclude_cmd,
|
2022-11-02 18:17:21 +01:00
|
|
|
"no set as-path exclude ASNUM...",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Exclude from the as-path\n"
|
|
|
|
"AS number\n")
|
2008-04-10 13:47:45 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
|
2008-04-10 13:47:45 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2008-04-10 13:47:45 +02:00
|
|
|
}
|
|
|
|
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
DEFPY_YANG(set_aspath_exclude_access_list, set_aspath_exclude_access_list_cmd,
|
|
|
|
"set as-path exclude as-path-access-list AS_PATH_FILTER_NAME",
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS-path attribute\n"
|
|
|
|
"Exclude from the as-path\n"
|
|
|
|
"Specify an as path access list name\n"
|
|
|
|
"AS path access list name\n")
|
|
|
|
{
|
|
|
|
char *str;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2023-08-19 12:00:17 +02:00
|
|
|
int ret;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
|
|
|
|
str = argv_concat(argv, argc, 3);
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:exclude-as-path", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
|
2023-08-19 12:00:17 +02:00
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG(no_set_aspath_exclude_access_list, no_set_aspath_exclude_access_list_cmd,
|
|
|
|
"no set as-path exclude as-path-access-list [AS_PATH_FILTER_NAME]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Exclude from the as-path\n"
|
|
|
|
"Specify an as path access list name\n"
|
|
|
|
"AS path access list name\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
ALIAS_YANG (no_set_aspath_exclude, no_set_aspath_exclude_all_cmd,
|
|
|
|
"no set as-path exclude",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"Transform BGP AS_PATH attribute\n"
|
|
|
|
"Exclude from the as-path\n")
|
2008-04-10 13:47:45 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_community,
|
|
|
|
set_community_cmd,
|
|
|
|
"set community AA:NN...",
|
|
|
|
SET_STR
|
|
|
|
"BGP community attribute\n"
|
|
|
|
COMMUNITY_VAL_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-30 02:16:31 +02:00
|
|
|
int idx_aa_nn = 2;
|
2002-12-13 21:15:29 +01:00
|
|
|
int i;
|
|
|
|
int first = 0;
|
|
|
|
int additive = 0;
|
|
|
|
struct buffer *b;
|
|
|
|
struct community *com = NULL;
|
|
|
|
char *str;
|
2020-10-30 08:45:43 +01:00
|
|
|
char *argstr = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
int ret;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-community']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:community-string",
|
|
|
|
xpath);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
b = buffer_new(1024);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-09-30 02:16:31 +02:00
|
|
|
for (i = idx_aa_nn; i < argc; i++) {
|
2016-09-22 17:15:50 +02:00
|
|
|
if (strncmp(argv[i]->arg, "additive", strlen(argv[i]->arg))
|
|
|
|
== 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
additive = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (first)
|
|
|
|
buffer_putc(b, ' ');
|
|
|
|
else
|
|
|
|
first = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-09-22 17:15:50 +02:00
|
|
|
if (strncmp(argv[i]->arg, "local-AS", strlen(argv[i]->arg))
|
|
|
|
== 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
buffer_putstr(b, "local-AS");
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-22 17:15:50 +02:00
|
|
|
if (strncmp(argv[i]->arg, "no-a", strlen("no-a")) == 0
|
|
|
|
&& strncmp(argv[i]->arg, "no-advertise",
|
|
|
|
strlen(argv[i]->arg))
|
|
|
|
== 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
buffer_putstr(b, "no-advertise");
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-22 17:15:50 +02:00
|
|
|
if (strncmp(argv[i]->arg, "no-e", strlen("no-e")) == 0
|
|
|
|
&& strncmp(argv[i]->arg, "no-export", strlen(argv[i]->arg))
|
|
|
|
== 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
buffer_putstr(b, "no-export");
|
|
|
|
continue;
|
|
|
|
}
|
2021-01-21 14:03:40 +01:00
|
|
|
if (strncmp(argv[i]->arg, "blackhole", strlen(argv[i]->arg))
|
|
|
|
== 0) {
|
|
|
|
buffer_putstr(b, "blackhole");
|
|
|
|
continue;
|
|
|
|
}
|
2018-02-09 19:22:50 +01:00
|
|
|
if (strncmp(argv[i]->arg, "graceful-shutdown",
|
|
|
|
strlen(argv[i]->arg))
|
2017-08-25 20:27:49 +02:00
|
|
|
== 0) {
|
|
|
|
buffer_putstr(b, "graceful-shutdown");
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-22 17:15:50 +02:00
|
|
|
buffer_putstr(b, argv[i]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
buffer_putc(b, '\0');
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Fetch result string then compile it to communities attribute. */
|
|
|
|
str = buffer_getstr(b);
|
|
|
|
buffer_free(b);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-04-08 21:57:47 +02:00
|
|
|
if (str)
|
2002-12-13 21:15:29 +01:00
|
|
|
com = community_str2com(str);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Can't compile user input into communities attribute. */
|
|
|
|
if (!com) {
|
2022-04-08 21:57:47 +02:00
|
|
|
vty_out(vty, "%% Malformed communities attribute '%s'\n", str);
|
|
|
|
XFREE(MTYPE_TMP, str);
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2022-04-08 21:57:47 +02:00
|
|
|
XFREE(MTYPE_TMP, str);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set communites attribute string. */
|
2022-04-08 21:57:47 +02:00
|
|
|
str = community_str(com, false, false);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (additive) {
|
2019-05-06 23:05:06 +02:00
|
|
|
size_t argstr_sz = strlen(str) + strlen(" additive") + 1;
|
|
|
|
argstr = XCALLOC(MTYPE_TMP, argstr_sz);
|
|
|
|
strlcpy(argstr, str, argstr_sz);
|
|
|
|
strlcat(argstr, " additive", argstr_sz);
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argstr);
|
2002-12-13 21:15:29 +01:00
|
|
|
} else
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
if (argstr)
|
|
|
|
XFREE(MTYPE_TMP, argstr);
|
2018-10-22 21:58:39 +02:00
|
|
|
community_free(&com);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_community_none,
|
|
|
|
set_community_none_cmd,
|
|
|
|
"set community none",
|
|
|
|
SET_STR
|
|
|
|
"BGP community attribute\n"
|
|
|
|
"No community attribute\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-community']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:community-none", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_community,
|
|
|
|
no_set_community_cmd,
|
|
|
|
"no set community AA:NN...",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP community attribute\n"
|
|
|
|
COMMUNITY_VAL_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-community']";
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
2018-12-16 19:54:41 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
ALIAS_YANG (no_set_community,
|
|
|
|
no_set_community_short_cmd,
|
|
|
|
"no set community",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP community attribute\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (set_community_delete,
|
2002-12-13 21:15:29 +01:00
|
|
|
set_community_delete_cmd,
|
2021-10-19 14:14:19 +02:00
|
|
|
"set comm-list <(1-99)|(100-500)|COMMUNITY_LIST_NAME> delete",
|
2002-12-13 21:15:29 +01:00
|
|
|
SET_STR
|
|
|
|
"set BGP community list (for deletion)\n"
|
|
|
|
"Community-list number (standard)\n"
|
2015-05-20 02:47:22 +02:00
|
|
|
"Community-list number (expanded)\n"
|
2002-12-13 21:15:29 +01:00
|
|
|
"Community-list name\n"
|
|
|
|
"Delete matching communities\n")
|
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:comm-list-delete']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_comm_list = 2;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_comm_list]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_community_delete,
|
|
|
|
no_set_community_delete_cmd,
|
2021-10-19 14:14:19 +02:00
|
|
|
"no set comm-list [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> delete]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"set BGP community list (for deletion)\n"
|
|
|
|
"Community-list number (standard)\n"
|
|
|
|
"Community-list number (expanded)\n"
|
|
|
|
"Community-list name\n"
|
|
|
|
"Delete matching communities\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:comm-list-delete']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_lcommunity,
|
|
|
|
set_lcommunity_cmd,
|
|
|
|
"set large-community AA:BB:CC...",
|
|
|
|
SET_STR
|
|
|
|
"BGP large community attribute\n"
|
|
|
|
"Large Community number in aa:bb:cc format or additive\n")
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
|
|
|
char *str;
|
2020-10-30 08:45:43 +01:00
|
|
|
int ret;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-large-community']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:large-community-string",
|
|
|
|
xpath);
|
2016-11-15 11:00:39 +01:00
|
|
|
str = argv_concat(argv, argc, 2);
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_lcommunity_none,
|
|
|
|
set_lcommunity_none_cmd,
|
|
|
|
"set large-community none",
|
|
|
|
SET_STR
|
|
|
|
"BGP large community attribute\n"
|
|
|
|
"No large community attribute\n")
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-large-community']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:large-community-none",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_lcommunity,
|
|
|
|
no_set_lcommunity_cmd,
|
|
|
|
"no set large-community none",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP large community attribute\n"
|
|
|
|
"No community attribute\n")
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-large-community']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_lcommunity1,
|
|
|
|
no_set_lcommunity1_cmd,
|
|
|
|
"no set large-community AA:BB:CC...",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP large community attribute\n"
|
|
|
|
"Large community in AA:BB:CC... format or additive\n")
|
2017-01-20 16:43:08 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-large-community']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-01-20 16:43:08 +01:00
|
|
|
}
|
2016-11-15 11:00:39 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
ALIAS_YANG (no_set_lcommunity1,
|
|
|
|
no_set_lcommunity1_short_cmd,
|
|
|
|
"no set large-community",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP large community attribute\n")
|
2018-12-19 13:30:01 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (set_lcommunity_delete,
|
2016-11-15 11:00:39 +01:00
|
|
|
set_lcommunity_delete_cmd,
|
2021-10-19 14:14:19 +02:00
|
|
|
"set large-comm-list <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> delete",
|
2016-11-15 11:00:39 +01:00
|
|
|
SET_STR
|
|
|
|
"set BGP large community list (for deletion)\n"
|
|
|
|
"Large Community-list number (standard)\n"
|
|
|
|
"Large Communitly-list number (expanded)\n"
|
|
|
|
"Large Community-list name\n"
|
|
|
|
"Delete matching large communities\n")
|
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:large-comm-list-delete']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2019-06-26 14:06:10 +02:00
|
|
|
int idx_lcomm_list = 2;
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_lcomm_list]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_lcommunity_delete,
|
|
|
|
no_set_lcommunity_delete_cmd,
|
2021-10-19 14:14:19 +02:00
|
|
|
"no set large-comm-list <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [delete]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"set BGP large community list (for deletion)\n"
|
|
|
|
"Large Community-list number (standard)\n"
|
|
|
|
"Large Communitly-list number (expanded)\n"
|
|
|
|
"Large Community-list name\n"
|
|
|
|
"Delete matching large communities\n")
|
2016-11-15 11:00:39 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:large-comm-list-delete']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-11-15 11:00:39 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
ALIAS_YANG (no_set_lcommunity_delete,
|
|
|
|
no_set_lcommunity_delete_short_cmd,
|
|
|
|
"no set large-comm-list",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"set BGP large community list (for deletion)\n")
|
2018-12-19 13:30:01 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_ecommunity_rt,
|
|
|
|
set_ecommunity_rt_cmd,
|
|
|
|
"set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Route Target extended community\n"
|
|
|
|
"VPN extended community\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-30 02:16:31 +02:00
|
|
|
int idx_asn_nn = 3;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *str;
|
2020-10-30 08:45:43 +01:00
|
|
|
int ret;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-rt']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-rt", xpath);
|
2016-09-30 02:16:31 +02:00
|
|
|
str = argv_concat(argv, argc, idx_asn_nn);
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_ecommunity_rt,
|
|
|
|
no_set_ecommunity_rt_cmd,
|
|
|
|
"no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Route Target extended community\n"
|
|
|
|
"VPN extended community\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-rt']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
ALIAS_YANG (no_set_ecommunity_rt,
|
|
|
|
no_set_ecommunity_rt_short_cmd,
|
|
|
|
"no set extcommunity rt",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Route Target extended community\n")
|
|
|
|
|
|
|
|
DEFUN_YANG (set_ecommunity_soo,
|
|
|
|
set_ecommunity_soo_cmd,
|
|
|
|
"set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Site-of-Origin extended community\n"
|
|
|
|
"VPN extended community\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-30 02:16:31 +02:00
|
|
|
int idx_asn_nn = 3;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *str;
|
2020-10-30 08:45:43 +01:00
|
|
|
int ret;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-soo']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-soo",
|
|
|
|
xpath);
|
2016-09-30 02:16:31 +02:00
|
|
|
str = argv_concat(argv, argc, idx_asn_nn);
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_ecommunity_soo,
|
|
|
|
no_set_ecommunity_soo_cmd,
|
|
|
|
"no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Site-of-Origin extended community\n"
|
|
|
|
"VPN extended community\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-soo']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
ALIAS_YANG (no_set_ecommunity_soo,
|
|
|
|
no_set_ecommunity_soo_short_cmd,
|
|
|
|
"no set extcommunity soo",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"GP extended community attribute\n"
|
|
|
|
"Site-of-Origin extended community\n")
|
|
|
|
|
2021-08-02 21:27:55 +02:00
|
|
|
DEFUN_YANG(set_ecommunity_none, set_ecommunity_none_cmd,
|
|
|
|
"set extcommunity none",
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"No extended community attribute\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-none']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-none",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG(no_set_ecommunity_none, no_set_ecommunity_none_cmd,
|
|
|
|
"no set extcommunity none",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"No extended community attribute\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-none']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_ecommunity_lb,
|
|
|
|
set_ecommunity_lb_cmd,
|
2024-04-10 09:16:01 +02:00
|
|
|
"set extcommunity bandwidth <(1-4294967295)|cumulative|num-multipaths> [non-transitive]",
|
2020-10-30 08:45:43 +01:00
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Link bandwidth extended community\n"
|
|
|
|
"Bandwidth value in Mbps\n"
|
|
|
|
"Cumulative bandwidth of all multipaths (outbound-only)\n"
|
|
|
|
"Internally computed bandwidth based on number of multipaths (outbound-only)\n"
|
|
|
|
"Attribute is set as non-transitive\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
int idx_lb = 3;
|
2021-08-03 13:25:01 +02:00
|
|
|
int idx_non_transitive = 0;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-lb']";
|
|
|
|
char xpath_lb_type[XPATH_MAXLEN];
|
|
|
|
char xpath_bandwidth[XPATH_MAXLEN];
|
|
|
|
char xpath_non_transitive[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_lb_type, sizeof(xpath_lb_type),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type",
|
|
|
|
xpath);
|
|
|
|
snprintf(xpath_bandwidth, sizeof(xpath_bandwidth),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth",
|
|
|
|
xpath);
|
|
|
|
snprintf(xpath_non_transitive, sizeof(xpath_non_transitive),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific",
|
|
|
|
xpath);
|
|
|
|
|
|
|
|
if ((strcmp(argv[idx_lb]->arg, "cumulative")) == 0)
|
|
|
|
nb_cli_enqueue_change(vty, xpath_lb_type, NB_OP_MODIFY,
|
|
|
|
"cumulative-bandwidth");
|
|
|
|
else if ((strcmp(argv[idx_lb]->arg, "num-multipaths")) == 0)
|
|
|
|
nb_cli_enqueue_change(vty, xpath_lb_type, NB_OP_MODIFY,
|
|
|
|
"computed-bandwidth");
|
|
|
|
else {
|
|
|
|
nb_cli_enqueue_change(vty, xpath_lb_type, NB_OP_MODIFY,
|
|
|
|
"explicit-bandwidth");
|
|
|
|
nb_cli_enqueue_change(vty, xpath_bandwidth, NB_OP_MODIFY,
|
|
|
|
argv[idx_lb]->arg);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-08-03 13:25:01 +02:00
|
|
|
if (argv_find(argv, argc, "non-transitive", &idx_non_transitive))
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_non_transitive, NB_OP_MODIFY,
|
|
|
|
"true");
|
|
|
|
else
|
|
|
|
nb_cli_enqueue_change(vty, xpath_non_transitive, NB_OP_MODIFY,
|
|
|
|
"false");
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_set_ecommunity_lb,
|
|
|
|
no_set_ecommunity_lb_cmd,
|
2024-04-10 09:16:01 +02:00
|
|
|
"no set extcommunity bandwidth <(1-4294967295)|cumulative|num-multipaths> [non-transitive]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Link bandwidth extended community\n"
|
|
|
|
"Bandwidth value in Mbps\n"
|
|
|
|
"Cumulative bandwidth of all multipaths (outbound-only)\n"
|
|
|
|
"Internally computed bandwidth based on number of multipaths (outbound-only)\n"
|
|
|
|
"Attribute is set as non-transitive\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-lb']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
ALIAS_YANG (no_set_ecommunity_lb,
|
|
|
|
no_set_ecommunity_lb_short_cmd,
|
|
|
|
"no set extcommunity bandwidth",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Link bandwidth extended community\n")
|
|
|
|
|
bgpd: Implement Node Target Extended Communities
kttps://datatracker.ietf.org/doc/html/draft-ietf-idr-node-target-ext-comm
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.2 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.3 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r2 vtysh -c 'show ip bgp 10.10.10.10/32'
% Network not in table
unet> sh r3 vtysh -c 'show ip bgp 10.10.10.10/32'
BGP routing table entry for 10.10.10.10/32, version 1
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.1.1
65001
192.168.1.1 from 192.168.1.1 (192.168.1.1)
Origin IGP, metric 0, valid, external, best (First path received)
Extended Community: NT:192.168.1.3 NT:192.168.1.4
Last update: Tue Apr 11 23:19:33 2023
unet>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-04-05 14:51:45 +02:00
|
|
|
DEFPY_YANG (set_ecommunity_nt,
|
|
|
|
set_ecommunity_nt_cmd,
|
|
|
|
"set extcommunity nt RTLIST...",
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Node Target extended community\n"
|
|
|
|
"Node Target ID\n")
|
|
|
|
{
|
|
|
|
int idx_nt = 3;
|
|
|
|
char *str;
|
|
|
|
int ret;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-nt']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-nt", xpath);
|
|
|
|
str = argv_concat(argv, argc, idx_nt);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG (no_set_ecommunity_nt,
|
|
|
|
no_set_ecommunity_nt_cmd,
|
|
|
|
"no set extcommunity nt RTLIST...",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Node Target extended community\n"
|
|
|
|
"Node Target ID\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-nt']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2023-05-22 15:36:06 +02:00
|
|
|
DEFPY_YANG(set_ecommunity_color, set_ecommunity_color_cmd,
|
|
|
|
"set extcommunity color RTLIST...",
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Color extended community\n"
|
|
|
|
"Color ID\n")
|
|
|
|
{
|
|
|
|
int idx_color = 3;
|
|
|
|
char *str;
|
|
|
|
int ret;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-color']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:extcommunity-color",
|
|
|
|
xpath);
|
|
|
|
str = argv_concat(argv, argc, idx_color);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
|
|
|
|
ret = nb_cli_apply_changes(vty, NULL);
|
|
|
|
XFREE(MTYPE_TMP, str);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG(no_set_ecommunity_color_all, no_set_ecommunity_color_all_cmd,
|
|
|
|
"no set extcommunity color",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Color extended community\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-color']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG(no_set_ecommunity_color, no_set_ecommunity_color_cmd,
|
|
|
|
"no set extcommunity color RTLIST...",
|
|
|
|
NO_STR SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Color extended community\n"
|
|
|
|
"Color ID\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-extcommunity-color']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
bgpd: Implement Node Target Extended Communities
kttps://datatracker.ietf.org/doc/html/draft-ietf-idr-node-target-ext-comm
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.2 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.3 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r2 vtysh -c 'show ip bgp 10.10.10.10/32'
% Network not in table
unet> sh r3 vtysh -c 'show ip bgp 10.10.10.10/32'
BGP routing table entry for 10.10.10.10/32, version 1
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.1.1
65001
192.168.1.1 from 192.168.1.1 (192.168.1.1)
Origin IGP, metric 0, valid, external, best (First path received)
Extended Community: NT:192.168.1.3 NT:192.168.1.4
Last update: Tue Apr 11 23:19:33 2023
unet>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-04-05 14:51:45 +02:00
|
|
|
ALIAS_YANG (no_set_ecommunity_nt,
|
|
|
|
no_set_ecommunity_nt_short_cmd,
|
|
|
|
"no set extcommunity nt",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP extended community attribute\n"
|
|
|
|
"Node Target extended community\n")
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_origin,
|
|
|
|
set_origin_cmd,
|
|
|
|
"set origin <egp|igp|incomplete>",
|
|
|
|
SET_STR
|
|
|
|
"BGP origin code\n"
|
|
|
|
"remote EGP\n"
|
|
|
|
"local IGP\n"
|
|
|
|
"unknown heritage\n")
|
2020-03-24 19:50:44 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
int idx_origin = 2;
|
|
|
|
const char *origin_type;
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-origin']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
if (strncmp(argv[idx_origin]->arg, "igp", 2) == 0)
|
|
|
|
origin_type = "igp";
|
|
|
|
else if (strncmp(argv[idx_origin]->arg, "egp", 1) == 0)
|
|
|
|
origin_type = "egp";
|
|
|
|
else if (strncmp(argv[idx_origin]->arg, "incomplete", 2) == 0)
|
|
|
|
origin_type = "incomplete";
|
|
|
|
else {
|
|
|
|
vty_out(vty, "%% Invalid match origin type\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:origin", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, origin_type);
|
2020-03-24 19:50:44 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2020-03-24 19:50:44 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_origin,
|
|
|
|
no_set_origin_cmd,
|
|
|
|
"no set origin [<egp|igp|incomplete>]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP origin code\n"
|
|
|
|
"remote EGP\n"
|
|
|
|
"local IGP\n"
|
|
|
|
"unknown heritage\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:set-origin']";
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_atomic_aggregate,
|
|
|
|
set_atomic_aggregate_cmd,
|
|
|
|
"set atomic-aggregate",
|
|
|
|
SET_STR
|
|
|
|
"BGP atomic aggregate attribute\n" )
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:atomic-aggregate']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:atomic-aggregate",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_atomic_aggregate,
|
|
|
|
no_set_atomic_aggregate_cmd,
|
|
|
|
"no set atomic-aggregate",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP atomic aggregate attribute\n" )
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:atomic-aggregate']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2022-10-12 20:06:47 +02:00
|
|
|
DEFPY_YANG (set_aigp_metric,
|
|
|
|
set_aigp_metric_cmd,
|
|
|
|
"set aigp-metric <igp-metric|(1-4294967295)>$aigp_metric",
|
|
|
|
SET_STR
|
|
|
|
"BGP AIGP attribute (AIGP Metric TLV)\n"
|
|
|
|
"AIGP Metric value from IGP protocol\n"
|
|
|
|
"Manual AIGP Metric value\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:aigp-metric']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:aigp-metric", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, aigp_metric);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG (no_set_aigp_metric,
|
|
|
|
no_set_aigp_metric_cmd,
|
|
|
|
"no set aigp-metric [<igp-metric|(1-4294967295)>]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP AIGP attribute (AIGP Metric TLV)\n"
|
|
|
|
"AIGP Metric value from IGP protocol\n"
|
|
|
|
"Manual AIGP Metric value\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:aigp-metric']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_aggregator_as,
|
|
|
|
set_aggregator_as_cmd,
|
2022-11-02 18:17:21 +01:00
|
|
|
"set aggregator as ASNUM A.B.C.D",
|
2020-10-30 08:45:43 +01:00
|
|
|
SET_STR
|
|
|
|
"BGP aggregator attribute\n"
|
|
|
|
"AS number of aggregator\n"
|
2022-11-02 18:17:21 +01:00
|
|
|
AS_STR
|
2020-10-30 08:45:43 +01:00
|
|
|
"IP address of aggregator\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_number = 3;
|
|
|
|
int idx_ipv4 = 4;
|
2020-10-30 08:45:43 +01:00
|
|
|
char xpath_asn[XPATH_MAXLEN];
|
|
|
|
char xpath_addr[XPATH_MAXLEN];
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:aggregator']";
|
2022-11-02 18:17:21 +01:00
|
|
|
as_t as_value;
|
|
|
|
|
|
|
|
if (!asn_str2asn(argv[idx_number]->arg, &as_value)) {
|
|
|
|
vty_out(vty, "%% Invalid AS value %s\n", argv[idx_number]->arg);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(
|
|
|
|
xpath_asn, sizeof(xpath_asn),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_asn, NB_OP_MODIFY,
|
|
|
|
argv[idx_number]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
snprintf(
|
|
|
|
xpath_addr, sizeof(xpath_addr),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_addr, NB_OP_MODIFY,
|
|
|
|
argv[idx_ipv4]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_aggregator_as,
|
|
|
|
no_set_aggregator_as_cmd,
|
2022-11-02 18:17:21 +01:00
|
|
|
"no set aggregator as [ASNUM A.B.C.D]",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP aggregator attribute\n"
|
|
|
|
"AS number of aggregator\n"
|
2022-11-02 18:17:21 +01:00
|
|
|
AS_STR
|
2020-10-30 08:45:43 +01:00
|
|
|
"IP address of aggregator\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:aggregator']";
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
DEFUN_YANG (match_ipv6_next_hop_address,
|
|
|
|
match_ipv6_next_hop_address_cmd,
|
2021-11-19 19:11:52 +01:00
|
|
|
"match ipv6 next-hop address X:X::X:X",
|
2020-10-30 08:45:43 +01:00
|
|
|
MATCH_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Match IPv6 next-hop address of route\n"
|
2021-11-19 19:11:52 +01:00
|
|
|
"IPv6 address\n"
|
2020-10-30 08:45:43 +01:00
|
|
|
"IPv6 address of next hop\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:ipv6-address",
|
|
|
|
xpath);
|
2021-11-22 20:26:33 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[argc - 1]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
DEFUN_YANG (no_match_ipv6_next_hop_address,
|
|
|
|
no_match_ipv6_next_hop_address_cmd,
|
2021-11-19 19:11:52 +01:00
|
|
|
"no match ipv6 next-hop address X:X::X:X",
|
2020-10-30 08:45:43 +01:00
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Match IPv6 next-hop address of route\n"
|
2021-11-19 19:11:52 +01:00
|
|
|
"IPv6 address\n"
|
2020-10-30 08:45:43 +01:00
|
|
|
"IPv6 address of next hop\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']";
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
ALIAS_HIDDEN (match_ipv6_next_hop_address,
|
2021-11-19 19:11:52 +01:00
|
|
|
match_ipv6_next_hop_old_cmd,
|
|
|
|
"match ipv6 next-hop X:X::X:X",
|
|
|
|
MATCH_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Match IPv6 next-hop address of route\n"
|
|
|
|
"IPv6 address of next hop\n")
|
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
ALIAS_HIDDEN (no_match_ipv6_next_hop_address,
|
2021-11-19 19:11:52 +01:00
|
|
|
no_match_ipv6_next_hop_old_cmd,
|
|
|
|
"no match ipv6 next-hop X:X::X:X",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Match IPv6 next-hop address of route\n"
|
|
|
|
"IPv6 address of next hop\n")
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (match_ipv4_next_hop,
|
2020-03-09 16:13:19 +01:00
|
|
|
match_ipv4_next_hop_cmd,
|
2020-06-02 18:23:09 +02:00
|
|
|
"match ip next-hop address A.B.C.D",
|
2020-03-09 16:13:19 +01:00
|
|
|
MATCH_STR
|
|
|
|
IP_STR
|
|
|
|
"Match IP next-hop address of route\n"
|
|
|
|
"IP address\n"
|
|
|
|
"IP address of next-hop\n")
|
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ipv4-nexthop']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:ipv4-address",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[4]->arg);
|
2020-03-09 16:13:19 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2020-06-02 18:23:09 +02:00
|
|
|
}
|
2020-03-09 16:13:19 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFPY_YANG (no_match_ipv4_next_hop,
|
2020-06-02 18:23:09 +02:00
|
|
|
no_match_ipv4_next_hop_cmd,
|
|
|
|
"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")
|
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:ipv4-nexthop']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2020-03-09 16:13:19 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_ipv6_nexthop_peer,
|
|
|
|
set_ipv6_nexthop_peer_cmd,
|
|
|
|
"set ipv6 next-hop peer-address",
|
|
|
|
SET_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Next hop address\n"
|
|
|
|
"Use peer address (for BGP only)\n")
|
2015-05-20 02:24:45 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-peer-address']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:preference", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2015-05-20 02:24:45 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_ipv6_nexthop_peer,
|
|
|
|
no_set_ipv6_nexthop_peer_cmd,
|
|
|
|
"no set ipv6 next-hop peer-address",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
IPV6_STR
|
|
|
|
"IPv6 next-hop address\n"
|
|
|
|
"Use peer address (for BGP only)\n")
|
2015-05-20 02:24:45 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-peer-address']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2015-05-20 02:24:45 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_ipv6_nexthop_prefer_global,
|
|
|
|
set_ipv6_nexthop_prefer_global_cmd,
|
|
|
|
"set ipv6 next-hop prefer-global",
|
|
|
|
SET_STR
|
|
|
|
IPV6_STR
|
|
|
|
"IPv6 next-hop address\n"
|
|
|
|
"Prefer global over link-local if both exist\n")
|
2016-08-03 15:49:09 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-prefer-global']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:preference", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-08-03 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_ipv6_nexthop_prefer_global,
|
|
|
|
no_set_ipv6_nexthop_prefer_global_cmd,
|
|
|
|
"no set ipv6 next-hop prefer-global",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
IPV6_STR
|
|
|
|
"IPv6 next-hop address\n"
|
|
|
|
"Prefer global over link-local if both exist\n")
|
2016-08-03 15:49:09 +02:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-prefer-global']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2016-08-03 15:49:09 +02:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_ipv6_nexthop_global,
|
|
|
|
set_ipv6_nexthop_global_cmd,
|
|
|
|
"set ipv6 next-hop global X:X::X:X",
|
|
|
|
SET_STR
|
|
|
|
IPV6_STR
|
|
|
|
"IPv6 next-hop address\n"
|
|
|
|
"IPv6 global address\n"
|
|
|
|
"IPv6 address of next hop\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_ipv6 = 4;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-nexthop-global']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2015-06-11 18:19:59 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv6-address", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_ipv6]->arg);
|
2015-06-11 18:19:59 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_ipv6_nexthop_global,
|
|
|
|
no_set_ipv6_nexthop_global_cmd,
|
|
|
|
"no set ipv6 next-hop global X:X::X:X",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
IPV6_STR
|
|
|
|
"IPv6 next-hop address\n"
|
|
|
|
"IPv6 global address\n"
|
|
|
|
"IPv6 address of next hop\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-nexthop-global']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
#ifdef KEEP_OLD_VPN_COMMANDS
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_vpn_nexthop,
|
|
|
|
set_vpn_nexthop_cmd,
|
|
|
|
"set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
|
|
|
|
SET_STR
|
|
|
|
"VPNv4 information\n"
|
|
|
|
"VPN next-hop address\n"
|
|
|
|
"IP address of next hop\n"
|
|
|
|
"VPNv6 information\n"
|
|
|
|
"VPN next-hop address\n"
|
|
|
|
"IPv6 address of next hop\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-01-18 12:27:52 +01:00
|
|
|
int idx_ip = 3;
|
|
|
|
afi_t afi;
|
|
|
|
int idx = 0;
|
2021-04-01 03:10:12 +02:00
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
|
2020-10-30 08:45:43 +01:00
|
|
|
if (afi == AFI_IP) {
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv4-address",
|
|
|
|
xpath);
|
|
|
|
} else {
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv6-address",
|
|
|
|
xpath);
|
|
|
|
}
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_ip]->arg);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-01-18 12:27:52 +01:00
|
|
|
}
|
2020-10-30 08:45:43 +01:00
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2016-09-27 15:24:19 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_vpn_nexthop,
|
|
|
|
no_set_vpn_nexthop_cmd,
|
|
|
|
"no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"VPNv4 information\n"
|
|
|
|
"VPN next-hop address\n"
|
|
|
|
"IP address of next hop\n"
|
|
|
|
"VPNv6 information\n"
|
|
|
|
"VPN next-hop address\n"
|
|
|
|
"IPv6 address of next hop\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-01-18 12:27:52 +01:00
|
|
|
afi_t afi;
|
|
|
|
int idx = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
|
2020-10-30 08:45:43 +01:00
|
|
|
if (afi == AFI_IP) {
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
} else {
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
}
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-01-18 12:27:52 +01:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
#endif /* KEEP_OLD_VPN_COMMANDS */
|
|
|
|
|
2022-11-22 13:50:09 +01:00
|
|
|
DEFPY_YANG (set_ipx_vpn_nexthop,
|
2020-10-30 08:45:43 +01:00
|
|
|
set_ipx_vpn_nexthop_cmd,
|
2022-11-22 13:50:09 +01:00
|
|
|
"set <ipv4|ipv6> vpn next-hop <A.B.C.D$addrv4|X:X::X:X$addrv6>",
|
2020-10-30 08:45:43 +01:00
|
|
|
SET_STR
|
|
|
|
"IPv4 information\n"
|
|
|
|
"IPv6 information\n"
|
|
|
|
"VPN information\n"
|
|
|
|
"VPN next-hop address\n"
|
|
|
|
"IP address of next hop\n"
|
|
|
|
"IPv6 address of next hop\n")
|
2017-01-18 12:27:52 +01:00
|
|
|
{
|
|
|
|
int idx_ip = 4;
|
|
|
|
afi_t afi;
|
|
|
|
int idx = 0;
|
2020-10-30 08:45:43 +01:00
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
2020-10-30 08:45:43 +01:00
|
|
|
if (afi == AFI_IP) {
|
2022-11-22 13:50:09 +01:00
|
|
|
if (addrv6_str) {
|
|
|
|
vty_out(vty, "%% IPv4 next-hop expected\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv4-address",
|
|
|
|
xpath);
|
|
|
|
} else {
|
2022-11-22 13:50:09 +01:00
|
|
|
if (addrv4_str) {
|
|
|
|
vty_out(vty, "%% IPv6 next-hop expected\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:ipv6-address",
|
|
|
|
xpath);
|
|
|
|
}
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_ip]->arg);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-01-18 12:27:52 +01:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (no_set_ipx_vpn_nexthop,
|
|
|
|
no_set_ipx_vpn_nexthop_cmd,
|
|
|
|
"no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"IPv4 information\n"
|
|
|
|
"IPv6 information\n"
|
|
|
|
"VPN information\n"
|
|
|
|
"VPN next-hop address\n"
|
|
|
|
"IP address of next hop\n"
|
|
|
|
"IPv6 address of next hop\n")
|
|
|
|
{
|
2017-01-18 12:27:52 +01:00
|
|
|
afi_t afi;
|
|
|
|
int idx = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-01-18 12:27:52 +01:00
|
|
|
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
|
2020-10-30 08:45:43 +01:00
|
|
|
if (afi == AFI_IP) {
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
} else {
|
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
}
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2017-01-18 12:27:52 +01:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
DEFUN_YANG (set_originator_id,
|
|
|
|
set_originator_id_cmd,
|
|
|
|
"set originator-id A.B.C.D",
|
|
|
|
SET_STR
|
|
|
|
"BGP originator ID attribute\n"
|
|
|
|
"IP address of originator\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:45:50 +02:00
|
|
|
int idx_ipv4 = 2;
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:originator-id']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-set-action/frr-bgp-route-map:originator-id", xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[idx_ipv4]->arg);
|
2016-09-27 07:05:12 +02:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_YANG (no_set_originator_id,
|
|
|
|
no_set_originator_id_cmd,
|
|
|
|
"no set originator-id [A.B.C.D]",
|
|
|
|
NO_STR
|
|
|
|
SET_STR
|
|
|
|
"BGP originator ID attribute\n"
|
|
|
|
"IP address of originator\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-30 08:45:43 +01:00
|
|
|
const char *xpath =
|
|
|
|
"./set-action[action='frr-bgp-route-map:originator-id']";
|
2017-01-30 20:49:24 +01:00
|
|
|
|
2020-10-30 08:45:43 +01:00
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2022-08-31 22:00:26 +02:00
|
|
|
DEFPY_YANG (match_rpki_extcommunity,
|
|
|
|
match_rpki_extcommunity_cmd,
|
|
|
|
"[no$no] match rpki-extcommunity <valid|invalid|notfound>",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"BGP RPKI (Origin Validation State) extended community attribute\n"
|
|
|
|
"Valid prefix\n"
|
|
|
|
"Invalid prefix\n"
|
|
|
|
"Prefix not found\n")
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:rpki-extcommunity']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
|
|
|
|
if (!no) {
|
|
|
|
snprintf(
|
|
|
|
xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:rpki-extcommunity",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
|
|
|
argv[2]->arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2023-05-10 22:37:47 +02:00
|
|
|
DEFPY_YANG (match_source_protocol,
|
|
|
|
match_source_protocol_cmd,
|
|
|
|
"match source-protocol " FRR_REDIST_STR_ZEBRA "$proto",
|
|
|
|
MATCH_STR
|
|
|
|
"Match protocol via which the route was learnt\n"
|
|
|
|
FRR_REDIST_HELP_STR_ZEBRA)
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:source-protocol']";
|
|
|
|
char xpath_value[XPATH_MAXLEN];
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
|
|
|
snprintf(xpath_value, sizeof(xpath_value),
|
|
|
|
"%s/rmap-match-condition/frr-bgp-route-map:source-protocol",
|
|
|
|
xpath);
|
|
|
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY_YANG (no_match_source_protocol,
|
|
|
|
no_match_source_protocol_cmd,
|
|
|
|
"no match source-protocol [" FRR_REDIST_STR_ZEBRA "]",
|
|
|
|
NO_STR
|
|
|
|
MATCH_STR
|
|
|
|
"Match protocol via which the route was learnt\n"
|
|
|
|
FRR_REDIST_HELP_STR_ZEBRA)
|
|
|
|
{
|
|
|
|
const char *xpath =
|
|
|
|
"./match-condition[condition='frr-bgp-route-map:source-protocol']";
|
|
|
|
|
|
|
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
|
|
|
|
|
|
|
return nb_cli_apply_changes(vty, NULL);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Initialization of route map. */
|
2005-06-28 14:44:16 +02:00
|
|
|
void bgp_route_map_init(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
route_map_init();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
bgpd: bgpd-table-map.patch
COMMAND:
table-map <route-map-name>
DESCRIPTION:
This feature is used to apply a route-map on route updates from BGP to Zebra.
All the applicable match operations are allowed, such as match on prefix,
next-hop, communities, etc. Set operations for this attach-point are limited
to metric and next-hop only. Any operation of this feature does not affect
BGPs internal RIB.
Supported for ipv4 and ipv6 address families. It works on multi-paths as well,
however, metric setting is based on the best-path only.
IMPLEMENTATION NOTES:
The route-map application at this point is not supposed to modify any of BGP
route's attributes (anything in bgp_info for that matter). To achieve that,
creating a copy of the bgp_attr was inevitable. Implementation tries to keep
the memory footprint low, code comments do point out the rationale behind a
few choices made.
bgp_zebra_announce() was already a big routine, adding this feature would
extend it further. Patch has created a few smaller routines/macros whereever
possible to keep the size of the routine in check without compromising on the
readability of the code/flow inside this routine.
For updating a partially filtered route (with its nexthops), BGP to Zebra
replacement semantic of the next-hops serves the purpose well. However, with
this patch there could be some redundant withdraws each time BGP announces a
route thats (all the nexthops) gets denied by the route-map application.
Handling of this case could be optimized by keeping state with the prefix and
the nexthops in BGP. The patch doesn't optimizing that case, as even with the
redundant withdraws the total number of updates to zebra are still be capped
by the total number of routes in the table.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Pradosh Mohapatra <pmohapat@cumulusnetworks.com>
2015-05-20 02:40:34 +02:00
|
|
|
route_map_add_hook(bgp_route_map_add);
|
|
|
|
route_map_delete_hook(bgp_route_map_delete);
|
|
|
|
route_map_event_hook(bgp_route_map_event);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_interface_hook(generic_match_add);
|
|
|
|
route_map_no_match_interface_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_ip_address_hook(generic_match_add);
|
|
|
|
route_map_no_match_ip_address_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_ip_address_prefix_list_hook(generic_match_add);
|
|
|
|
route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_ip_next_hop_hook(generic_match_add);
|
|
|
|
route_map_no_match_ip_next_hop_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
route_map_match_ipv6_next_hop_hook(generic_match_add);
|
|
|
|
route_map_no_match_ipv6_next_hop_hook(generic_match_delete);
|
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
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);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-09-28 10:51:50 +02:00
|
|
|
route_map_match_ip_next_hop_type_hook(generic_match_add);
|
|
|
|
route_map_no_match_ip_next_hop_type_hook(generic_match_delete);
|
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_ipv6_address_hook(generic_match_add);
|
|
|
|
route_map_no_match_ipv6_address_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
|
|
|
|
route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-09-28 10:51:50 +02:00
|
|
|
route_map_match_ipv6_next_hop_type_hook(generic_match_add);
|
|
|
|
route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete);
|
|
|
|
|
2021-11-24 15:28:31 +01:00
|
|
|
route_map_match_ipv6_next_hop_prefix_list_hook(generic_match_add);
|
|
|
|
route_map_no_match_ipv6_next_hop_prefix_list_hook(generic_match_delete);
|
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_metric_hook(generic_match_add);
|
|
|
|
route_map_no_match_metric_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_match_tag_hook(generic_match_add);
|
|
|
|
route_map_no_match_tag_hook(generic_match_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-01-28 12:59:57 +01:00
|
|
|
route_map_set_srte_color_hook(generic_set_add);
|
|
|
|
route_map_no_set_srte_color_hook(generic_set_delete);
|
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_set_ip_nexthop_hook(generic_set_add);
|
|
|
|
route_map_no_set_ip_nexthop_hook(generic_set_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_set_ipv6_nexthop_local_hook(generic_set_add);
|
|
|
|
route_map_no_set_ipv6_nexthop_local_hook(generic_set_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_set_metric_hook(generic_set_add);
|
|
|
|
route_map_no_set_metric_hook(generic_set_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
route_map_set_tag_hook(generic_set_add);
|
|
|
|
route_map_no_set_tag_hook(generic_set_delete);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
route_map_install_match(&route_match_peer_cmd);
|
2021-07-18 11:14:24 +02:00
|
|
|
route_map_install_match(&route_match_alias_cmd);
|
2015-05-20 02:40:40 +02:00
|
|
|
route_map_install_match(&route_match_local_pref_cmd);
|
2020-11-30 23:01:03 +01:00
|
|
|
#ifdef HAVE_SCRIPTING
|
2020-11-29 22:01:59 +01:00
|
|
|
route_map_install_match(&route_match_script_cmd);
|
2017-11-07 15:14:32 +01:00
|
|
|
#endif
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_match(&route_match_ip_address_cmd);
|
|
|
|
route_map_install_match(&route_match_ip_next_hop_cmd);
|
2005-02-02 17:43:17 +01:00
|
|
|
route_map_install_match(&route_match_ip_route_source_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
|
|
|
|
route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
|
2018-09-28 10:51:50 +02:00
|
|
|
route_map_install_match(&route_match_ip_next_hop_type_cmd);
|
2023-05-10 22:37:47 +02:00
|
|
|
route_map_install_match(&route_match_source_protocol_cmd);
|
2005-02-02 17:43:17 +01:00
|
|
|
route_map_install_match(&route_match_ip_route_source_prefix_list_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_match(&route_match_aspath_cmd);
|
|
|
|
route_map_install_match(&route_match_community_cmd);
|
2016-11-15 11:00:39 +01:00
|
|
|
route_map_install_match(&route_match_lcommunity_cmd);
|
2003-04-19 17:49:49 +02:00
|
|
|
route_map_install_match(&route_match_ecommunity_cmd);
|
2015-05-20 02:40:40 +02:00
|
|
|
route_map_install_match(&route_match_local_pref_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_match(&route_match_metric_cmd);
|
|
|
|
route_map_install_match(&route_match_origin_cmd);
|
2011-11-22 17:15:10 +01:00
|
|
|
route_map_install_match(&route_match_probability_cmd);
|
2015-05-20 02:40:47 +02:00
|
|
|
route_map_install_match(&route_match_interface_cmd);
|
2015-05-20 02:46:33 +02:00
|
|
|
route_map_install_match(&route_match_tag_cmd);
|
2017-06-21 10:02:46 +02:00
|
|
|
route_map_install_match(&route_match_mac_address_cmd);
|
2017-06-21 11:00:24 +02:00
|
|
|
route_map_install_match(&route_match_evpn_vni_cmd);
|
2018-01-27 02:16:48 +01:00
|
|
|
route_map_install_match(&route_match_evpn_route_type_cmd);
|
2019-11-13 01:51:24 +01:00
|
|
|
route_map_install_match(&route_match_evpn_rd_cmd);
|
2018-02-22 07:02:07 +01:00
|
|
|
route_map_install_match(&route_match_evpn_default_route_cmd);
|
2019-02-15 03:07:27 +01:00
|
|
|
route_map_install_match(&route_match_vrl_source_vrf_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-05-21 11:04:00 +02:00
|
|
|
route_map_install_set(&route_set_evpn_gateway_ip_ipv4_cmd);
|
|
|
|
route_map_install_set(&route_set_evpn_gateway_ip_ipv6_cmd);
|
2019-04-29 15:26:01 +02:00
|
|
|
route_map_install_set(&route_set_table_id_cmd);
|
2020-01-28 12:59:57 +01:00
|
|
|
route_map_install_set(&route_set_srte_color_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_ip_nexthop_cmd);
|
|
|
|
route_map_install_set(&route_set_local_pref_cmd);
|
|
|
|
route_map_install_set(&route_set_weight_cmd);
|
2017-06-02 21:22:53 +02:00
|
|
|
route_map_install_set(&route_set_label_index_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_metric_cmd);
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
route_map_install_set(&route_set_distance_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_aspath_prepend_cmd);
|
2008-04-10 13:47:45 +02:00
|
|
|
route_map_install_set(&route_set_aspath_exclude_cmd);
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
route_map_install_set(&route_set_aspath_replace_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_origin_cmd);
|
|
|
|
route_map_install_set(&route_set_atomic_aggregate_cmd);
|
2022-10-12 20:06:47 +02:00
|
|
|
route_map_install_set(&route_set_aigp_metric_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_aggregator_as_cmd);
|
|
|
|
route_map_install_set(&route_set_community_cmd);
|
|
|
|
route_map_install_set(&route_set_community_delete_cmd);
|
2023-06-14 16:16:55 +02:00
|
|
|
route_map_install_set(&route_set_ecommunity_delete_cmd);
|
2016-11-15 11:00:39 +01:00
|
|
|
route_map_install_set(&route_set_lcommunity_cmd);
|
|
|
|
route_map_install_set(&route_set_lcommunity_delete_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_vpnv4_nexthop_cmd);
|
2017-01-18 12:27:52 +01:00
|
|
|
route_map_install_set(&route_set_vpnv6_nexthop_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_originator_id_cmd);
|
|
|
|
route_map_install_set(&route_set_ecommunity_rt_cmd);
|
bgpd: Implement Node Target Extended Communities
kttps://datatracker.ietf.org/doc/html/draft-ietf-idr-node-target-ext-comm
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.2 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.3 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r2 vtysh -c 'show ip bgp 10.10.10.10/32'
% Network not in table
unet> sh r3 vtysh -c 'show ip bgp 10.10.10.10/32'
BGP routing table entry for 10.10.10.10/32, version 1
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.1.1
65001
192.168.1.1 from 192.168.1.1 (192.168.1.1)
Origin IGP, metric 0, valid, external, best (First path received)
Extended Community: NT:192.168.1.3 NT:192.168.1.4
Last update: Tue Apr 11 23:19:33 2023
unet>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-04-05 14:51:45 +02:00
|
|
|
route_map_install_set(&route_set_ecommunity_nt_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_ecommunity_soo_cmd);
|
2020-03-24 19:50:44 +01:00
|
|
|
route_map_install_set(&route_set_ecommunity_lb_cmd);
|
2023-05-22 15:36:06 +02:00
|
|
|
route_map_install_set(&route_set_ecommunity_color_cmd);
|
2021-08-02 21:27:55 +02:00
|
|
|
route_map_install_set(&route_set_ecommunity_none_cmd);
|
2015-05-20 02:46:33 +02:00
|
|
|
route_map_install_set(&route_set_tag_cmd);
|
2017-06-02 21:22:53 +02:00
|
|
|
route_map_install_set(&route_set_label_index_cmd);
|
bgpd: add resolution for l3vpn traffic over gre interfaces
When a route imported from l3vpn is analysed, the nexthop from default
VRF is looked up against a valid MPLS path. Generally, this is done on
backbones with a MPLS signalisation transport layer like LDP. Generally,
the BGP connection is multiple hops away. That scenario is already
working.
There is case where it is possible to run L3VPN over GRE interfaces, and
where there is no LSP path over that GRE interface: GRE is just here to
tunnel MPLS traffic. On that case, the nexthop given in the path does not
have MPLS path, but should be authorized to convey MPLS traffic provided
that the user permits it via a configuration command.
That commit introduces a new command that can be activated in route-map:
> set l3vpn next-hop encapsulation gre
That command authorizes the nexthop tracking engine to accept paths that
o have a GRE interface as output, independently of the presence of an LSP
path or not.
A configuration example is given below. When bgp incoming vpnv4 updates
are received, the nexthop of NLRI is 192.168.0.2. Based on nexthop
tracking service from zebra, BGP knows that the output interface to reach
192.168.0.2 is r1-gre0. Because that interface is not MPLS based, but is
a GRE tunnel, then the update will be using that nexthop to be installed.
interface r1-gre0
ip address 192.168.0.1/24
exit
router bgp 65500
bgp router-id 1.1.1.1
neighbor 192.168.0.2 remote-as 65500
!
address-family ipv4 unicast
no neighbor 192.168.0.2 activate
exit-address-family
!
address-family ipv4 vpn
neighbor 192.168.0.2 activate
neighbor 192.168.0.2 route-map rmap in
exit-address-family
exit
!
router bgp 65500 vrf vrf1
bgp router-id 1.1.1.1
no bgp network import-check
!
address-family ipv4 unicast
network 10.201.0.0/24
redistribute connected
label vpn export 101
rd vpn export 444:1
rt vpn both 52:100
export vpn
import vpn
exit-address-family
exit
!
route-map rmap permit 1
set l3vpn next-hop encapsulation gre
exit
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2021-09-20 11:50:52 +02:00
|
|
|
route_map_install_set(&route_set_l3vpn_nexthop_encapsulation_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es>
(at Technical University of Madrid as part of Euro6ix Project)
Enhanced Route Server functionality and Route-Maps:
* bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to
support rs-clients. A 'struct bgp_table *rib' has been added to the
first (to mantain a separated RIB for each rs-client) and two new
route-maps have been added to the last (for import/export policies).
Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX},
PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT.
* bgpd/bgpd.c: Modified the functions that create/delete/etc peers in
order to consider the new fields included in 'struct peer' for
supporting rs-clients, i.e. the import/export route-maps and the
'struct bgp_table'.
* bgpd/bgp_route.{ch}: Modified several functions related with
receiving/sending announces in order to support the new Route Server
capabilities.
Function 'bgp_process' has been reorganized, creating an auxiliar
function for best path selection ('bgp_best_selection').
Modified 'bgp_show' and 'bgp_show_route' for displaying information
about any RIB (and not only the main bgp RIB).
Added commands for displaying information about RS-clients RIBs:
'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient
(A.B.C.D|X:X::X:X) X:X::X:X/M', etc
* bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two
new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT})
and 'void *owner' which points to 'struct bgp' or 'struct peer' which
owns the table.
When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set.
* bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and
'no neighbor ... route-server-client' now not only set/unset the flag
PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct
bgp_table' of the peer. Special actions are taken for peer_groups.
Command 'neighbor ... route-map WORD (in|out)' now also supports two
new kinds of route-map: 'import' and 'export'.
Added commands 'clear bgp * rsclient', etc. These commands allow a new
kind of soft_reconfig which affects only the RIB of the specified
RS-client.
Added commands 'show bgp rsclient summary', etc which display a
summary of the rs-clients configured for the corresponding address
family.
* bgpd/bgp_routemap.c: A new match statement is available,
'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in
import/export route-maps, and it matches when the peer who announces
(when used in an import route-map) or is going to receive (when used
in an export route-map) the route is the same than the one specified
in the statement.
For peer-groups the statement matches if the specified peer is member
of the peer-group.
A special version of the command, 'match peer local', matches with
routes originated by the Route Server (defined with 'network ...',
redistributed routes and default-originate).
* lib/routemap.{ch}: Added a new clause 'call NAME' for use in
route-maps. It jumps into the specified route-map and when it returns
the first route-map ends if the called RM returns DENY_MATCH, or
continues in other case.
2004-09-13 07:12:46 +02:00
|
|
|
install_element(RMAP_NODE, &match_peer_cmd);
|
|
|
|
install_element(RMAP_NODE, &match_peer_local_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_peer_cmd);
|
2005-02-02 17:43:17 +01:00
|
|
|
install_element(RMAP_NODE, &match_ip_route_source_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_ip_route_source_cmd);
|
|
|
|
install_element(RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
|
2017-06-21 10:02:46 +02:00
|
|
|
install_element(RMAP_NODE, &match_mac_address_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_mac_address_cmd);
|
2017-06-21 11:00:24 +02:00
|
|
|
install_element(RMAP_NODE, &match_evpn_vni_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
|
2018-01-27 02:16:48 +01:00
|
|
|
install_element(RMAP_NODE, &match_evpn_route_type_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
|
2019-11-13 01:51:24 +01:00
|
|
|
install_element(RMAP_NODE, &match_evpn_rd_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_evpn_rd_cmd);
|
2018-02-22 07:02:07 +01:00
|
|
|
install_element(RMAP_NODE, &match_evpn_default_route_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
|
2021-05-21 11:04:00 +02:00
|
|
|
install_element(RMAP_NODE, &set_evpn_gw_ip_ipv4_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_evpn_gw_ip_ipv4_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_evpn_gw_ip_ipv6_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_evpn_gw_ip_ipv6_cmd);
|
2019-02-15 03:07:27 +01:00
|
|
|
install_element(RMAP_NODE, &match_vrl_source_vrf_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_vrl_source_vrf_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &match_aspath_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_aspath_cmd);
|
2015-05-20 02:40:40 +02:00
|
|
|
install_element(RMAP_NODE, &match_local_pref_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_local_pref_cmd);
|
2021-07-18 11:14:24 +02:00
|
|
|
install_element(RMAP_NODE, &match_alias_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_alias_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &match_community_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_community_cmd);
|
2016-11-15 11:00:39 +01:00
|
|
|
install_element(RMAP_NODE, &match_lcommunity_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_lcommunity_cmd);
|
2003-04-19 17:49:49 +02:00
|
|
|
install_element(RMAP_NODE, &match_ecommunity_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_ecommunity_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &match_origin_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_origin_cmd);
|
2011-11-22 17:15:10 +01:00
|
|
|
install_element(RMAP_NODE, &match_probability_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_probability_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-04-29 15:26:01 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_table_id_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_table_id_cmd);
|
2003-11-02 08:24:40 +01:00
|
|
|
install_element(RMAP_NODE, &set_ip_nexthop_peer_cmd);
|
2015-05-20 03:03:49 +02:00
|
|
|
install_element(RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_local_pref_cmd);
|
bgpd: Create `set distance XXX` command for routemaps
Allow bgp to set a local Administrative distance to use
for installing routes into the rib.
Example:
!
router bgp 9323
bgp router-id 1.2.3.4
neighbor enp0s8 interface remote-as external
!
address-family ipv4 unicast
neighbor enp0s8 route-map DISTANCE in
exit-address-family
!
route-map DISTANCE permit 10
set distance 153
!
line vty
!
end
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued route, r - rejected route
B 0.0.0.0/0 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
K>* 0.0.0.0/0 [0/100] via 10.0.2.2, enp0s3, 00:06:31
B>* 1.1.1.1/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.2/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
B>* 1.1.1.3/32 [153/0] via fe80::a00:27ff:fe84:c2d6, enp0s8, 00:00:06
C>* 10.0.2.0/24 is directly connected, enp0s3, 00:06:31
K>* 169.254.0.0/16 [0/1000] is directly connected, enp0s3, 00:06:31
eva#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-09-13 22:43:16 +02:00
|
|
|
install_element(RMAP_NODE, &set_distance_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_distance_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_local_pref_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_weight_cmd);
|
2017-06-02 21:22:53 +02:00
|
|
|
install_element(RMAP_NODE, &set_label_index_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_weight_cmd);
|
2017-06-02 21:22:53 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_label_index_cmd);
|
2016-10-04 21:21:45 +02:00
|
|
|
install_element(RMAP_NODE, &set_aspath_prepend_asn_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_aspath_prepend_lastas_cmd);
|
2008-04-10 13:47:45 +02:00
|
|
|
install_element(RMAP_NODE, &set_aspath_exclude_cmd);
|
2023-06-13 14:53:03 +02:00
|
|
|
install_element(RMAP_NODE, &set_aspath_exclude_all_cmd);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
install_element(RMAP_NODE, &set_aspath_exclude_access_list_cmd);
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
install_element(RMAP_NODE, &set_aspath_replace_asn_cmd);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
install_element(RMAP_NODE, &set_aspath_replace_access_list_cmd);
|
2024-05-02 22:07:19 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_aspath_prepend_last_as_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_aspath_prepend_as_cmd);
|
2008-04-10 13:47:45 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_aspath_exclude_cmd);
|
2018-11-15 20:57:34 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_aspath_exclude_all_cmd);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to exclude the unwanted as segments, based on an AS path
access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path exclude as-path-access-list RULE
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-12 19:44:02 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_aspath_exclude_access_list_cmd);
|
bgpd: Add `set as-path replace <any|ASN>` cmd for route-maps
```
route-map tstas permit 10
set as-path replace 1
exit
```
Before:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:39:50 2022
```
After:
```
donatas-laptop(config-router-af)# do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 65010 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Mon Apr 25 10:40:16 2022
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-04-25 09:34:36 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_aspath_replace_asn_cmd);
|
bgpd: add set as-path exclude acl-list command
A route-map applied on incoming BGP updates is not able
to replace an unwanted as segments by another one.
unwanted as segment are based on an AS path access-list.
The below configuration illustrates the case:
router bgp 65001
address-family ipv4 unicast
neighbor 192.168.1.2 route-map rule_2 in
exit-address-family
bgp as-path access-list RULE permit ^65
route-map rule_2 permit 10
set as-path replace as-path-access-list RULE 6000
```
BGP routing table entry for 10.10.10.10/32, version 13
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
65000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path received)
```
After:
```
do show ip bgp 10.10.10.10/32
BGP routing table entry for 10.10.10.10/32, version 15
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.10.65
6000 1 2 3 123
192.168.10.65 from 192.168.10.65 (10.10.10.11)
Origin IGP, metric 0, valid, external, best (First path
received)
```
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
2023-07-11 10:03:04 +02:00
|
|
|
install_element(RMAP_NODE, &no_set_aspath_replace_access_list_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_origin_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_origin_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_atomic_aggregate_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_atomic_aggregate_cmd);
|
2022-10-12 20:06:47 +02:00
|
|
|
install_element(RMAP_NODE, &set_aigp_metric_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_aigp_metric_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_aggregator_as_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_aggregator_as_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_community_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_community_none_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_community_cmd);
|
2018-12-16 19:54:41 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_community_short_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_community_delete_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_community_delete_cmd);
|
2016-11-15 11:00:39 +01:00
|
|
|
install_element(RMAP_NODE, &set_lcommunity_cmd);
|
|
|
|
install_element(RMAP_NODE, &set_lcommunity_none_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_lcommunity_cmd);
|
2017-01-20 16:43:08 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_lcommunity1_cmd);
|
2018-12-19 13:30:01 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_lcommunity1_short_cmd);
|
2016-11-15 11:00:39 +01:00
|
|
|
install_element(RMAP_NODE, &set_lcommunity_delete_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_lcommunity_delete_cmd);
|
2018-12-19 13:30:01 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_lcommunity_delete_short_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_rt_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_rt_cmd);
|
2018-12-19 13:22:26 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_rt_short_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_soo_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_soo_cmd);
|
2018-12-19 13:22:26 +01:00
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_soo_short_cmd);
|
2020-03-24 19:50:44 +01:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_lb_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_lb_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_lb_short_cmd);
|
2021-08-02 21:27:55 +02:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_none_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_none_cmd);
|
bgpd: Implement Node Target Extended Communities
kttps://datatracker.ietf.org/doc/html/draft-ietf-idr-node-target-ext-comm
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.2 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r1 vtysh -c 'sh ip bgp nei 192.168.1.3 adver'
BGP table version is 1, local router ID is 192.168.1.1, vrf id 0
Default local pref 100, local AS 65001
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 10.10.10.10/32 0.0.0.0 0 32768 i
Total number of prefixes 1
unet> sh r2 vtysh -c 'show ip bgp 10.10.10.10/32'
% Network not in table
unet> sh r3 vtysh -c 'show ip bgp 10.10.10.10/32'
BGP routing table entry for 10.10.10.10/32, version 1
Paths: (1 available, best #1, table default)
Advertised to non peer-group peers:
192.168.1.1
65001
192.168.1.1 from 192.168.1.1 (192.168.1.1)
Origin IGP, metric 0, valid, external, best (First path received)
Extended Community: NT:192.168.1.3 NT:192.168.1.4
Last update: Tue Apr 11 23:19:33 2023
unet>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-04-05 14:51:45 +02:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_nt_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_nt_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_nt_short_cmd);
|
2023-05-22 15:36:06 +02:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_color_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_color_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_color_all_cmd);
|
2023-06-14 16:16:55 +02:00
|
|
|
install_element(RMAP_NODE, &set_ecommunity_delete_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ecommunity_delete_cmd);
|
2017-01-18 12:27:52 +01:00
|
|
|
#ifdef KEEP_OLD_VPN_COMMANDS
|
|
|
|
install_element(RMAP_NODE, &set_vpn_nexthop_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_vpn_nexthop_cmd);
|
|
|
|
#endif /* KEEP_OLD_VPN_COMMANDS */
|
|
|
|
install_element(RMAP_NODE, &set_ipx_vpn_nexthop_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ipx_vpn_nexthop_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_originator_id_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_originator_id_cmd);
|
bgpd: add resolution for l3vpn traffic over gre interfaces
When a route imported from l3vpn is analysed, the nexthop from default
VRF is looked up against a valid MPLS path. Generally, this is done on
backbones with a MPLS signalisation transport layer like LDP. Generally,
the BGP connection is multiple hops away. That scenario is already
working.
There is case where it is possible to run L3VPN over GRE interfaces, and
where there is no LSP path over that GRE interface: GRE is just here to
tunnel MPLS traffic. On that case, the nexthop given in the path does not
have MPLS path, but should be authorized to convey MPLS traffic provided
that the user permits it via a configuration command.
That commit introduces a new command that can be activated in route-map:
> set l3vpn next-hop encapsulation gre
That command authorizes the nexthop tracking engine to accept paths that
o have a GRE interface as output, independently of the presence of an LSP
path or not.
A configuration example is given below. When bgp incoming vpnv4 updates
are received, the nexthop of NLRI is 192.168.0.2. Based on nexthop
tracking service from zebra, BGP knows that the output interface to reach
192.168.0.2 is r1-gre0. Because that interface is not MPLS based, but is
a GRE tunnel, then the update will be using that nexthop to be installed.
interface r1-gre0
ip address 192.168.0.1/24
exit
router bgp 65500
bgp router-id 1.1.1.1
neighbor 192.168.0.2 remote-as 65500
!
address-family ipv4 unicast
no neighbor 192.168.0.2 activate
exit-address-family
!
address-family ipv4 vpn
neighbor 192.168.0.2 activate
neighbor 192.168.0.2 route-map rmap in
exit-address-family
exit
!
router bgp 65500 vrf vrf1
bgp router-id 1.1.1.1
no bgp network import-check
!
address-family ipv4 unicast
network 10.201.0.0/24
redistribute connected
label vpn export 101
rd vpn export 444:1
rt vpn both 52:100
export vpn
import vpn
exit-address-family
exit
!
route-map rmap permit 1
set l3vpn next-hop encapsulation gre
exit
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2021-09-20 11:50:52 +02:00
|
|
|
install_element(RMAP_NODE, &set_l3vpn_nexthop_encapsulation_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_match(&route_match_ipv6_address_cmd);
|
|
|
|
route_map_install_match(&route_match_ipv6_next_hop_cmd);
|
2021-11-22 20:26:33 +01:00
|
|
|
route_map_install_match(&route_match_ipv6_next_hop_address_cmd);
|
2021-11-24 15:28:31 +01:00
|
|
|
route_map_install_match(&route_match_ipv6_next_hop_prefix_list_cmd);
|
2020-03-09 16:13:19 +01:00
|
|
|
route_map_install_match(&route_match_ipv4_next_hop_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
|
2018-09-28 10:51:50 +02:00
|
|
|
route_map_install_match(&route_match_ipv6_next_hop_type_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_ipv6_nexthop_global_cmd);
|
2016-08-03 15:49:09 +02:00
|
|
|
route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
route_map_install_set(&route_set_ipv6_nexthop_local_cmd);
|
2015-05-20 02:24:45 +02:00
|
|
|
route_map_install_set(&route_set_ipv6_nexthop_peer_cmd);
|
2022-08-31 22:00:26 +02:00
|
|
|
route_map_install_match(&route_match_rpki_extcommunity_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-22 20:26:33 +01:00
|
|
|
install_element(RMAP_NODE, &match_ipv6_next_hop_address_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_ipv6_next_hop_address_cmd);
|
2021-11-19 19:11:52 +01:00
|
|
|
install_element(RMAP_NODE, &match_ipv6_next_hop_old_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_ipv6_next_hop_old_cmd);
|
2020-03-09 16:13:19 +01:00
|
|
|
install_element(RMAP_NODE, &match_ipv4_next_hop_cmd);
|
2020-06-02 18:23:09 +02:00
|
|
|
install_element(RMAP_NODE, &no_match_ipv4_next_hop_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(RMAP_NODE, &set_ipv6_nexthop_global_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
|
2016-08-03 15:49:09 +02:00
|
|
|
install_element(RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
|
2015-05-20 02:24:45 +02:00
|
|
|
install_element(RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
|
2022-08-31 22:00:26 +02:00
|
|
|
install_element(RMAP_NODE, &match_rpki_extcommunity_cmd);
|
2023-05-10 22:37:47 +02:00
|
|
|
install_element(RMAP_NODE, &match_source_protocol_cmd);
|
|
|
|
install_element(RMAP_NODE, &no_match_source_protocol_cmd);
|
2020-11-30 23:01:03 +01:00
|
|
|
#ifdef HAVE_SCRIPTING
|
2020-11-29 22:01:59 +01:00
|
|
|
install_element(RMAP_NODE, &match_script_cmd);
|
2017-11-07 15:14:32 +01:00
|
|
|
#endif
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
void bgp_route_map_terminate(void)
|
|
|
|
{
|
|
|
|
/* ToDo: Cleanup all the used memory */
|
|
|
|
route_map_finish();
|
|
|
|
}
|