frr/bgpd/bgp_routemap.c

4770 lines
121 KiB
C
Raw Normal View History

2002-12-13 21:15:29 +01:00
/* Route map function of bgpd.
Copyright (C) 1998, 1999 Kunihiro Ishiguro
This file is part of GNU Zebra.
GNU Zebra is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU Zebra is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Zebra; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#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"
#ifdef HAVE_LIBPCREPOSIX
# include <pcreposix.h>
2002-12-13 21:15:29 +01:00
#else
# ifdef HAVE_GNU_REGEX
# include <regex.h>
# else
# include "regex-gnu.h"
# endif /* HAVE_GNU_REGEX */
#endif /* HAVE_LIBPCREPOSIX */
2002-12-13 21:15:29 +01:00
#include "buffer.h"
#include "sockunion.h"
#include "hash.h"
#include "queue.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"
#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"
#include "bgpd/bgp_clist.h"
#include "bgpd/bgp_filter.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_ecommunity.h"
#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"
2002-12-13 21:15:29 +01:00
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
#if ENABLE_BGP_VNC
# 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
2002-12-13 21:15:29 +01:00
/* Memo of route-map commands.
o Cisco route-map
match as-path : Done
community : Done
interface : Done
2002-12-13 21:15:29 +01:00
ip address : Done
ip next-hop : Done
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)
tag : Done
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
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
tag : Done
2002-12-13 21:15:29 +01:00
weight : Done
o Local extensions
2002-12-13 21:15:29 +01:00
set ipv6 next-hop global: Done
set ipv6 next-hop prefer-global: Done
2002-12-13 21:15:29 +01:00
set ipv6 next-hop local : Done
set as-path exclude : Done
2002-12-13 21:15:29 +01: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
struct rmap_value
{
u_int8_t action;
u_int8_t variable;
u_int32_t value;
};
static int
route_value_match (struct rmap_value *rv, u_int32_t value)
{
if (rv->variable == 0 && value == rv->value)
return RMAP_MATCH;
return RMAP_NOMATCH;
}
static u_int32_t
route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
{
u_int32_t value;
switch (rv->variable)
{
case 1:
value = peer->rtt;
break;
default:
value = rv->value;
break;
}
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)
{
u_int8_t action = RMAP_VALUE_SET, var = 0;
unsigned long larg = 0;
char *endptr = NULL;
struct rmap_value *rv;
if (arg[0] == '+')
{
action = RMAP_VALUE_ADD;
arg++;
}
else if (arg[0] == '-')
{
action = RMAP_VALUE_SUB;
arg++;
}
if (all_digit(arg))
{
errno = 0;
larg = strtoul (arg, &endptr, 10);
if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
return NULL;
}
else
{
if (strcmp(arg, "rtt") == 0)
var = 1;
else
return NULL;
}
rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
if (!rv)
return NULL;
rv->action = action;
rv->variable = var;
rv->value = larg;
return rv;
}
static void
route_value_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* generic as path object to be shared in multiple rules */
static void *
route_aspath_compile (const char *arg)
{
struct aspath *aspath;
aspath = aspath_str2aspath (arg);
if (! aspath)
return NULL;
return aspath;
}
static void
route_aspath_free (void *rule)
{
struct aspath *aspath = rule;
aspath_free (aspath);
}
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 (A.B.C.D|X:X::X:X)' */
/* Compares the peer specified in the 'match peer' clause with the peer
received in bgp_info->peer. If it is the same, or if the peer structure
received is a peer_group containing it, returns RMAP_MATCH. */
static route_map_result_t
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_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
void *object)
{
union sockunion *su;
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;
struct listnode *node, *nnode;
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 (type == RMAP_BGP)
{
su = rule;
peer = ((struct bgp_info *) object)->peer;
if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
return RMAP_NOMATCH;
/* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
if (sockunion_same (su, &su_def))
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;
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 ( 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_DEFAULT))
ret = RMAP_MATCH;
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
else
ret = RMAP_NOMATCH;
return ret;
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
}
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 (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (sockunion_same (su, &peer->su))
return RMAP_MATCH;
return RMAP_NOMATCH;
}
else
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, 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
{
if (sockunion_same (su, &peer->su))
return RMAP_MATCH;
}
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
}
}
return RMAP_NOMATCH;
}
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
{
union sockunion *su;
int ret;
su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", 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) {
XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
return NULL;
}
return su;
}
/* Free route map's compiled `ip address' value. */
static void
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_match_peer_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip address matching. */
struct route_map_rule_cmd route_match_peer_cmd =
{
"peer",
route_match_peer,
route_match_peer_compile,
route_match_peer_free
};
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. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ip_address (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
/* struct prefix_ipv4 match; */
if (type == RMAP_BGP)
{
alist = access_list_lookup (AFI_IP, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
return (access_list_apply (alist, prefix) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
/* Route map `ip address' match statement. `arg' should be
access-list name. */
static void *
route_match_ip_address_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
2002-12-13 21:15:29 +01:00
route_match_ip_address_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip address matching. */
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
};
2002-12-13 21:15:29 +01:00
/* `match ip next-hop IP_ADDRESS' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ip_next_hop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
struct bgp_info *bgp_info;
struct prefix_ipv4 p;
if (type == RMAP_BGP)
{
bgp_info = object;
p.family = AF_INET;
p.prefix = bgp_info->attr->nexthop;
p.prefixlen = IPV4_MAX_BITLEN;
alist = access_list_lookup (AFI_IP, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
return (access_list_apply (alist, &p) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
/* Route map `ip next-hop' match statement. `arg' is
access-list name. */
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
2002-12-13 21:15:29 +01:00
route_match_ip_next_hop_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip next-hop matching. */
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
};
/* `match ip route-source ACCESS-LIST' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
route_match_ip_route_source (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
struct bgp_info *bgp_info;
struct peer *peer;
struct prefix_ipv4 p;
if (type == RMAP_BGP)
{
bgp_info = object;
peer = bgp_info->peer;
if (! peer || sockunion_family (&peer->su) != AF_INET)
return RMAP_NOMATCH;
p.family = AF_INET;
p.prefix = peer->su.sin.sin_addr;
p.prefixlen = IPV4_MAX_BITLEN;
alist = access_list_lookup (AFI_IP, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
return (access_list_apply (alist, &p) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
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. */
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
};
2002-12-13 21:15:29 +01:00
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
if (type == RMAP_BGP)
{
plist = prefix_list_lookup (AFI_IP, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
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
2002-12-13 21:15:29 +01:00
route_match_ip_address_prefix_list_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
{
"ip address prefix-list",
route_match_ip_address_prefix_list,
route_match_ip_address_prefix_list_compile,
route_match_ip_address_prefix_list_free
};
2002-12-13 21:15:29 +01:00
/* `match ip next-hop prefix-list PREFIX_LIST' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
struct bgp_info *bgp_info;
struct prefix_ipv4 p;
if (type == RMAP_BGP)
{
bgp_info = object;
p.family = AF_INET;
p.prefix = bgp_info->attr->nexthop;
p.prefixlen = IPV4_MAX_BITLEN;
plist = prefix_list_lookup (AFI_IP, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
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
2002-12-13 21:15:29 +01:00
route_match_ip_next_hop_prefix_list_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
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,
route_match_ip_next_hop_prefix_list_compile,
route_match_ip_next_hop_prefix_list_free
};
/* `match ip route-source prefix-list PREFIX_LIST' */
static route_map_result_t
route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
struct bgp_info *bgp_info;
struct peer *peer;
struct prefix_ipv4 p;
if (type == RMAP_BGP)
{
bgp_info = object;
peer = bgp_info->peer;
if (! peer || sockunion_family (&peer->su) != AF_INET)
return RMAP_NOMATCH;
p.family = AF_INET;
p.prefix = peer->su.sin.sin_addr;
p.prefixlen = IPV4_MAX_BITLEN;
plist = prefix_list_lookup (AFI_IP, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
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);
}
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,
route_match_ip_route_source_prefix_list_compile,
route_match_ip_route_source_prefix_list_free
};
/* `match local-preference LOCAL-PREF' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
route_match_local_pref (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_int32_t *local_pref;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
local_pref = rule;
bgp_info = object;
if (bgp_info->attr->local_pref == *local_pref)
return RMAP_MATCH;
else
return RMAP_NOMATCH;
}
return RMAP_NOMATCH;
}
/* Route map `match local-preference' match statement.
`arg' is local-pref value */
static void *
route_match_local_pref_compile (const char *arg)
{
u_int32_t *local_pref;
char *endptr = NULL;
unsigned long tmpval;
/* Locpref value shoud be integer. */
if (! all_digit (arg))
return NULL;
errno = 0;
tmpval = strtoul (arg, &endptr, 10);
if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
return NULL;
local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
if (!local_pref)
return local_pref;
*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. */
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
};
2002-12-13 21:15:29 +01:00
/* `match metric METRIC' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_metric (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
2002-12-13 21:15:29 +01:00
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
rv = rule;
2002-12-13 21:15:29 +01:00
bgp_info = object;
return route_value_match(rv, bgp_info->attr->med);
2002-12-13 21:15:29 +01:00
}
return RMAP_NOMATCH;
}
/* Route map commands for metric matching. */
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
};
2002-12-13 21:15:29 +01:00
/* `match as-path ASPATH' */
/* Match function for as-path match. I assume given object is */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_aspath (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct as_list *as_list;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
as_list = as_list_lookup ((char *) rule);
if (as_list == NULL)
return RMAP_NOMATCH;
2002-12-13 21:15:29 +01:00
bgp_info = object;
2002-12-13 21:15:29 +01:00
/* Perform match. */
return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
/* Compile function for as-path match. */
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
2002-12-13 21:15:29 +01:00
route_match_aspath_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for aspath matching. */
struct route_map_rule_cmd route_match_aspath_cmd =
{
"as-path",
route_match_aspath,
route_match_aspath_compile,
route_match_aspath_free
};
2002-12-13 21:15:29 +01:00
/* `match community COMMUNIY' */
struct rmap_community
{
char *name;
int exact;
};
/* Match function for community match. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_community (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct bgp_info *bgp_info;
struct rmap_community *rcom;
if (type == RMAP_BGP)
{
bgp_info = object;
rcom = rule;
list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
2002-12-13 21:15:29 +01:00
if (! list)
return RMAP_NOMATCH;
if (rcom->exact)
{
if (community_list_exact_match (bgp_info->attr->community, list))
return RMAP_MATCH;
}
else
{
if (community_list_match (bgp_info->attr->community, list))
return RMAP_MATCH;
}
}
return RMAP_NOMATCH;
}
/* Compile function for community match. */
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;
rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
p = strchr (arg, ' ');
if (p)
{
len = p - arg;
rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
memcpy (rcom->name, arg, len);
rcom->exact = 1;
}
else
{
rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
rcom->exact = 0;
}
return rcom;
}
/* Compile function for community match. */
static void
2002-12-13 21:15:29 +01:00
route_match_community_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. */
struct route_map_rule_cmd route_match_community_cmd =
{
"community",
route_match_community,
route_match_community_compile,
route_match_community_free
};
/* Match function for extcommunity match. */
static route_map_result_t
route_match_ecommunity (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
bgp_info = object;
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
list = community_list_lookup (bgp_clist, (char *) rule,
EXTCOMMUNITY_LIST_MASTER);
if (! list)
return RMAP_NOMATCH;
if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
/* Compile function for extcommunity match. */
static void *
route_match_ecommunity_compile (const char *arg)
{
return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
}
/* Compile function for extcommunity match. */
static void
route_match_ecommunity_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for community matching. */
struct route_map_rule_cmd route_match_ecommunity_cmd =
{
"extcommunity",
route_match_ecommunity,
route_match_ecommunity_compile,
route_match_ecommunity_free
};
2002-12-13 21:15:29 +01:00
/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
and `address-family vpnv4'. */
2002-12-13 21:15:29 +01:00
/* `match origin' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_origin (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_char *origin;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
origin = rule;
bgp_info = object;
if (bgp_info->attr->origin == *origin)
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
static void *
route_match_origin_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
u_char *origin;
origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
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
2002-12-13 21:15:29 +01:00
route_match_origin_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for origin matching. */
struct route_map_rule_cmd route_match_origin_cmd =
{
"origin",
route_match_origin,
route_match_origin_compile,
route_match_origin_free
};
/* match probability { */
static route_map_result_t
route_match_probability (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
long r = random();
switch (*(long *) rule)
{
case 0: break;
case RAND_MAX: return RMAP_MATCH;
default:
if (r < *(long *) rule)
{
return RMAP_MATCH;
}
}
return RMAP_NOMATCH;
}
static void *
route_match_probability_compile (const char *arg)
{
long *lobule;
unsigned perc;
perc = atoi (arg);
lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
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);
}
struct route_map_rule_cmd route_match_probability_cmd =
{
"probability",
route_match_probability,
route_match_probability_compile,
route_match_probability_free
};
/* `match interface IFNAME' */
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t
route_match_interface (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct interface *ifp;
struct bgp_info *info;
if (type == RMAP_BGP)
{
info = object;
if (!info || !info->attr)
return RMAP_NOMATCH;
ifp = if_lookup_by_name_all_vrf ((char *)rule);
if (ifp == NULL || ifp->ifindex != info->attr->nh_ifindex)
return RMAP_NOMATCH;
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
/* 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. */
struct route_map_rule_cmd route_match_interface_cmd =
{
"interface",
route_match_interface,
route_match_interface_compile,
route_match_interface_free
};
/* } */
2002-12-13 21:15:29 +01:00
/* `set ip next-hop IP_ADDRESS' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t
route_match_tag (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
route_tag_t *tag;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
tag = rule;
bgp_info = object;
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
return ((bgp_info->attr->extra->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
}
return RMAP_NOMATCH;
}
/* Route map commands for tag matching. */
static struct route_map_rule_cmd route_match_tag_cmd =
{
"tag",
route_match_tag,
route_map_rule_tag_compile,
route_map_rule_tag_free,
};
2002-12-13 21:15:29 +01:00
/* Set nexthop to object. ojbect must be pointer to struct attr. */
struct rmap_ip_nexthop_set
{
struct in_addr *address;
int peer_address;
int unchanged;
};
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_ip_nexthop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_ip_nexthop_set *rins = rule;
2002-12-13 21:15:29 +01:00
struct bgp_info *bgp_info;
struct peer *peer;
2002-12-13 21:15:29 +01:00
if (type == RMAP_BGP)
{
bgp_info = object;
peer = bgp_info->peer;
if (rins->unchanged)
{
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_NEXTHOP_UNCHANGED);
}
else if (rins->peer_address)
{
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 ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
&& peer->su_remote
&& sockunion_family (peer->su_remote) == AF_INET)
{
bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
}
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.
*/
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
bgp_info->attr->nexthop.s_addr = 0;
}
}
else
{
/* Set next hop value. */
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
bgp_info->attr->nexthop = *rins->address;
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_IPV4_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. */
static void *
route_set_ip_nexthop_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
struct rmap_ip_nexthop_set *rins;
struct in_addr *address = NULL;
int peer_address = 0;
int unchanged = 0;
2002-12-13 21:15:29 +01:00
int ret;
if (strcmp (arg, "peer-address") == 0)
peer_address = 1;
else if (strcmp (arg, "unchanged") == 0)
unchanged = 1;
else
2002-12-13 21:15:29 +01:00
{
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;
}
2002-12-13 21:15:29 +01:00
}
rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
rins->address = address;
rins->peer_address = peer_address;
rins->unchanged = unchanged;
return rins;
2002-12-13 21:15:29 +01:00
}
/* Free route map's compiled `ip nexthop' value. */
static void
2002-12-13 21:15:29 +01:00
route_set_ip_nexthop_free (void *rule)
{
struct rmap_ip_nexthop_set *rins = rule;
if (rins->address)
XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
2002-12-13 21:15:29 +01:00
}
/* Route map commands for ip nexthop set. */
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
};
2002-12-13 21:15:29 +01:00
/* `set local-preference LOCAL_PREF' */
/* Set local preference. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_local_pref (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
2002-12-13 21:15:29 +01:00
struct bgp_info *bgp_info;
u_int32_t locpref = 0;
2002-12-13 21:15:29 +01:00
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
rv = rule;
2002-12-13 21:15:29 +01:00
bgp_info = object;
/* Set local preference value. */
if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
locpref = bgp_info->attr->local_pref;
2002-12-13 21:15:29 +01:00
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
2002-12-13 21:15:29 +01:00
}
return RMAP_OKAY;
}
/* Set local preference rule structure. */
struct route_map_rule_cmd route_set_local_pref_cmd =
{
"local-preference",
route_set_local_pref,
route_value_compile,
route_value_free,
2002-12-13 21:15:29 +01:00
};
2002-12-13 21:15:29 +01:00
/* `set weight WEIGHT' */
/* Set weight. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
void *object)
{
struct rmap_value *rv;
2002-12-13 21:15:29 +01:00
struct bgp_info *bgp_info;
u_int32_t weight;
2002-12-13 21:15:29 +01:00
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
rv = rule;
2002-12-13 21:15:29 +01:00
bgp_info = object;
/* Set weight value. */
weight = route_value_adjust(rv, 0, bgp_info->peer);
if (weight)
(bgp_attr_extra_get (bgp_info->attr))->weight = weight;
else if (bgp_info->attr->extra)
bgp_info->attr->extra->weight = 0;
2002-12-13 21:15:29 +01:00
}
return RMAP_OKAY;
}
/* Set local preference rule structure. */
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
};
2002-12-13 21:15:29 +01:00
/* `set metric METRIC' */
/* Set metric to attribute. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_metric (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_value *rv;
2002-12-13 21:15:29 +01:00
struct bgp_info *bgp_info;
u_int32_t med = 0;
2002-12-13 21:15:29 +01:00
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
rv = rule;
2002-12-13 21:15:29 +01:00
bgp_info = object;
if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
med = bgp_info->attr->med;
2002-12-13 21:15:29 +01:00
bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
2002-12-13 21:15:29 +01:00
}
return RMAP_OKAY;
}
/* Set metric rule structure. */
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
};
2002-12-13 21:15:29 +01:00
/* `set as-path prepend ASPATH' */
/* For AS path prepend mechanism. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
{
struct aspath *aspath;
struct aspath *new;
struct bgp_info *binfo;
if (type == RMAP_BGP)
{
binfo = object;
if (binfo->attr->aspath->refcnt)
new = aspath_dup (binfo->attr->aspath);
else
new = binfo->attr->aspath;
if ((uintptr_t)rule > 10)
{
aspath = rule;
aspath_prepend (aspath, new);
}
else
{
as_t as = aspath_leftmost(new);
if (!as) as = binfo->peer->as;
new = aspath_add_seq_n (new, as, (uintptr_t) rule);
}
2002-12-13 21:15:29 +01:00
binfo->attr->aspath = new;
}
return RMAP_OKAY;
}
static void *
route_set_aspath_prepend_compile (const char *arg)
{
unsigned int num;
if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
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);
}
/* Set as-path prepend rule structure. */
2002-12-13 21:15:29 +01:00
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
};
/* `set as-path exclude ASn' */
/* 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.
*/
static route_map_result_t
route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
{
struct aspath * new_path, * exclude_path;
struct bgp_info *binfo;
if (type == RMAP_BGP)
{
exclude_path = rule;
binfo = object;
if (binfo->attr->aspath->refcnt)
new_path = aspath_dup (binfo->attr->aspath);
else
new_path = binfo->attr->aspath;
binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
}
return RMAP_OKAY;
}
/* Set ASn exlude rule structure. */
struct route_map_rule_cmd route_set_aspath_exclude_cmd =
{
"as-path exclude",
route_set_aspath_exclude,
route_aspath_compile,
route_aspath_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. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_community (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct rmap_com_set *rcs;
struct bgp_info *binfo;
struct attr *attr;
struct community *new = NULL;
struct community *old;
struct community *merge;
2002-12-13 21:15:29 +01:00
if (type == RMAP_BGP)
{
rcs = rule;
binfo = object;
attr = binfo->attr;
old = attr->community;
/* "none" case. */
if (rcs->none)
{
attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
attr->community = NULL;
/* See the longer comment down below. */
if (old && old->refcnt == 0)
community_free(old);
2002-12-13 21:15:29 +01:00
return RMAP_OKAY;
}
/* "additive" case. */
if (rcs->additive && old)
{
merge = community_merge (community_dup (old), rcs->com);
/* 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);
2002-12-13 21:15:29 +01:00
new = community_uniq_sort (merge);
community_free (merge);
}
else
new = community_dup (rcs->com);
/* will be interned by caller if required */
attr->community = new;
2002-12-13 21:15:29 +01:00
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
}
return RMAP_OKAY;
}
/* Compile function for set community. */
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;
if (strcmp (arg, "none") == 0)
none = 1;
else
{
sp = strstr (arg, "additive");
if (sp && sp > arg)
{
/* "additive" keyworkd is included. */
additive = 1;
*(sp - 1) = '\0';
}
com = community_str2com (arg);
if (additive)
*(sp - 1) = ' ';
if (! com)
return NULL;
}
rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
rcs->com = com;
2002-12-13 21:15:29 +01:00
rcs->additive = additive;
rcs->none = none;
return rcs;
}
/* Free function for set community. */
static void
2002-12-13 21:15:29 +01:00
route_set_community_free (void *rule)
{
struct rmap_com_set *rcs = rule;
if (rcs->com)
community_free (rcs->com);
XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
}
/* Set community rule structure. */
struct route_map_rule_cmd route_set_community_cmd =
{
"community",
route_set_community,
route_set_community_compile,
route_set_community_free,
};
/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
2002-12-13 21:15:29 +01:00
/* For community set mechanism. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_community_delete (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct community_list *list;
struct community *merge;
struct community *new;
struct community *old;
struct bgp_info *binfo;
if (type == RMAP_BGP)
{
if (! rule)
return RMAP_OKAY;
binfo = object;
list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
2002-12-13 21:15:29 +01:00
old = binfo->attr->community;
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);
2002-12-13 21:15:29 +01:00
if (new->size == 0)
{
binfo->attr->community = NULL;
binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
community_free (new);
}
else
{
binfo->attr->community = new;
2002-12-13 21:15:29 +01:00
binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
}
}
}
return RMAP_OKAY;
}
/* Compile function for set community. */
static void *
route_set_community_delete_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
char *p;
char *str;
int len;
p = strchr (arg, ' ');
if (p)
{
len = p - arg;
str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
memcpy (str, arg, len);
}
else
str = NULL;
return str;
}
/* Free function for set community. */
static void
2002-12-13 21:15:29 +01:00
route_set_community_delete_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Set community rule structure. */
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
/* `set extcommunity rt COMMUNITY' */
/* For community set mechanism. Used by _rt and _soo. */
static route_map_result_t
route_set_ecommunity (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
2002-12-13 21:15:29 +01:00
{
struct ecommunity *ecom;
struct ecommunity *new_ecom;
struct ecommunity *old_ecom;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
ecom = rule;
bgp_info = object;
if (! ecom)
return RMAP_OKAY;
/* We assume additive for Extended Community. */
old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
2002-12-13 21:15:29 +01:00
if (old_ecom)
{
new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
/* 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);
}
2002-12-13 21:15:29 +01:00
else
new_ecom = ecommunity_dup (ecom);
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
bgp_info->attr->extra->ecommunity = new_ecom;
2002-12-13 21:15:29 +01:00
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
}
return RMAP_OKAY;
}
/* Compile function for set community. */
static void *
route_set_ecommunity_rt_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
struct ecommunity *ecom;
ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
if (! ecom)
return NULL;
return ecommunity_intern (ecom);
2002-12-13 21:15:29 +01: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
{
struct ecommunity *ecom = rule;
ecommunity_unintern (&ecom);
2002-12-13 21:15:29 +01:00
}
/* Set community rule structure. */
struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
{
"extcommunity rt",
route_set_ecommunity,
2002-12-13 21:15:29 +01:00
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. */
static void *
route_set_ecommunity_soo_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
struct ecommunity *ecom;
ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
if (! ecom)
return NULL;
return ecommunity_intern (ecom);
2002-12-13 21:15:29 +01:00
}
/* Set community rule structure. */
struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
{
"extcommunity soo",
route_set_ecommunity,
2002-12-13 21:15:29 +01:00
route_set_ecommunity_soo_compile,
route_set_ecommunity_free,
2002-12-13 21:15:29 +01:00
};
2002-12-13 21:15:29 +01:00
/* `set origin ORIGIN' */
/* For origin set. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
{
u_char *origin;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
origin = rule;
bgp_info = object;
bgp_info->attr->origin = *origin;
}
return RMAP_OKAY;
}
/* Compile function for origin set. */
static void *
route_set_origin_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
u_char *origin;
origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
if (strcmp (arg, "igp") == 0)
*origin = 0;
else if (strcmp (arg, "egp") == 0)
*origin = 1;
else
*origin = 2;
return origin;
}
/* Compile function for origin set. */
static void
2002-12-13 21:15:29 +01:00
route_set_origin_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Set origin rule structure. */
2002-12-13 21:15:29 +01:00
struct route_map_rule_cmd route_set_origin_cmd =
{
"origin",
route_set_origin,
route_set_origin_compile,
route_set_origin_free,
};
2002-12-13 21:15:29 +01:00
/* `set atomic-aggregate' */
/* For atomic aggregate set. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_atomic_aggregate (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
bgp_info = object;
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
}
return RMAP_OKAY;
}
/* Compile function for atomic aggregate. */
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
2002-12-13 21:15:29 +01:00
route_set_atomic_aggregate_free (void *rule)
{
return;
}
/* Set atomic aggregate rule structure. */
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
/* `set aggregator as AS A.B.C.D' */
struct aggregator
{
as_t as;
struct in_addr address;
};
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_aggregator_as (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
struct aggregator *aggregator;
struct attr_extra *ae;
2002-12-13 21:15:29 +01:00
if (type == RMAP_BGP)
{
bgp_info = object;
aggregator = rule;
ae = bgp_attr_extra_get (bgp_info->attr);
ae->aggregator_as = aggregator->as;
ae->aggregator_addr = aggregator->address;
2002-12-13 21:15:29 +01:00
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
}
return RMAP_OKAY;
}
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];
aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
2002-12-13 21:15:29 +01:00
sscanf (arg, "%s %s", as, address);
aggregator->as = strtoul (as, NULL, 10);
inet_aton (address, &aggregator->address);
return aggregator;
}
static void
2002-12-13 21:15:29 +01:00
route_set_aggregator_as_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
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,
};
/* Set tag to object. object must be pointer to struct bgp_info */
static route_map_result_t
route_set_tag (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
route_tag_t *tag;
struct bgp_info *bgp_info;
struct attr_extra *ae;
if (type == RMAP_BGP)
{
tag = rule;
bgp_info = object;
ae = bgp_attr_extra_get (bgp_info->attr);
/* Set tag value */
ae->tag=*tag;
}
return RMAP_OKAY;
}
/* Route map commands for tag set. */
static struct route_map_rule_cmd route_set_tag_cmd =
{
"tag",
route_set_tag,
route_map_rule_tag_compile,
route_map_rule_tag_free,
};
2002-12-13 21:15:29 +01:00
#ifdef HAVE_IPV6
/* `match ipv6 address IP_ACCESS_LIST' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ipv6_address (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct access_list *alist;
if (type == RMAP_BGP)
{
alist = access_list_lookup (AFI_IP6, (char *) rule);
if (alist == NULL)
return RMAP_NOMATCH;
return (access_list_apply (alist, prefix) == FILTER_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
static void *
route_match_ipv6_address_compile (const char *arg)
2002-12-13 21:15:29 +01:00
{
return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
}
static void
2002-12-13 21:15:29 +01:00
route_match_ipv6_address_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip address matching. */
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
};
2002-12-13 21:15:29 +01:00
/* `match ipv6 next-hop IP_ADDRESS' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
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;
2002-12-13 21:15:29 +01:00
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
bgp_info = object;
if (!bgp_info->attr->extra)
return RMAP_NOMATCH;
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
if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
2002-12-13 21:15:29 +01:00
return RMAP_MATCH;
2015-05-20 03:04:00 +02:00
if (bgp_info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
2002-12-13 21:15:29 +01:00
return RMAP_MATCH;
return RMAP_NOMATCH;
}
return RMAP_NOMATCH;
}
static void *
route_match_ipv6_next_hop_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;
}
static void
2002-12-13 21:15:29 +01:00
route_match_ipv6_next_hop_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
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 address prefix-list PREFIX_LIST' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
if (type == RMAP_BGP)
{
plist = prefix_list_lookup (AFI_IP6, (char *) rule);
if (plist == NULL)
return RMAP_NOMATCH;
return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
RMAP_NOMATCH : RMAP_MATCH);
}
return RMAP_NOMATCH;
}
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
2002-12-13 21:15:29 +01:00
route_match_ipv6_address_prefix_list_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
{
"ipv6 address prefix-list",
route_match_ipv6_address_prefix_list,
route_match_ipv6_address_prefix_list_compile,
route_match_ipv6_address_prefix_list_free
};
2002-12-13 21:15:29 +01:00
/* `set ipv6 nexthop global IP_ADDRESS' */
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *address;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
/* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
2002-12-13 21:15:29 +01:00
/* Set nexthop length. */
if (bgp_info->attr->extra->mp_nexthop_len == 0)
2015-05-20 03:04:00 +02:00
bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
SET_FLAG(bgp_info->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. */
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
2002-12-13 21:15:29 +01:00
route_set_ipv6_nexthop_global_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip nexthop set. */
struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
{
"ipv6 next-hop global",
route_set_ipv6_nexthop_global,
route_set_ipv6_nexthop_global_compile,
route_set_ipv6_nexthop_global_free
};
/* Set next-hop preference value. */
static route_map_result_t
route_set_ipv6_nexthop_prefer_global (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
struct peer *peer;
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
bgp_info = object;
peer = bgp_info->peer;
if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
&& peer->su_remote
&& sockunion_family (peer->su_remote) == AF_INET6)
{
/* Set next hop preference to global */
bgp_info->attr->extra->mp_nexthop_prefer_global = TRUE;
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
}
else
{
bgp_info->attr->extra->mp_nexthop_prefer_global = FALSE;
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
}
}
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. */
struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd =
{
"ipv6 next-hop prefer-global",
route_set_ipv6_nexthop_prefer_global,
route_set_ipv6_nexthop_prefer_global_compile,
route_set_ipv6_nexthop_prefer_global_free
};
2002-12-13 21:15:29 +01:00
/* `set ipv6 nexthop local IP_ADDRESS' */
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr *address;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
/* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
2002-12-13 21:15:29 +01:00
/* Set nexthop length. */
2015-05-20 03:04:00 +02:00
if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
SET_FLAG(bgp_info->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. */
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
2002-12-13 21:15:29 +01:00
route_set_ipv6_nexthop_local_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip nexthop set. */
struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
{
"ipv6 next-hop local",
route_set_ipv6_nexthop_local,
route_set_ipv6_nexthop_local_compile,
route_set_ipv6_nexthop_local_free
};
/* `set ipv6 nexthop peer-address' */
/* Set nexthop to object. ojbect must be pointer to struct attr. */
static route_map_result_t
route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in6_addr peer_address;
struct bgp_info *bgp_info;
struct peer *peer;
char peer_addr_buf[INET6_ADDRSTRLEN];
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
bgp_info = object;
peer = bgp_info->peer;
if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
&& peer->su_remote
&& sockunion_family (peer->su_remote) == AF_INET6)
{
inet_pton (AF_INET6, sockunion2str (peer->su_remote,
peer_addr_buf,
INET6_ADDRSTRLEN),
&peer_address);
/* Set next hop value and length in attribute. */
if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
{
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
if (bgp_info->attr->extra->mp_nexthop_len != 32)
bgp_info->attr->extra->mp_nexthop_len = 32;
}
else
{
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
if (bgp_info->attr->extra->mp_nexthop_len == 0)
bgp_info->attr->extra->mp_nexthop_len = 16;
}
}
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(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_NEXTHOP_PEER_ADDRESS);
/* clear next hop value. */
memset (&((bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global),
0, sizeof (struct in6_addr));
memset (&((bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local),
0, sizeof (struct in6_addr));
}
}
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. */
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
};
2002-12-13 21:15:29 +01:00
#endif /* HAVE_IPV6 */
2002-12-13 21:15:29 +01:00
/* `set vpnv4 nexthop A.B.C.D' */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct in_addr *address;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
address = rule;
bgp_info = object;
/* Set next hop value. */
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
(bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
2002-12-13 21:15:29 +01:00
}
return RMAP_OKAY;
}
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;
}
static void
2002-12-13 21:15:29 +01:00
route_set_vpnv4_nexthop_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip nexthop set. */
struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
{
"vpnv4 next-hop",
route_set_vpnv4_nexthop,
route_set_vpnv4_nexthop_compile,
route_set_vpnv4_nexthop_free
};
2002-12-13 21:15:29 +01:00
/* `set originator-id' */
/* For origin set. */
static route_map_result_t
2002-12-13 21:15:29 +01:00
route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
{
struct in_addr *address;
struct bgp_info *bgp_info;
if (type == RMAP_BGP)
{
address = rule;
bgp_info = object;
bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
(bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
2002-12-13 21:15:29 +01:00
}
return RMAP_OKAY;
}
/* Compile function for originator-id set. */
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
2002-12-13 21:15:29 +01:00
route_set_originator_id_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Set originator-id rule structure. */
2002-12-13 21:15:29 +01:00
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
/* Add bgp route map rule. */
static int
2002-12-13 21:15:29 +01:00
bgp_route_match_add (struct vty *vty, struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type)
2002-12-13 21:15:29 +01:00
{
int ret;
ret = route_map_add_match (index, command, arg);
if (ret)
{
switch (ret)
{
case RMAP_RULE_MISSING:
vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
case RMAP_COMPILE_ERROR:
vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
}
}
if (type != RMAP_EVENT_MATCH_ADDED)
{
route_map_upd8_dependency (type, arg, index->map->name);
}
2002-12-13 21:15:29 +01:00
return CMD_SUCCESS;
}
/* Delete bgp route map rule. */
static int
2002-12-13 21:15:29 +01:00
bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type)
2002-12-13 21:15:29 +01:00
{
int ret;
char *dep_name = NULL;
const char *tmpstr;
char *rmap_name = NULL;
2002-12-13 21:15:29 +01:00
if (type != RMAP_EVENT_MATCH_DELETED)
{
/* ignore the mundane, the types without any dependency */
if (arg == NULL)
{
if ((tmpstr = route_map_get_match_arg(index, command)) != NULL)
dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
}
else
{
dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
}
rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
}
ret = route_map_delete_match (index, command, dep_name);
2002-12-13 21:15:29 +01:00
if (ret)
{
switch (ret)
{
case RMAP_RULE_MISSING:
vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
break;
2002-12-13 21:15:29 +01:00
case RMAP_COMPILE_ERROR:
vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
break;
2002-12-13 21:15:29 +01:00
}
if (dep_name)
XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
if (rmap_name)
XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
return CMD_WARNING;
2002-12-13 21:15:29 +01:00
}
if (type != RMAP_EVENT_MATCH_DELETED && dep_name)
route_map_upd8_dependency(type, dep_name, rmap_name);
if (dep_name)
XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
if (rmap_name)
XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
2002-12-13 21:15:29 +01:00
return CMD_SUCCESS;
}
/* Add bgp route map rule. */
static int
2002-12-13 21:15:29 +01:00
bgp_route_set_add (struct vty *vty, struct route_map_index *index,
const char *command, const char *arg)
2002-12-13 21:15:29 +01:00
{
int ret;
ret = route_map_add_set (index, command, arg);
if (ret)
{
switch (ret)
{
case RMAP_RULE_MISSING:
vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
case RMAP_COMPILE_ERROR:
vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
}
}
return CMD_SUCCESS;
}
/* Delete bgp route map rule. */
static int
2002-12-13 21:15:29 +01:00
bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
const char *command, const char *arg)
2002-12-13 21:15:29 +01:00
{
int ret;
ret = route_map_delete_set (index, command, arg);
if (ret)
{
switch (ret)
{
case RMAP_RULE_MISSING:
vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
case RMAP_COMPILE_ERROR:
vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
}
}
return CMD_SUCCESS;
}
/*
BGP: route-server will now use addpath...chop the _rsclient code Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Ticket: CM-8122 per draft-ietf-idr-ix-bgp-route-server-09: 2.3.2.2.2. BGP ADD-PATH Approach The [I-D.ietf-idr-add-paths] Internet draft proposes a different approach to multiple path propagation, by allowing a BGP speaker to forward multiple paths for the same prefix on a single BGP session. As [RFC4271] specifies that a BGP listener must implement an implicit withdraw when it receives an UPDATE message for a prefix which already exists in its Adj-RIB-In, this approach requires explicit support for the feature both on the route server and on its clients. If the ADD-PATH capability is negotiated bidirectionally between the route server and a route server client, and the route server client propagates multiple paths for the same prefix to the route server, then this could potentially cause the propagation of inactive, invalid or suboptimal paths to the route server, thereby causing loss of reachability to other route server clients. For this reason, ADD- PATH implementations on a route server should enforce send-only mode with the route server clients, which would result in negotiating receive-only mode from the client to the route server. This allows us to delete all of the following code: - All XXXX_rsclient() functions - peer->rib - BGP_TABLE_MAIN and BGP_TABLE_RSCLIENT - RMAP_IMPORT and RMAP_EXPORT
2015-11-10 16:29:12 +01:00
* This is the workhorse routine for processing in/out routemap
* modifications.
*/
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
{
int update;
2002-12-13 21:15:29 +01:00
struct bgp_filter *filter;
if (!peer || !rmap_name)
return;
filter = &peer->filter[afi][safi];
/*
* in is for non-route-server clients,
* out is for all peers
*/
if (!CHECK_FLAG(peer->flags, PEER_FLAG_RSERVER_CLIENT))
2002-12-13 21:15:29 +01:00
{
if (filter->map[RMAP_IN].name &&
(strcmp(rmap_name, filter->map[RMAP_IN].name) == 0))
2002-12-13 21:15:29 +01:00
{
filter->map[RMAP_IN].map = map;
if (route_update && peer->status == Established)
{
if (CHECK_FLAG (peer->af_flags[afi][safi],
PEER_FLAG_SOFT_RECONFIG))
{
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug("Processing route_map %s update on "
"peer %s (inbound, soft-reconfig)",
rmap_name, peer->host);
bgp_soft_reconfig_in (peer, afi, safi);
}
else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
|| CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
{
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug("Processing route_map %s update on "
"peer %s (inbound, route-refresh)",
rmap_name, peer->host);
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
}
}
2002-12-13 21:15:29 +01:00
}
}
if (CHECK_FLAG(peer->flags, PEER_FLAG_RSERVER_CLIENT))
2002-12-13 21:15:29 +01:00
{
update = 0;
if (update && route_update && peer->status == Established)
{
if (CHECK_FLAG (peer->af_flags[afi][safi],
PEER_FLAG_SOFT_RECONFIG))
{
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug("Processing route_map %s update on "
"peer %s (import, soft-reconfig)",
rmap_name, peer->host);
bgp_soft_reconfig_in (peer, afi, safi);
}
else if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
|| CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
{
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug("Processing route_map %s update on "
"peer %s (import, route-refresh)",
rmap_name, peer->host);
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
}
/* DD: Else, what else do we do ? Reset peer ? */
2002-12-13 21:15:29 +01: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.
*/
if (filter->map[RMAP_OUT].name &&
(strcmp(rmap_name, filter->map[RMAP_OUT].name) == 0))
filter->map[RMAP_OUT].map = map;
if (filter->usmap.name &&
(strcmp(rmap_name, filter->usmap.name) == 0))
filter->usmap.map = map;
if (peer->default_rmap[afi][safi].name &&
(strcmp (rmap_name, peer->default_rmap[afi][safi].name) == 0))
peer->default_rmap[afi][safi].map = map;
}
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
static void
bgp_route_map_update_peer_group(const char *rmap_name, struct route_map *map,
struct bgp *bgp)
{
struct peer_group *group;
struct listnode *node, *nnode;
struct bgp_filter *filter;
int afi, safi;
int direct;
if (!bgp)
return;
/* All the peers have been updated correctly already. This is
* just updating the placeholder data. No real update required.
*/
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; 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) == 0))
filter->map[direct].map = map;
}
if (filter->usmap.name &&
(strcmp(rmap_name, filter->usmap.name) == 0))
filter->usmap.map = map;
}
}
/*
* 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.
*/
static void
bgp_route_map_process_update (struct bgp *bgp, const char *rmap_name, int route_update)
{
int i;
afi_t afi;
safi_t safi;
struct peer *peer;
struct bgp_node *bn;
struct bgp_static *bgp_static;
struct listnode *node, *nnode;
struct route_map *map;
char buf[INET6_ADDRSTRLEN];
map = route_map_lookup_by_name (rmap_name);
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
/* Ignore dummy peer-group structure */
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
continue;
2002-12-13 21:15:29 +01:00
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
/* Ignore inactive AFI/SAFI */
if (! peer->afc[afi][safi])
continue;
/* process in/out/import/export/default-orig route-maps */
bgp_route_map_process_peer(rmap_name, map, peer, afi, safi, route_update);
}
2002-12-13 21:15:29 +01:00
}
/* for outbound/default-orig route-maps, process for groups */
update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP, rmap_name,
route_update, 0);
/* update peer-group config (template) */
bgp_route_map_update_peer_group(rmap_name, map, bgp);
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
/* For table route-map updates. */
if (bgp->table_map[afi][safi].name &&
(strcmp(rmap_name, bgp->table_map[afi][safi].name) == 0))
{
bgp->table_map[afi][safi].map = map;
Overhual BGP debugs Summary of changes - added an option to enable keepalive debugs for a specific peer - added an option to enable inbound and/or outbound updates debugs for a specific peer - added an option to enable update debugs for a specific prefix - added an option to enable zebra debugs for a specific prefix - combined "deb bgp", "deb bgp events" and "deb bgp fsm" into "deb bgp neighbor-events". "deb bgp neighbor-events" can be enabled for a specific peer. - merged "deb bgp filters" into "deb bgp update" - moved the per-peer logging to one central log file. We now have the ability to filter all verbose debugs on a per-peer and per-prefix basis so we no longer need to keep log files per-peer. This simplifies troubleshooting by keeping all BGP logs in one location. The use r can then grep for the peer IP they are interested in if they wish to see the logs for a specific peer. - Changed "show debugging" in isis to "show debugging isis" to be consistent with all other protocols. This was very confusing for the user because they would type "show debug" and expect to see a list of debugs enabled across all protocols. - Removed "undebug" from the parser for BGP. Again this was to be consisten with all other protocols. - Removed the "all" keyword from the BGP debug parser. The user can now do "no debug bgp" to disable all BGP debugs, before you had to type "no deb all bgp" which was confusing. The new parse tree for BGP debugging is: deb bgp as4 deb bgp as4 segment deb bgp keepalives [A.B.C.D|WORD|X:X::X:X] deb bgp neighbor-events [A.B.C.D|WORD|X:X::X:X] deb bgp nht deb bgp updates [in|out] [A.B.C.D|WORD|X:X::X:X] deb bgp updates prefix [A.B.C.D/M|X:X::X:X/M] deb bgp zebra deb bgp zebra prefix [A.B.C.D/M|X:X::X:X/M]
2015-05-20 02:58:12 +02:00
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Processing route_map %s update on "
"table map", rmap_name);
if (route_update)
bgp_zebra_announce_table(bgp, afi, safi);
}
/* For network route-map updates. */
for (bn = bgp_table_top (bgp->route[afi][safi]); bn; bn = bgp_route_next (bn))
if ((bgp_static = bn->info) != NULL)
{
if (bgp_static->rmap.name &&
(strcmp(rmap_name, bgp_static->rmap.name) == 0))
{
bgp_static->rmap.map = map;
if (route_update)
if (!bgp_static->backdoor)
{
if (bgp_debug_zebra(&bn->p))
zlog_debug("Processing route_map %s update on "
"static route %s", rmap_name,
inet_ntop (bn->p.family, &bn->p.u.prefix,
buf, INET6_ADDRSTRLEN));
bgp_static_update (bgp, &bn->p, bgp_static, afi, safi);
}
}
}
}
2002-12-13 21:15:29 +01:00
/* For redistribute route-map updates. */
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 listnode *node;
struct bgp_redist *red;
red_list = bgp->redist[afi][i];
if (!red_list)
continue;
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
{
if (red->rmap.name &&
(strcmp(rmap_name, red->rmap.name) == 0))
{
red->rmap.map = map;
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
if (route_update)
{
if (BGP_DEBUG (zebra, ZEBRA))
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
zlog_debug("Processing route_map %s update on "
"redistributed routes", rmap_name);
bgp_redistribute_resend (bgp, afi, i, red->instance);
}
}
}
}
}
static int
bgp_route_map_process_update_cb (char *rmap_name)
{
struct listnode *node, *nnode;
struct bgp *bgp;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
bgp_route_map_process_update(bgp, rmap_name, 1);
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
#if ENABLE_BGP_VNC
zlog_debug("%s: calling vnc_routemap_update", __func__);
vnc_routemap_update(bgp, __func__);
#endif
return 0;
}
int
bgp_route_map_update_timer(struct thread *thread)
{
bm->t_rmap_update = NULL;
route_map_walk_update_list(bgp_route_map_process_update_cb);
return (0);
}
static void
bgp_route_map_mark_update (const char *rmap_name)
{
if (bm->t_rmap_update == NULL)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
struct bgp *bgp;
/* rmap_update_timer of 0 means don't do route updates */
if (bm->rmap_update_timer)
{
bm->t_rmap_update =
thread_add_timer(bm->master, bgp_route_map_update_timer, NULL,
bm->rmap_update_timer);
/* Signal the groups that a route-map update event has started */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP, rmap_name, 1, 1);
}
else
{
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
bgp_route_map_process_update(bgp, rmap_name, 0);
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
#if ENABLE_BGP_VNC
zlog_debug("%s: calling vnc_routemap_update", __func__);
vnc_routemap_update(bgp, __func__);
#endif
}
2002-12-13 21:15:29 +01: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
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
{
if (route_map_mark_updated(rmap_name, 0) == 0)
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
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
}
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
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
{
if (route_map_mark_updated(rmap_name, 1) == 0)
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
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
}
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
static void
bgp_route_map_event (route_map_event_t 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
{
if (route_map_mark_updated(rmap_name, 0) == 0)
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
}
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
DEFUN (match_peer,
match_peer_cmd,
"match peer (A.B.C.D|X:X::X:X)",
MATCH_STR
"Match peer address\n"
"IP address of peer\n"
"IPv6 address 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
{
return bgp_route_match_add (vty, vty->index, "peer", argv[0],
RMAP_EVENT_MATCH_ADDED);
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
}
DEFUN (match_peer_local,
match_peer_local_cmd,
"match peer local",
MATCH_STR
"Match peer address\n"
"Static or Redistributed routes\n")
{
return bgp_route_match_add (vty, vty->index, "peer", "local",
RMAP_EVENT_MATCH_DELETED);
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
}
DEFUN (no_match_peer,
no_match_peer_cmd,
"no match peer",
NO_STR
MATCH_STR
"Match peer address\n")
{
if (argc == 0)
return bgp_route_match_delete (vty, vty->index, "peer", NULL,
RMAP_EVENT_MATCH_DELETED);
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 bgp_route_match_delete (vty, vty->index, "peer", argv[0],
RMAP_EVENT_MATCH_DELETED);
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
}
ALIAS (no_match_peer,
no_match_peer_val_cmd,
"no match peer (A.B.C.D|X:X::X:X)",
NO_STR
MATCH_STR
"Match peer address\n"
"IP address of peer\n"
"IPv6 address 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
ALIAS (no_match_peer,
no_match_peer_local_cmd,
"no match peer local",
NO_STR
MATCH_STR
"Match peer address\n"
"Static or Redistributed routes\n")
2002-12-13 21:15:29 +01:00
DEFUN (match_ip_address,
match_ip_address_cmd,
"match ip address (<1-199>|<1300-2699>|WORD)",
MATCH_STR
IP_STR
"Match address of route\n"
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ip address", argv[0],
RMAP_EVENT_FILTER_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ip_address,
no_match_ip_address_cmd,
"no match ip address",
NO_STR
MATCH_STR
IP_STR
"Match address of route\n")
{
if (argc == 0)
return bgp_route_match_delete (vty, vty->index, "ip address", NULL,
RMAP_EVENT_FILTER_DELETED);
2002-12-13 21:15:29 +01:00
return bgp_route_match_delete (vty, vty->index, "ip address", argv[0],
RMAP_EVENT_FILTER_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_ip_address,
no_match_ip_address_val_cmd,
"no match ip address (<1-199>|<1300-2699>|WORD)",
NO_STR
MATCH_STR
IP_STR
"Match address of route\n"
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
DEFUN (match_ip_next_hop,
match_ip_next_hop_cmd,
"match ip next-hop (<1-199>|<1300-2699>|WORD)",
MATCH_STR
IP_STR
"Match next-hop address of route\n"
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0],
RMAP_EVENT_FILTER_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ip_next_hop,
no_match_ip_next_hop_cmd,
"no match ip next-hop",
NO_STR
MATCH_STR
IP_STR
"Match next-hop address of route\n")
{
if (argc == 0)
return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL,
RMAP_EVENT_FILTER_DELETED);
2002-12-13 21:15:29 +01:00
return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0],
RMAP_EVENT_FILTER_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_ip_next_hop,
no_match_ip_next_hop_val_cmd,
"no match ip next-hop (<1-199>|<1300-2699>|WORD)",
NO_STR
MATCH_STR
IP_STR
"Match next-hop address of route\n"
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP Access-list name\n")
/* match probability { */
DEFUN (match_probability,
match_probability_cmd,
"match probability <0-100>",
MATCH_STR
"Match portion of routes defined by percentage value\n"
"Percentage of routes\n")
{
return bgp_route_match_add (vty, vty->index, "probability", argv[0],
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_probability,
no_match_probability_cmd,
"no match probability",
NO_STR
MATCH_STR
"Match portion of routes defined by percentage value\n")
{
return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL,
RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_probability,
no_match_probability_val_cmd,
"no match probability <1-99>",
NO_STR
MATCH_STR
"Match portion of routes defined by percentage value\n"
"Percentage of routes\n")
/* } */
DEFUN (match_ip_route_source,
match_ip_route_source_cmd,
"match ip route-source (<1-199>|<1300-2699>|WORD)",
MATCH_STR
IP_STR
"Match advertising source address of route\n"
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP standard access-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0],
RMAP_EVENT_FILTER_ADDED);
}
DEFUN (no_match_ip_route_source,
no_match_ip_route_source_cmd,
"no match ip route-source",
NO_STR
MATCH_STR
IP_STR
"Match advertising source address of route\n")
{
if (argc == 0)
return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL,
RMAP_EVENT_FILTER_DELETED);
return bgp_route_match_delete (vty, vty->index, "ip route-source",
argv[0], RMAP_EVENT_FILTER_DELETED);
}
ALIAS (no_match_ip_route_source,
no_match_ip_route_source_val_cmd,
"no match ip route-source (<1-199>|<1300-2699>|WORD)",
NO_STR
MATCH_STR
IP_STR
"Match advertising source address of route\n"
"IP access-list number\n"
"IP access-list number (expanded range)\n"
"IP standard access-list name\n")
2002-12-13 21:15:29 +01:00
DEFUN (match_ip_address_prefix_list,
match_ip_address_prefix_list_cmd,
"match ip address prefix-list WORD",
MATCH_STR
IP_STR
"Match address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ip address prefix-list",
argv[0], RMAP_EVENT_PLIST_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ip_address_prefix_list,
no_match_ip_address_prefix_list_cmd,
"no match ip address prefix-list",
NO_STR
MATCH_STR
IP_STR
"Match address of route\n"
"Match entries of prefix-lists\n")
{
return bgp_route_match_delete (vty, vty->index, "ip address prefix-list",
argc == 0 ? NULL : argv[0],
RMAP_EVENT_PLIST_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_ip_address_prefix_list,
no_match_ip_address_prefix_list_val_cmd,
"no match ip address prefix-list WORD",
NO_STR
MATCH_STR
IP_STR
"Match address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
DEFUN (match_ip_next_hop_prefix_list,
match_ip_next_hop_prefix_list_cmd,
"match ip next-hop prefix-list WORD",
MATCH_STR
IP_STR
"Match next-hop address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list",
argv[0], RMAP_EVENT_PLIST_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ip_next_hop_prefix_list,
no_match_ip_next_hop_prefix_list_cmd,
"no match ip next-hop prefix-list",
NO_STR
MATCH_STR
IP_STR
"Match next-hop address of route\n"
"Match entries of prefix-lists\n")
{
return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
argc == 0 ? NULL : argv[0],
RMAP_EVENT_PLIST_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_ip_next_hop_prefix_list,
no_match_ip_next_hop_prefix_list_val_cmd,
"no match ip next-hop prefix-list WORD",
NO_STR
MATCH_STR
IP_STR
"Match next-hop address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
DEFUN (match_ip_route_source_prefix_list,
match_ip_route_source_prefix_list_cmd,
"match ip route-source prefix-list WORD",
MATCH_STR
IP_STR
"Match advertising source address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list",
argv[0], RMAP_EVENT_PLIST_ADDED);
}
DEFUN (no_match_ip_route_source_prefix_list,
no_match_ip_route_source_prefix_list_cmd,
"no match ip route-source prefix-list",
NO_STR
MATCH_STR
IP_STR
"Match advertising source address of route\n"
"Match entries of prefix-lists\n")
{
return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list",
argc == 0 ? NULL : argv[0],
RMAP_EVENT_PLIST_DELETED);
}
ALIAS (no_match_ip_route_source_prefix_list,
no_match_ip_route_source_prefix_list_val_cmd,
"no match ip route-source prefix-list WORD",
NO_STR
MATCH_STR
IP_STR
"Match advertising source address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
2002-12-13 21:15:29 +01:00
DEFUN (match_metric,
match_metric_cmd,
"match metric <0-4294967295>",
MATCH_STR
"Match metric of route\n"
"Metric value\n")
{
return bgp_route_match_add (vty, vty->index, "metric", argv[0],
RMAP_EVENT_MATCH_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_metric,
no_match_metric_cmd,
"no match metric",
NO_STR
MATCH_STR
"Match metric of route\n")
{
return bgp_route_match_delete (vty, vty->index, "metric",
argc == 0 ? NULL : argv[0],
RMAP_EVENT_MATCH_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_metric,
no_match_metric_val_cmd,
"no match metric <0-4294967295>",
NO_STR
MATCH_STR
"Match metric of route\n"
"Metric value\n")
DEFUN (match_local_pref,
match_local_pref_cmd,
"match local-preference <0-4294967295>",
MATCH_STR
"Match local-preference of route\n"
"Metric value\n")
{
return bgp_route_match_add (vty, vty->index, "local-preference", argv[0],
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_local_pref,
no_match_local_pref_cmd,
"no match local-preference",
NO_STR
MATCH_STR
"Match local preference of route\n")
{
return bgp_route_match_delete (vty, vty->index, "local-preference",
argc == 0 ? NULL : argv[0],
RMAP_EVENT_MATCH_DELETED);
return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0],
RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_local_pref,
no_match_local_pref_val_cmd,
"no match local-preference <0-4294967295>",
NO_STR
MATCH_STR
"Match local preference of route\n"
"Local preference value\n")
2002-12-13 21:15:29 +01:00
DEFUN (match_community,
match_community_cmd,
"match community (<1-99>|<100-500>|WORD)",
2002-12-13 21:15:29 +01:00
MATCH_STR
"Match BGP community list\n"
"Community-list number (standard)\n"
"Community-list number (expanded)\n"
"Community-list name\n")
{
return bgp_route_match_add (vty, vty->index, "community", argv[0],
RMAP_EVENT_CLIST_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (match_community_exact,
match_community_exact_cmd,
"match community (<1-99>|<100-500>|WORD) exact-match",
2002-12-13 21:15:29 +01:00
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")
{
int ret;
char *argstr;
argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
strlen (argv[0]) + strlen ("exact-match") + 2);
sprintf (argstr, "%s exact-match", argv[0]);
ret = bgp_route_match_add (vty, vty->index, "community", argstr,
RMAP_EVENT_CLIST_ADDED);
2002-12-13 21:15:29 +01:00
XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
return ret;
}
DEFUN (no_match_community,
no_match_community_cmd,
"no match community",
NO_STR
MATCH_STR
"Match BGP community list\n")
{
return bgp_route_match_delete (vty, vty->index, "community", NULL,
RMAP_EVENT_CLIST_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_community,
no_match_community_val_cmd,
"no match community (<1-99>|<100-500>|WORD)",
2002-12-13 21:15:29 +01:00
NO_STR
MATCH_STR
"Match BGP community list\n"
"Community-list number (standard)\n"
"Community-list number (expanded)\n"
"Community-list name\n")
ALIAS (no_match_community,
no_match_community_exact_cmd,
"no match community (<1-99>|<100-500>|WORD) exact-match",
2002-12-13 21:15:29 +01:00
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")
DEFUN (match_ecommunity,
match_ecommunity_cmd,
"match extcommunity (<1-99>|<100-500>|WORD)",
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")
{
return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0],
RMAP_EVENT_ECLIST_ADDED);
}
DEFUN (no_match_ecommunity,
no_match_ecommunity_cmd,
"no match extcommunity",
NO_STR
MATCH_STR
"Match BGP/VPN extended community list\n")
{
return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL,
RMAP_EVENT_ECLIST_DELETED);
}
ALIAS (no_match_ecommunity,
no_match_ecommunity_val_cmd,
"no match extcommunity (<1-99>|<100-500>|WORD)",
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")
2002-12-13 21:15:29 +01:00
DEFUN (match_aspath,
match_aspath_cmd,
"match as-path WORD",
MATCH_STR
"Match BGP AS path list\n"
"AS path access-list name\n")
{
return bgp_route_match_add (vty, vty->index, "as-path", argv[0],
RMAP_EVENT_ASLIST_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_aspath,
no_match_aspath_cmd,
"no match as-path",
NO_STR
MATCH_STR
"Match BGP AS path list\n")
{
return bgp_route_match_delete (vty, vty->index, "as-path", NULL,
RMAP_EVENT_ASLIST_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_aspath,
no_match_aspath_val_cmd,
"no match as-path WORD",
NO_STR
MATCH_STR
"Match BGP AS path list\n"
"AS path access-list name\n")
DEFUN (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")
{
if (strncmp (argv[0], "igp", 2) == 0)
return bgp_route_match_add (vty, vty->index, "origin", "igp",
RMAP_EVENT_MATCH_ADDED);
2002-12-13 21:15:29 +01:00
if (strncmp (argv[0], "egp", 1) == 0)
return bgp_route_match_add (vty, vty->index, "origin", "egp",
RMAP_EVENT_MATCH_ADDED);
2002-12-13 21:15:29 +01:00
if (strncmp (argv[0], "incomplete", 2) == 0)
return bgp_route_match_add (vty, vty->index, "origin", "incomplete",
RMAP_EVENT_MATCH_ADDED);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
}
DEFUN (no_match_origin,
no_match_origin_cmd,
"no match origin",
NO_STR
MATCH_STR
"BGP origin code\n")
{
return bgp_route_match_delete (vty, vty->index, "origin", NULL,
RMAP_EVENT_MATCH_DELETED);
2002-12-13 21:15:29 +01:00
}
ALIAS (no_match_origin,
no_match_origin_val_cmd,
"no match origin (egp|igp|incomplete)",
NO_STR
MATCH_STR
"BGP origin code\n"
"remote EGP\n"
"local IGP\n"
"unknown heritage\n")
DEFUN (match_interface,
match_interface_cmd,
"match interface WORD",
MATCH_STR
"Match first hop interface of route\n"
"Interface name\n")
{
return bgp_route_match_add (vty, vty->index, "interface", argv[0],
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_interface,
no_match_interface_cmd,
"no match interface",
NO_STR
MATCH_STR
"Match first hop interface of route\n")
{
if (argc == 0)
return bgp_route_match_delete (vty, vty->index, "interface", NULL,
RMAP_EVENT_MATCH_DELETED);
return bgp_route_match_delete (vty, vty->index, "interface", argv[0],
RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_interface,
no_match_interface_val_cmd,
"no match interface WORD",
NO_STR
MATCH_STR
"Match first hop interface of route\n"
"Interface name\n")
DEFUN (match_tag,
match_tag_cmd,
"match tag <1-4294967295>",
MATCH_STR
"Match tag of route\n"
"Tag value\n")
{
return bgp_route_match_add (vty, vty->index, "tag", argv[0],
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_tag,
no_match_tag_cmd,
"no match tag",
NO_STR
MATCH_STR
"Match tag of route\n")
{
if (argc == 0)
return bgp_route_match_delete (vty, vty->index, "tag", NULL,
RMAP_EVENT_MATCH_DELETED);
return bgp_route_match_delete (vty, vty->index, "tag", argv[0],
RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_tag,
no_match_tag_val_cmd,
"no match tag <1-4294967295>",
NO_STR
MATCH_STR
"Match tag of route\n"
"Tag value\n")
2002-12-13 21:15:29 +01:00
DEFUN (set_ip_nexthop,
set_ip_nexthop_cmd,
"set ip next-hop A.B.C.D",
2002-12-13 21:15:29 +01:00
SET_STR
IP_STR
"Next hop address\n"
"IP address of next hop\n")
2002-12-13 21:15:29 +01:00
{
union sockunion su;
int ret;
ret = str2sockunion (argv[0], &su);
if (ret < 0)
{
vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (su.sin.sin_addr.s_addr == 0 ||
IPV4_CLASS_DE(su.sin.sin_addr.s_addr))
{
vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast "
"or reserved%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_WARNING;
}
return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
}
DEFUN (set_ip_nexthop_peer,
set_ip_nexthop_peer_cmd,
"set ip next-hop peer-address",
SET_STR
IP_STR
"Next hop address\n"
"Use peer address (for BGP only)\n")
{
return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
}
DEFUN (set_ip_nexthop_unchanged,
set_ip_nexthop_unchanged_cmd,
"set ip next-hop unchanged",
SET_STR
IP_STR
"Next hop address\n"
"Don't modify existing Next hop address\n")
{
return bgp_route_set_add (vty, vty->index, "ip next-hop", "unchanged");
}
2002-12-13 21:15:29 +01:00
DEFUN (no_set_ip_nexthop,
no_set_ip_nexthop_cmd,
"no set ip next-hop",
NO_STR
SET_STR
"Next hop address\n")
{
if (argc == 0)
2002-12-13 21:15:29 +01:00
return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
}
ALIAS (no_set_ip_nexthop,
no_set_ip_nexthop_val_cmd,
"no set ip next-hop A.B.C.D",
2002-12-13 21:15:29 +01:00
NO_STR
SET_STR
IP_STR
"Next hop address\n"
"IP address of next hop\n")
2002-12-13 21:15:29 +01:00
ALIAS (no_set_ip_nexthop,
no_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")
2002-12-13 21:15:29 +01:00
DEFUN (set_metric,
set_metric_cmd,
"set metric <0-4294967295>",
2002-12-13 21:15:29 +01:00
SET_STR
"Metric value for destination routing protocol\n"
"Metric value\n")
2002-12-13 21:15:29 +01:00
{
return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
}
ALIAS (set_metric,
set_metric_addsub_cmd,
"set metric <+/-metric>",
SET_STR
"Metric value for destination routing protocol\n"
"Add or subtract metric\n")
ALIAS (set_metric,
set_metric_rtt_cmd,
"set metric (rtt|+rtt|-rtt)",
SET_STR
"Metric value for destination routing protocol\n"
"Assign round trip time\n"
"Add round trip time\n"
"Subtract round trip time\n")
2002-12-13 21:15:29 +01:00
DEFUN (no_set_metric,
no_set_metric_cmd,
"no set metric",
NO_STR
SET_STR
"Metric value for destination routing protocol\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "metric", NULL);
return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
}
ALIAS (no_set_metric,
no_set_metric_val_cmd,
"no set metric <0-4294967295>",
NO_STR
SET_STR
"Metric value for destination routing protocol\n"
"Metric value\n")
DEFUN (set_local_pref,
set_local_pref_cmd,
"set local-preference <0-4294967295>",
SET_STR
"BGP local preference path attribute\n"
"Preference value\n")
{
return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
}
DEFUN (no_set_local_pref,
no_set_local_pref_cmd,
"no set local-preference",
NO_STR
SET_STR
"BGP local preference path attribute\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
}
ALIAS (no_set_local_pref,
no_set_local_pref_val_cmd,
"no set local-preference <0-4294967295>",
NO_STR
SET_STR
"BGP local preference path attribute\n"
"Preference value\n")
DEFUN (set_weight,
set_weight_cmd,
"set weight <0-4294967295>",
SET_STR
"BGP weight for routing table\n"
"Weight value\n")
{
return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
}
DEFUN (no_set_weight,
no_set_weight_cmd,
"no set weight",
NO_STR
SET_STR
"BGP weight for routing table\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "weight", NULL);
return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
}
ALIAS (no_set_weight,
no_set_weight_val_cmd,
"no set weight <0-4294967295>",
NO_STR
SET_STR
"BGP weight for routing table\n"
"Weight value\n")
DEFUN (set_aspath_prepend,
set_aspath_prepend_cmd,
"set as-path prepend ." CMD_AS_RANGE,
2002-12-13 21:15:29 +01:00
SET_STR
"Transform BGP AS_PATH attribute\n"
2002-12-13 21:15:29 +01:00
"Prepend to the as-path\n"
"AS number\n")
{
int ret;
char *str;
str = argv_concat (argv, argc, 0);
ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
XFREE (MTYPE_TMP, str);
return ret;
}
ALIAS (set_aspath_prepend,
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"
"Use the peer's AS-number\n"
"Number of times to insert")
2002-12-13 21:15:29 +01:00
DEFUN (no_set_aspath_prepend,
no_set_aspath_prepend_cmd,
"no set as-path prepend",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
2002-12-13 21:15:29 +01:00
"Prepend to the as-path\n")
{
int ret;
char *str;
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
str = argv_concat (argv, argc, 0);
ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
XFREE (MTYPE_TMP, str);
return ret;
2002-12-13 21:15:29 +01:00
}
ALIAS (no_set_aspath_prepend,
no_set_aspath_prepend_val_cmd,
"no set as-path prepend ." CMD_AS_RANGE,
2002-12-13 21:15:29 +01:00
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
2002-12-13 21:15:29 +01:00
"Prepend to the as-path\n"
"AS number\n")
DEFUN (set_aspath_exclude,
set_aspath_exclude_cmd,
"set as-path exclude ." CMD_AS_RANGE,
SET_STR
"Transform BGP AS-path attribute\n"
"Exclude from the as-path\n"
"AS number\n")
{
int ret;
char *str;
str = argv_concat (argv, argc, 0);
ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
XFREE (MTYPE_TMP, str);
return ret;
}
DEFUN (no_set_aspath_exclude,
no_set_aspath_exclude_cmd,
"no set as-path exclude",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
"Exclude from the as-path\n")
{
int ret;
char *str;
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
str = argv_concat (argv, argc, 0);
ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
XFREE (MTYPE_TMP, str);
return ret;
}
ALIAS (no_set_aspath_exclude,
no_set_aspath_exclude_val_cmd,
"no set as-path exclude ." CMD_AS_RANGE,
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
"Exclude from the as-path\n"
"AS number\n")
2002-12-13 21:15:29 +01:00
DEFUN (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
{
int i;
int first = 0;
int additive = 0;
struct buffer *b;
struct community *com = NULL;
char *str;
char *argstr;
int ret;
b = buffer_new (1024);
for (i = 0; i < argc; i++)
{
if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
{
additive = 1;
continue;
}
if (first)
buffer_putc (b, ' ');
else
first = 1;
if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
{
buffer_putstr (b, "internet");
continue;
}
if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
{
buffer_putstr (b, "local-AS");
continue;
}
if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
&& strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
{
buffer_putstr (b, "no-advertise");
continue;
}
if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
&& strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
{
buffer_putstr (b, "no-export");
continue;
}
buffer_putstr (b, argv[i]);
}
buffer_putc (b, '\0');
/* Fetch result string then compile it to communities attribute. */
str = buffer_getstr (b);
buffer_free (b);
if (str)
{
com = community_str2com (str);
XFREE (MTYPE_TMP, str);
2002-12-13 21:15:29 +01:00
}
/* Can't compile user input into communities attribute. */
if (! com)
{
vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
return CMD_WARNING;
}
/* Set communites attribute string. */
str = community_str (com);
if (additive)
{
argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
strcpy (argstr, str);
strcpy (argstr + strlen (str), " additive");
ret = bgp_route_set_add (vty, vty->index, "community", argstr);
XFREE (MTYPE_TMP, argstr);
}
else
ret = bgp_route_set_add (vty, vty->index, "community", str);
community_free (com);
return ret;
}
DEFUN (set_community_none,
set_community_none_cmd,
"set community none",
SET_STR
"BGP community attribute\n"
"No community attribute\n")
{
return bgp_route_set_add (vty, vty->index, "community", "none");
}
DEFUN (no_set_community,
no_set_community_cmd,
"no set community",
NO_STR
SET_STR
"BGP community attribute\n")
{
return bgp_route_set_delete (vty, vty->index, "community", NULL);
}
ALIAS (no_set_community,
no_set_community_val_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
ALIAS (no_set_community,
no_set_community_none_cmd,
"no set community none",
NO_STR
SET_STR
"BGP community attribute\n"
"No community attribute\n")
DEFUN (set_community_delete,
set_community_delete_cmd,
"set comm-list (<1-99>|<100-500>|WORD) delete",
2002-12-13 21:15:29 +01:00
SET_STR
"set BGP community list (for deletion)\n"
"Community-list number (standard)\n"
"Community-list number (expanded)\n"
2002-12-13 21:15:29 +01:00
"Community-list name\n"
"Delete matching communities\n")
{
char *str;
str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
strcpy (str, argv[0]);
strcpy (str + strlen (argv[0]), " delete");
bgp_route_set_add (vty, vty->index, "comm-list", str);
XFREE (MTYPE_TMP, str);
return CMD_SUCCESS;
}
DEFUN (no_set_community_delete,
no_set_community_delete_cmd,
"no set comm-list",
NO_STR
SET_STR
"set BGP community list (for deletion)\n")
{
return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
}
ALIAS (no_set_community_delete,
no_set_community_delete_val_cmd,
"no set comm-list (<1-99>|<100-500>|WORD) delete",
2002-12-13 21:15:29 +01:00
NO_STR
SET_STR
"set BGP community list (for deletion)\n"
"Community-list number (standard)\n"
"Community-list number (expanded)\n"
2002-12-13 21:15:29 +01:00
"Community-list name\n"
"Delete matching communities\n")
DEFUN (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"
2002-12-13 21:15:29 +01:00
"VPN extended community\n")
{
int ret;
char *str;
str = argv_concat (argv, argc, 0);
ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
XFREE (MTYPE_TMP, str);
return ret;
}
DEFUN (no_set_ecommunity_rt,
no_set_ecommunity_rt_cmd,
"no set extcommunity rt",
NO_STR
SET_STR
"BGP extended community attribute\n"
"Route Target extended community\n")
2002-12-13 21:15:29 +01:00
{
return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
}
ALIAS (no_set_ecommunity_rt,
no_set_ecommunity_rt_val_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"
2002-12-13 21:15:29 +01:00
"VPN extended community\n")
DEFUN (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")
{
int ret;
char *str;
str = argv_concat (argv, argc, 0);
ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
XFREE (MTYPE_TMP, str);
return ret;
}
DEFUN (no_set_ecommunity_soo,
no_set_ecommunity_soo_cmd,
"no set extcommunity soo",
NO_STR
SET_STR
"BGP extended community attribute\n"
"Site-of-Origin extended community\n")
{
return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
}
ALIAS (no_set_ecommunity_soo,
no_set_ecommunity_soo_val_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")
DEFUN (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")
{
if (strncmp (argv[0], "igp", 2) == 0)
return bgp_route_set_add (vty, vty->index, "origin", "igp");
if (strncmp (argv[0], "egp", 1) == 0)
return bgp_route_set_add (vty, vty->index, "origin", "egp");
if (strncmp (argv[0], "incomplete", 2) == 0)
return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
return CMD_WARNING;
}
DEFUN (no_set_origin,
no_set_origin_cmd,
"no set origin",
NO_STR
SET_STR
"BGP origin code\n")
{
return bgp_route_set_delete (vty, vty->index, "origin", NULL);
}
ALIAS (no_set_origin,
no_set_origin_val_cmd,
"no set origin (egp|igp|incomplete)",
NO_STR
SET_STR
"BGP origin code\n"
"remote EGP\n"
"local IGP\n"
"unknown heritage\n")
DEFUN (set_atomic_aggregate,
set_atomic_aggregate_cmd,
"set atomic-aggregate",
SET_STR
"BGP atomic aggregate attribute\n" )
{
return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
}
DEFUN (no_set_atomic_aggregate,
no_set_atomic_aggregate_cmd,
"no set atomic-aggregate",
NO_STR
SET_STR
"BGP atomic aggregate attribute\n" )
{
return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
}
DEFUN (set_aggregator_as,
set_aggregator_as_cmd,
"set aggregator as " CMD_AS_RANGE " A.B.C.D",
2002-12-13 21:15:29 +01:00
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
"AS number\n"
"IP address of aggregator\n")
{
int ret;
struct in_addr address;
char *argstr;
2002-12-13 21:15:29 +01:00
ret = inet_aton (argv[1], &address);
if (ret == 0)
{
vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
strlen (argv[0]) + strlen (argv[1]) + 2);
sprintf (argstr, "%s %s", argv[0], argv[1]);
ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
return ret;
}
DEFUN (no_set_aggregator_as,
no_set_aggregator_as_cmd,
"no set aggregator as",
NO_STR
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n")
{
int ret;
struct in_addr address;
char *argstr;
if (argv == 0)
return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
ret = inet_aton (argv[1], &address);
if (ret == 0)
{
vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
strlen (argv[0]) + strlen (argv[1]) + 2);
sprintf (argstr, "%s %s", argv[0], argv[1]);
ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
return ret;
}
ALIAS (no_set_aggregator_as,
no_set_aggregator_as_val_cmd,
"no set aggregator as " CMD_AS_RANGE " A.B.C.D",
2002-12-13 21:15:29 +01:00
NO_STR
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
"AS number\n"
"IP address of aggregator\n")
DEFUN (set_tag,
set_tag_cmd,
"set tag <1-4294967295>",
SET_STR
"Tag value for routing protocol\n"
"Tag value\n")
{
return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
}
DEFUN (no_set_tag,
no_set_tag_cmd,
"no set tag",
NO_STR
SET_STR
"Tag value for routing protocol\n")
{
if (argc == 0)
bgp_route_set_delete(vty, vty->index, "tag", NULL);
return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
}
ALIAS (no_set_tag,
no_set_tag_val_cmd,
"no set tag <1-4294967295>",
NO_STR
SET_STR
"Tag value for routing protocol\n"
"Tag value\n")
2002-12-13 21:15:29 +01:00
#ifdef HAVE_IPV6
DEFUN (match_ipv6_address,
match_ipv6_address_cmd,
"match ipv6 address WORD",
MATCH_STR
IPV6_STR
"Match IPv6 address of route\n"
"IPv6 access-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0],
RMAP_EVENT_FILTER_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ipv6_address,
no_match_ipv6_address_cmd,
"no match ipv6 address WORD",
NO_STR
MATCH_STR
IPV6_STR
"Match IPv6 address of route\n"
"IPv6 access-list name\n")
{
return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0],
RMAP_EVENT_FILTER_DELETED);
2002-12-13 21:15:29 +01:00
}
DEFUN (match_ipv6_next_hop,
match_ipv6_next_hop_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")
{
return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0],
RMAP_EVENT_MATCH_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ipv6_next_hop,
no_match_ipv6_next_hop_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")
{
return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0],
RMAP_EVENT_MATCH_DELETED);
2002-12-13 21:15:29 +01:00
}
DEFUN (match_ipv6_address_prefix_list,
match_ipv6_address_prefix_list_cmd,
"match ipv6 address prefix-list WORD",
MATCH_STR
IPV6_STR
"Match address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list",
argv[0], RMAP_EVENT_PLIST_ADDED);
2002-12-13 21:15:29 +01:00
}
DEFUN (no_match_ipv6_address_prefix_list,
no_match_ipv6_address_prefix_list_cmd,
"no match ipv6 address prefix-list WORD",
NO_STR
MATCH_STR
IPV6_STR
"Match address of route\n"
"Match entries of prefix-lists\n"
"IP prefix-list name\n")
{
return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list",
argv[0], RMAP_EVENT_PLIST_DELETED);
2002-12-13 21:15:29 +01:00
}
DEFUN (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")
{
return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
}
DEFUN (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")
{
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop peer-address", NULL);
}
DEFUN (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")
{
return bgp_route_set_add (vty, vty->index, "ipv6 next-hop prefer-global", NULL);;
}
DEFUN (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")
{
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop prefer-global", NULL);
}
2002-12-13 21:15:29 +01:00
DEFUN (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")
{
struct in6_addr addr;
int ret;
ret = inet_pton (AF_INET6, argv[0], &addr);
if (!ret)
{
vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
IN6_IS_ADDR_LOOPBACK(&addr) ||
IN6_IS_ADDR_MULTICAST(&addr) ||
IN6_IS_ADDR_LINKLOCAL(&addr))
{
vty_out (vty, "%% Invalid global nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
2002-12-13 21:15:29 +01:00
return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
}
DEFUN (no_set_ipv6_nexthop_global,
no_set_ipv6_nexthop_global_cmd,
"no set ipv6 next-hop global",
NO_STR
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
"IPv6 global address\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
}
ALIAS (no_set_ipv6_nexthop_global,
no_set_ipv6_nexthop_global_val_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")
DEFUN (set_ipv6_nexthop_local,
set_ipv6_nexthop_local_cmd,
"set ipv6 next-hop local X:X::X:X",
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
"IPv6 local address\n"
"IPv6 address of next hop\n")
{
struct in6_addr addr;
int ret;
ret = inet_pton (AF_INET6, argv[0], &addr);
if (!ret)
{
vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (!IN6_IS_ADDR_LINKLOCAL(&addr))
{
vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE);
return CMD_WARNING;
}
2002-12-13 21:15:29 +01:00
return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
}
DEFUN (no_set_ipv6_nexthop_local,
no_set_ipv6_nexthop_local_cmd,
"no set ipv6 next-hop local",
NO_STR
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
"IPv6 local address\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
}
ALIAS (no_set_ipv6_nexthop_local,
no_set_ipv6_nexthop_local_val_cmd,
"no set ipv6 next-hop local X:X::X:X",
NO_STR
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
"IPv6 local address\n"
"IPv6 address of next hop\n")
#endif /* HAVE_IPV6 */
DEFUN (set_vpnv4_nexthop,
set_vpnv4_nexthop_cmd,
"set vpnv4 next-hop A.B.C.D",
SET_STR
"VPNv4 information\n"
"VPNv4 next-hop address\n"
"IP address of next hop\n")
{
return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
}
DEFUN (no_set_vpnv4_nexthop,
no_set_vpnv4_nexthop_cmd,
"no set vpnv4 next-hop",
NO_STR
SET_STR
"VPNv4 information\n"
"VPNv4 next-hop address\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
}
ALIAS (no_set_vpnv4_nexthop,
no_set_vpnv4_nexthop_val_cmd,
"no set vpnv4 next-hop A.B.C.D",
NO_STR
SET_STR
"VPNv4 information\n"
"VPNv4 next-hop address\n"
"IP address of next hop\n")
DEFUN (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")
{
return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
}
DEFUN (no_set_originator_id,
no_set_originator_id_cmd,
"no set originator-id",
NO_STR
SET_STR
"BGP originator ID attribute\n")
{
if (argc == 0)
return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
}
ALIAS (no_set_originator_id,
no_set_originator_id_val_cmd,
"no set originator-id A.B.C.D",
NO_STR
SET_STR
"BGP originator ID attribute\n"
"IP address of originator\n")
/* Initialization of route map. */
void
bgp_route_map_init (void)
2002-12-13 21:15:29 +01:00
{
route_map_init ();
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);
2002-12-13 21:15:29 +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
route_map_install_match (&route_match_peer_cmd);
route_map_install_match (&route_match_local_pref_cmd);
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);
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);
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);
route_map_install_match (&route_match_ecommunity_cmd);
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);
route_map_install_match (&route_match_probability_cmd);
route_map_install_match (&route_match_interface_cmd);
route_map_install_match (&route_match_tag_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);
route_map_install_set (&route_set_metric_cmd);
route_map_install_set (&route_set_aspath_prepend_cmd);
route_map_install_set (&route_set_aspath_exclude_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);
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);
route_map_install_set (&route_set_vpnv4_nexthop_cmd);
route_map_install_set (&route_set_originator_id_cmd);
route_map_install_set (&route_set_ecommunity_rt_cmd);
route_map_install_set (&route_set_ecommunity_soo_cmd);
route_map_install_set (&route_set_tag_cmd);
2002-12-13 21:15:29 +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
install_element (RMAP_NODE, &match_peer_cmd);
install_element (RMAP_NODE, &match_peer_local_cmd);
install_element (RMAP_NODE, &no_match_peer_cmd);
install_element (RMAP_NODE, &no_match_peer_val_cmd);
install_element (RMAP_NODE, &no_match_peer_local_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &match_ip_address_cmd);
install_element (RMAP_NODE, &no_match_ip_address_cmd);
install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
install_element (RMAP_NODE, &match_ip_next_hop_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
install_element (RMAP_NODE, &match_ip_route_source_cmd);
install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &match_aspath_cmd);
install_element (RMAP_NODE, &no_match_aspath_cmd);
install_element (RMAP_NODE, &no_match_aspath_val_cmd);
install_element (RMAP_NODE, &match_metric_cmd);
install_element (RMAP_NODE, &no_match_metric_cmd);
install_element (RMAP_NODE, &no_match_metric_val_cmd);
install_element (RMAP_NODE, &match_local_pref_cmd);
install_element (RMAP_NODE, &no_match_local_pref_cmd);
install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &match_community_cmd);
install_element (RMAP_NODE, &match_community_exact_cmd);
install_element (RMAP_NODE, &no_match_community_cmd);
install_element (RMAP_NODE, &no_match_community_val_cmd);
install_element (RMAP_NODE, &no_match_community_exact_cmd);
install_element (RMAP_NODE, &match_ecommunity_cmd);
install_element (RMAP_NODE, &no_match_ecommunity_cmd);
install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &match_origin_cmd);
install_element (RMAP_NODE, &no_match_origin_cmd);
install_element (RMAP_NODE, &no_match_origin_val_cmd);
install_element (RMAP_NODE, &match_probability_cmd);
install_element (RMAP_NODE, &no_match_probability_cmd);
install_element (RMAP_NODE, &no_match_probability_val_cmd);
install_element (RMAP_NODE, &match_interface_cmd);
install_element (RMAP_NODE, &no_match_interface_cmd);
install_element (RMAP_NODE, &no_match_interface_val_cmd);
install_element (RMAP_NODE, &match_tag_cmd);
install_element (RMAP_NODE, &no_match_tag_cmd);
install_element (RMAP_NODE, &no_match_tag_val_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &set_ip_nexthop_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
install_element (RMAP_NODE, &set_ip_nexthop_unchanged_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
install_element (RMAP_NODE, &no_set_ip_nexthop_peer_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &set_local_pref_cmd);
install_element (RMAP_NODE, &no_set_local_pref_cmd);
install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
install_element (RMAP_NODE, &set_weight_cmd);
install_element (RMAP_NODE, &no_set_weight_cmd);
install_element (RMAP_NODE, &no_set_weight_val_cmd);
install_element (RMAP_NODE, &set_metric_cmd);
install_element (RMAP_NODE, &set_metric_addsub_cmd);
install_element (RMAP_NODE, &set_metric_rtt_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &no_set_metric_cmd);
install_element (RMAP_NODE, &no_set_metric_val_cmd);
install_element (RMAP_NODE, &set_aspath_prepend_cmd);
install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
install_element (RMAP_NODE, &set_aspath_exclude_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
install_element (RMAP_NODE, &no_set_aspath_exclude_val_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, &no_set_origin_val_cmd);
install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
install_element (RMAP_NODE, &set_aggregator_as_cmd);
install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
install_element (RMAP_NODE, &set_community_cmd);
install_element (RMAP_NODE, &set_community_none_cmd);
install_element (RMAP_NODE, &no_set_community_cmd);
install_element (RMAP_NODE, &no_set_community_val_cmd);
install_element (RMAP_NODE, &no_set_community_none_cmd);
install_element (RMAP_NODE, &set_community_delete_cmd);
install_element (RMAP_NODE, &no_set_community_delete_cmd);
install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
install_element (RMAP_NODE, &set_originator_id_cmd);
install_element (RMAP_NODE, &no_set_originator_id_cmd);
install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
install_element (RMAP_NODE, &set_tag_cmd);
install_element (RMAP_NODE, &no_set_tag_cmd);
install_element (RMAP_NODE, &no_set_tag_val_cmd);
2002-12-13 21:15:29 +01:00
#ifdef HAVE_IPV6
route_map_install_match (&route_match_ipv6_address_cmd);
route_map_install_match (&route_match_ipv6_next_hop_cmd);
route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
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);
route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &match_ipv6_address_cmd);
install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
2002-12-13 21:15:29 +01:00
install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
2002-12-13 21:15:29 +01:00
#endif /* HAVE_IPV6 */
}
void
bgp_route_map_terminate (void)
{
/* ToDo: Cleanup all the used memory */
route_map_add_hook (NULL);
route_map_delete_hook (NULL);
route_map_event_hook (NULL);
route_map_finish();
}