frr/lib/routemap.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1019 lines
38 KiB
C
Raw Normal View History

2002-12-13 21:15:29 +01:00
/* Route map function.
* Copyright (C) 1998 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 this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2002-12-13 21:15:29 +01:00
*/
#ifndef _ZEBRA_ROUTEMAP_H
#define _ZEBRA_ROUTEMAP_H
#include "typesafe.h"
#include "prefix.h"
#include "memory.h"
#include "qobj.h"
#include "vty.h"
#include "lib/plist.h"
#include "lib/plist_int.h"
#ifdef __cplusplus
extern "C" {
#endif
DECLARE_MTYPE(ROUTE_MAP_NAME);
DECLARE_MTYPE(ROUTE_MAP_RULE);
DECLARE_MTYPE(ROUTE_MAP_COMPILED);
2002-12-13 21:15:29 +01:00
/* Route map's type. */
enum route_map_type { RMAP_PERMIT, RMAP_DENY, RMAP_ANY };
2002-12-13 21:15:29 +01:00
typedef enum {
RMAP_DENYMATCH,
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
RMAP_PERMITMATCH
2002-12-13 21:15:29 +01:00
} route_map_result_t;
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
/*
* Route-map match or set result "Eg: match evpn vni xx"
* route-map match cmd always returns match/nomatch/noop
* match--> found a match
* nomatch--> didnt find a match
* noop--> not applicable
* route-map set retuns okay/error
* okay --> set was successful
* error --> set was not successful
*/
enum route_map_cmd_result_t {
/*
* route-map match cmd results
*/
RMAP_MATCH,
RMAP_NOMATCH,
RMAP_NOOP,
/*
* route-map set cmd results
*/
RMAP_OKAY,
RMAP_ERROR
};
2002-12-13 21:15:29 +01:00
typedef enum { RMAP_EXIT, RMAP_GOTO, RMAP_NEXT } route_map_end_t;
2002-12-13 21:15:29 +01:00
typedef enum {
RMAP_EVENT_SET_ADDED,
RMAP_EVENT_SET_DELETED,
RMAP_EVENT_SET_REPLACED,
RMAP_EVENT_MATCH_ADDED,
RMAP_EVENT_MATCH_DELETED,
RMAP_EVENT_MATCH_REPLACED,
RMAP_EVENT_INDEX_ADDED,
RMAP_EVENT_INDEX_DELETED,
RMAP_EVENT_CALL_ADDED, /* call to another routemap added */
RMAP_EVENT_CALL_DELETED,
RMAP_EVENT_PLIST_ADDED,
RMAP_EVENT_PLIST_DELETED,
RMAP_EVENT_CLIST_ADDED,
RMAP_EVENT_CLIST_DELETED,
RMAP_EVENT_ECLIST_ADDED,
RMAP_EVENT_ECLIST_DELETED,
RMAP_EVENT_LLIST_ADDED,
RMAP_EVENT_LLIST_DELETED,
RMAP_EVENT_ASLIST_ADDED,
RMAP_EVENT_ASLIST_DELETED,
RMAP_EVENT_FILTER_ADDED,
RMAP_EVENT_FILTER_DELETED,
2002-12-13 21:15:29 +01:00
} route_map_event_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
/* Depth limit in RMAP recursion using RMAP_CALL. */
#define RMAP_RECURSION_LIMIT 10
2002-12-13 21:15:29 +01:00
/* Route map rule structure for matching and setting. */
struct route_map_rule_cmd {
/* Route map rule name (e.g. as-path, metric) */
2004-10-08 08:29:12 +02:00
const char *str;
2002-12-13 21:15:29 +01:00
/* Function for value set or match. */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
enum route_map_cmd_result_t (*func_apply)(void *rule,
const struct prefix *prefix,
void *object);
2002-12-13 21:15:29 +01:00
/* Compile argument and return result as void *. */
void *(*func_compile)(const char *);
2002-12-13 21:15:29 +01:00
/* Free allocated value by func_compile (). */
void (*func_free)(void *);
/** To get the rule key after Compilation **/
void *(*func_get_rmap_rule_key)(void *val);
2002-12-13 21:15:29 +01:00
};
/* Route map apply error. */
enum rmap_compile_rets {
RMAP_COMPILE_SUCCESS,
/* Route map rule is missing. */
RMAP_RULE_MISSING,
2002-12-13 21:15:29 +01:00
/* Route map rule can't compile */
RMAP_COMPILE_ERROR,
};
2002-12-13 21:15:29 +01:00
/* Route map rule. This rule has both `match' rule and `set' rule. */
struct route_map_rule {
/* Rule type. */
const struct route_map_rule_cmd *cmd;
/* For pretty printing. */
char *rule_str;
/* Pre-compiled match rule. */
void *value;
/* Linked list. */
struct route_map_rule *next;
struct route_map_rule *prev;
};
2002-12-13 21:15:29 +01:00
/* Route map rule list. */
struct route_map_rule_list {
struct route_map_rule *head;
struct route_map_rule *tail;
};
/* Forward struct declaration: the complete can be found later this file. */
struct routemap_hook_context;
2002-12-13 21:15:29 +01:00
/* Route map index structure. */
struct route_map_index {
struct route_map *map;
char *description;
2002-12-13 21:15:29 +01:00
/* Preference of this route map rule. */
int pref;
/* Route map type permit or deny. */
enum route_map_type type;
/* Do we follow old rules, or hop forward? */
route_map_end_t exitpolicy;
/* If we're using "GOTO", to where do we go? */
int nextpref;
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 we're using "CALL", to which route-map do ew go? */
char *nextrm;
2002-12-13 21:15:29 +01:00
/* Matching rule list. */
struct route_map_rule_list match_list;
struct route_map_rule_list set_list;
/* Make linked list. */
struct route_map_index *next;
struct route_map_index *prev;
/* Keep track how many times we've try to apply */
uint64_t applied;
uint64_t applied_clear;
/* List of match/sets contexts. */
TAILQ_HEAD(, routemap_hook_context) rhclist;
QOBJ_FIELDS;
2002-12-13 21:15:29 +01:00
};
DECLARE_QOBJ_TYPE(route_map_index);
2002-12-13 21:15:29 +01:00
/* route map maximum length. Not strictly the maximum xpath length but cannot be
* greater
*/
#define RMAP_NAME_MAXLEN XPATH_MAXLEN
2002-12-13 21:15:29 +01:00
/* Route map list structure. */
struct route_map {
/* Name of route map. */
char *name;
/* Route map's rule. */
struct route_map_index *head;
struct route_map_index *tail;
/* Make linked list. */
struct route_map *next;
struct route_map *prev;
/* Maintain update info */
bool to_be_processed; /* True if modification isn't acted on yet */
bool deleted; /* If 1, then this node will be deleted */
bool optimization_disabled;
/* How many times have we applied this route-map */
uint64_t applied;
uint64_t applied_clear;
/* Counter to track active usage of this route-map */
uint16_t use_count;
/* Tables to maintain IPv4 and IPv6 prefixes from
* the prefix-list match clause.
*/
struct route_table *ipv4_prefix_table;
struct route_table *ipv6_prefix_table;
QOBJ_FIELDS;
2002-12-13 21:15:29 +01:00
};
DECLARE_QOBJ_TYPE(route_map);
2002-12-13 21:15:29 +01:00
/* Route-map match conditions */
#define IS_MATCH_INTERFACE(C) \
(strmatch(C, "frr-route-map:interface"))
#define IS_MATCH_IPv4_ADDRESS_LIST(C) \
(strmatch(C, "frr-route-map:ipv4-address-list"))
#define IS_MATCH_IPv6_ADDRESS_LIST(C) \
(strmatch(C, "frr-route-map:ipv6-address-list"))
#define IS_MATCH_IPv4_NEXTHOP_LIST(C) \
(strmatch(C, "frr-route-map:ipv4-next-hop-list"))
#define IS_MATCH_IPv6_NEXTHOP_LIST(C) \
(strmatch(C, "frr-route-map:ipv6-next-hop-list"))
#define IS_MATCH_IPv4_PREFIX_LIST(C) \
(strmatch(C, "frr-route-map:ipv4-prefix-list"))
#define IS_MATCH_IPv6_PREFIX_LIST(C) \
(strmatch(C, "frr-route-map:ipv6-prefix-list"))
#define IS_MATCH_IPv4_NEXTHOP_PREFIX_LIST(C) \
(strmatch(C, "frr-route-map:ipv4-next-hop-prefix-list"))
#define IS_MATCH_IPv6_NEXTHOP_PREFIX_LIST(C) \
(strmatch(C, "frr-route-map:ipv6-next-hop-prefix-list"))
#define IS_MATCH_IPv4_NEXTHOP_TYPE(C) \
(strmatch(C, "frr-route-map:ipv4-next-hop-type"))
#define IS_MATCH_IPv6_NEXTHOP_TYPE(C) \
(strmatch(C, "frr-route-map:ipv6-next-hop-type"))
#define IS_MATCH_METRIC(C) \
(strmatch(C, "frr-route-map:match-metric"))
#define IS_MATCH_TAG(C) (strmatch(C, "frr-route-map:match-tag"))
/* Zebra route-map match conditions */
#define IS_MATCH_IPv4_PREFIX_LEN(C) \
(strmatch(C, "frr-zebra-route-map:ipv4-prefix-length"))
#define IS_MATCH_IPv6_PREFIX_LEN(C) \
(strmatch(C, "frr-zebra-route-map:ipv6-prefix-length"))
#define IS_MATCH_IPv4_NH_PREFIX_LEN(C) \
(strmatch(C, "frr-zebra-route-map:ipv4-next-hop-prefix-length"))
#define IS_MATCH_SRC_PROTO(C) \
(strmatch(C, "frr-zebra-route-map:source-protocol"))
#define IS_MATCH_SRC_INSTANCE(C) \
(strmatch(C, "frr-zebra-route-map:source-instance"))
/* BGP route-map match conditions */
#define IS_MATCH_LOCAL_PREF(C) \
(strmatch(C, "frr-bgp-route-map:match-local-preference"))
#define IS_MATCH_ALIAS(C) (strmatch(C, "frr-bgp-route-map:match-alias"))
#define IS_MATCH_SCRIPT(C) (strmatch(C, "frr-bgp-route-map:match-script"))
#define IS_MATCH_ORIGIN(C) \
(strmatch(C, "frr-bgp-route-map:match-origin"))
#define IS_MATCH_RPKI(C) (strmatch(C, "frr-bgp-route-map:rpki"))
#define IS_MATCH_PROBABILITY(C) \
(strmatch(C, "frr-bgp-route-map:probability"))
#define IS_MATCH_SRC_VRF(C) \
(strmatch(C, "frr-bgp-route-map:source-vrf"))
#define IS_MATCH_PEER(C) (strmatch(C, "frr-bgp-route-map:peer"))
#define IS_MATCH_AS_LIST(C) \
(strmatch(C, "frr-bgp-route-map:as-path-list"))
#define IS_MATCH_MAC_LIST(C) \
(strmatch(C, "frr-bgp-route-map:mac-address-list"))
#define IS_MATCH_EVPN_ROUTE_TYPE(C) \
(strmatch(C, "frr-bgp-route-map:evpn-route-type"))
#define IS_MATCH_EVPN_DEFAULT_ROUTE(C) \
(strmatch(C, "frr-bgp-route-map:evpn-default-route"))
#define IS_MATCH_EVPN_VNI(C) \
(strmatch(C, "frr-bgp-route-map:evpn-vni"))
#define IS_MATCH_EVPN_DEFAULT_ROUTE(C) \
(strmatch(C, "frr-bgp-route-map:evpn-default-route"))
#define IS_MATCH_EVPN_RD(C) \
(strmatch(C, "frr-bgp-route-map:evpn-rd"))
#define IS_MATCH_ROUTE_SRC(C) \
(strmatch(C, "frr-bgp-route-map:ip-route-source"))
#define IS_MATCH_ROUTE_SRC_PL(C) \
(strmatch(C, "frr-bgp-route-map:ip-route-source-prefix-list"))
#define IS_MATCH_COMMUNITY(C) \
(strmatch(C, "frr-bgp-route-map:match-community"))
#define IS_MATCH_LCOMMUNITY(C) \
(strmatch(C, "frr-bgp-route-map:match-large-community"))
#define IS_MATCH_EXTCOMMUNITY(C) \
(strmatch(C, "frr-bgp-route-map:match-extcommunity"))
#define IS_MATCH_IPV4_NH(C) \
(strmatch(C, "frr-bgp-route-map:ipv4-nexthop"))
#define IS_MATCH_IPV6_NH(C) \
(strmatch(C, "frr-bgp-route-map:ipv6-nexthop"))
/* Route-map set actions */
#define IS_SET_IPv4_NH(A) \
(strmatch(A, "frr-route-map:ipv4-next-hop"))
#define IS_SET_IPv6_NH(A) \
(strmatch(A, "frr-route-map:ipv6-next-hop"))
#define IS_SET_METRIC(A) \
(strmatch(A, "frr-route-map:set-metric"))
#define IS_SET_TAG(A) (strmatch(A, "frr-route-map:set-tag"))
#define IS_SET_SR_TE_COLOR(A) \
(strmatch(A, "frr-route-map:set-sr-te-color"))
/* Zebra route-map set actions */
#define IS_SET_SRC(A) \
(strmatch(A, "frr-zebra-route-map:src-address"))
/* OSPF route-map set actions */
#define IS_SET_METRIC_TYPE(A) \
(strmatch(A, "frr-ospf-route-map:metric-type"))
#define IS_SET_FORWARDING_ADDR(A) \
(strmatch(A, "frr-ospf6-route-map:forwarding-address"))
/* BGP route-map_set actions */
#define IS_SET_WEIGHT(A) \
(strmatch(A, "frr-bgp-route-map:weight"))
#define IS_SET_TABLE(A) (strmatch(A, "frr-bgp-route-map:table"))
#define IS_SET_LOCAL_PREF(A) \
(strmatch(A, "frr-bgp-route-map:set-local-preference"))
#define IS_SET_LABEL_INDEX(A) \
(strmatch(A, "frr-bgp-route-map:label-index"))
#define IS_SET_DISTANCE(A) \
(strmatch(A, "frr-bgp-route-map:distance"))
#define IS_SET_ORIGIN(A) \
(strmatch(A, "frr-bgp-route-map:set-origin"))
#define IS_SET_ATOMIC_AGGREGATE(A) \
(strmatch(A, "frr-bgp-route-map:atomic-aggregate"))
#define IS_SET_ORIGINATOR_ID(A) \
(strmatch(A, "frr-bgp-route-map:originator-id"))
#define IS_SET_COMM_LIST_DEL(A) \
(strmatch(A, "frr-bgp-route-map:comm-list-delete"))
#define IS_SET_LCOMM_LIST_DEL(A) \
(strmatch(A, "frr-bgp-route-map:large-comm-list-delete"))
#define IS_SET_LCOMMUNITY(A) \
(strmatch(A, "frr-bgp-route-map:set-large-community"))
#define IS_SET_COMMUNITY(A) \
(strmatch(A, "frr-bgp-route-map:set-community"))
#define IS_SET_EXTCOMMUNITY_NONE(A) \
(strmatch(A, "frr-bgp-route-map:set-extcommunity-none"))
#define IS_SET_EXTCOMMUNITY_RT(A) \
(strmatch(A, "frr-bgp-route-map:set-extcommunity-rt"))
#define IS_SET_EXTCOMMUNITY_SOO(A) \
(strmatch(A, "frr-bgp-route-map:set-extcommunity-soo"))
#define IS_SET_EXTCOMMUNITY_LB(A) \
(strmatch(A, "frr-bgp-route-map:set-extcommunity-lb"))
#define IS_SET_AGGREGATOR(A) \
(strmatch(A, "frr-bgp-route-map:aggregator"))
#define IS_SET_AS_PREPEND(A) \
(strmatch(A, "frr-bgp-route-map:as-path-prepend"))
#define IS_SET_AS_EXCLUDE(A) \
(strmatch(A, "frr-bgp-route-map:as-path-exclude"))
#define IS_SET_AS_REPLACE(A) (strmatch(A, "frr-bgp-route-map:as-path-replace"))
#define IS_SET_IPV6_NH_GLOBAL(A) \
(strmatch(A, "frr-bgp-route-map:ipv6-nexthop-global"))
#define IS_SET_IPV6_VPN_NH(A) \
(strmatch(A, "frr-bgp-route-map:ipv6-vpn-address"))
#define IS_SET_IPV6_PEER_ADDR(A) \
(strmatch(A, "frr-bgp-route-map:ipv6-peer-address"))
#define IS_SET_IPV6_PREFER_GLOBAL(A) \
(strmatch(A, "frr-bgp-route-map:ipv6-prefer-global"))
#define IS_SET_IPV4_VPN_NH(A) \
(strmatch(A, "frr-bgp-route-map:ipv4-vpn-address"))
#define IS_SET_BGP_IPV4_NH(A) \
(strmatch(A, "frr-bgp-route-map:set-ipv4-nexthop"))
#define IS_SET_BGP_EVPN_GATEWAY_IP_IPV4(A) \
(strmatch(A, "frr-bgp-route-map:set-evpn-gateway-ip-ipv4"))
#define IS_SET_BGP_EVPN_GATEWAY_IP_IPV6(A) \
(strmatch(A, "frr-bgp-route-map:set-evpn-gateway-ip-ipv6"))
enum ecommunity_lb_type {
EXPLICIT_BANDWIDTH,
CUMULATIVE_BANDWIDTH,
COMPUTED_BANDWIDTH
};
2002-12-13 21:15:29 +01:00
/* Prototypes. */
extern void route_map_init(void);
/*
* This should only be called on shutdown
* Additionally this function sets the hooks to NULL
* before any processing is done.
*/
[bgpd] Stability fixes including bugs 397, 492 I've spent the last several weeks working on stability fixes to bgpd. These patches fix all of the numerous crashes, assertion failures, memory leaks and memory stomping I could find. Valgrind was used extensively. Added new function bgp_exit() to help catch problems. If "debug bgp" is configured and bgpd exits with status of 0, statistics on remaining lib/memory.c allocations are printed to stderr. It is my hope that other developers will use this to stay on top of memory issues. Example questionable exit: bgpd: memstats: Current memory utilization in module LIB: bgpd: memstats: Link List : 6 bgpd: memstats: Link Node : 5 bgpd: memstats: Hash : 8 bgpd: memstats: Hash Bucket : 2 bgpd: memstats: Hash Index : 8 bgpd: memstats: Work queue : 3 bgpd: memstats: Work queue item : 2 bgpd: memstats: Work queue name string : 3 bgpd: memstats: Current memory utilization in module BGP: bgpd: memstats: BGP instance : 1 bgpd: memstats: BGP peer : 1 bgpd: memstats: BGP peer hostname : 1 bgpd: memstats: BGP attribute : 1 bgpd: memstats: BGP extra attributes : 1 bgpd: memstats: BGP aspath : 1 bgpd: memstats: BGP aspath str : 1 bgpd: memstats: BGP table : 24 bgpd: memstats: BGP node : 1 bgpd: memstats: BGP route : 1 bgpd: memstats: BGP synchronise : 8 bgpd: memstats: BGP Process queue : 1 bgpd: memstats: BGP node clear queue : 1 bgpd: memstats: NOTE: If configuration exists, utilization may be expected. Example clean exit: bgpd: memstats: No remaining tracked memory utilization. This patch fixes bug #397: "Invalid free in bgp_announce_check()". This patch fixes bug #492: "SIGBUS in bgpd/bgp_route.c: bgp_clear_route_node()". My apologies for not separating out these changes into individual patches. The complexity of doing so boggled what is left of my brain. I hope this is all still useful to the community. This code has been production tested, in non-route-server-client mode, on a linux 32-bit box and a 64-bit box. Release/reset functions, used by bgp_exit(), added to: bgpd/bgp_attr.c,h bgpd/bgp_community.c,h bgpd/bgp_dump.c,h bgpd/bgp_ecommunity.c,h bgpd/bgp_filter.c,h bgpd/bgp_nexthop.c,h bgpd/bgp_route.c,h lib/routemap.c,h File by file analysis: * bgpd/bgp_aspath.c: Prevent re-use of ashash after it is released. * bgpd/bgp_attr.c: #if removed uncalled cluster_dup(). * bgpd/bgp_clist.c,h: Allow community_list_terminate() to be called from bgp_exit(). * bgpd/bgp_filter.c: Fix aslist->name use without allocation check, and also fix memory leak. * bgpd/bgp_main.c: Created bgp_exit() exit routine. This function frees allocations made as part of bgpd initialization and, to some extent, configuration. If "debug bgp" is configured, memory stats are printed as described above. * bgpd/bgp_nexthop.c: zclient_new() already allocates stream for ibuf/obuf, so bgp_scan_init() shouldn't do it too. Also, made it so zlookup is global so bgp_exit() can use it. * bgpd/bgp_packet.c: bgp_capability_msg_parse() call to bgp_clear_route() adjusted to use new BGP_CLEAR_ROUTE_NORMAL flag. * bgpd/bgp_route.h: Correct reference counter "lock" to be signed. bgp_clear_route() now accepts a bgp_clear_route_type of either BGP_CLEAR_ROUTE_NORMAL or BGP_CLEAR_ROUTE_MY_RSCLIENT. * bgpd/bgp_route.c: - bgp_process_rsclient(): attr was being zero'ed and then bgp_attr_extra_free() was being called with it, even though it was never filled with valid data. - bgp_process_rsclient(): Make sure rsclient->group is not NULL before use. - bgp_processq_del(): Add call to bgp_table_unlock(). - bgp_process(): Add call to bgp_table_lock(). - bgp_update_rsclient(): memset clearing of new_attr not needed since declarationw with "= { 0 }" does it. memset was already commented out. - bgp_update_rsclient(): Fix screwed up misleading indentation. - bgp_withdraw_rsclient(): Fix screwed up misleading indentation. - bgp_clear_route_node(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT. - bgp_clear_node_queue_del(): Add call to bgp_table_unlock() and also free struct bgp_clear_node_queue used for work item. - bgp_clear_node_complete(): Do peer_unlock() after BGP_EVENT_ADD() in case peer is released by peer_unlock() call. - bgp_clear_route_table(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT. Use struct bgp_clear_node_queue to supply data to worker. Add call to bgp_table_lock(). - bgp_clear_route(): Add support for BGP_CLEAR_ROUTE_NORMAL or BGP_CLEAR_ROUTE_MY_RSCLIENT. - bgp_clear_route_all(): Use BGP_CLEAR_ROUTE_NORMAL. Bug 397 fixes: - bgp_default_originate() - bgp_announce_table() * bgpd/bgp_table.h: - struct bgp_table: Added reference count. Changed type of owner to be "struct peer *" rather than "void *". - struct bgp_node: Correct reference counter "lock" to be signed. * bgpd/bgp_table.c: - Added bgp_table reference counting. - bgp_table_free(): Fixed cleanup code. Call peer_unlock() on owner if set. - bgp_unlock_node(): Added assertion. - bgp_node_get(): Added call to bgp_lock_node() to code path that it was missing from. * bgpd/bgp_vty.c: - peer_rsclient_set_vty(): Call peer_lock() as part of peer assignment to owner. Handle failure gracefully. - peer_rsclient_unset_vty(): Add call to bgp_clear_route() with BGP_CLEAR_ROUTE_MY_RSCLIENT purpose. * bgpd/bgp_zebra.c: Made it so zclient is global so bgp_exit() can use it. * bgpd/bgpd.c: - peer_lock(): Allow to be called when status is "Deleted". - peer_deactivate(): Supply BGP_CLEAR_ROUTE_NORMAL purpose to bgp_clear_route() call. - peer_delete(): Common variable listnode pn. Fix bug in which rsclient was only dealt with if not part of a peer group. Call bgp_clear_route() for rsclient, if appropriate, and do so with BGP_CLEAR_ROUTE_MY_RSCLIENT purpose. - peer_group_get(): Use XSTRDUP() instead of strdup() for conf->host. - peer_group_bind(): Call bgp_clear_route() for rsclient, and do so with BGP_CLEAR_ROUTE_MY_RSCLIENT purpose. - bgp_create(): Use XSTRDUP() instead of strdup() for peer_self->host. - bgp_delete(): Delete peers before groups, rather than after. And then rather than deleting rsclients, verify that there are none at this point. - bgp_unlock(): Add assertion. - bgp_free(): Call bgp_table_finish() rather than doing XFREE() itself. * lib/command.c,h: Compiler warning fixes. Add cmd_terminate(). Fixed massive leak in install_element() in which cmd_make_descvec() was being called more than once for the same cmd->strvec/string/doc. * lib/log.c: Make closezlog() check fp before calling fclose(). * lib/memory.c: Catch when alloc count goes negative by using signed counts. Correct #endif comment. Add log_memstats_stderr(). * lib/memory.h: Add log_memstats_stderr(). * lib/thread.c: thread->funcname was being accessed in thread_call() after it had been freed. Rearranged things so that thread_call() frees funcname. Also made it so thread_master_free() cleans up cpu_record. * lib/vty.c,h: Use global command_cr. Add vty_terminate(). * lib/zclient.c,h: Re-enable zclient_free().
2009-07-18 07:44:03 +02:00
extern void route_map_finish(void);
2002-12-13 21:15:29 +01:00
/* Add match statement to route map. */
extern enum rmap_compile_rets route_map_add_match(struct route_map_index *index,
const char *match_name,
const char *match_arg,
route_map_event_t type);
2002-12-13 21:15:29 +01:00
/* Delete specified route match rule. */
extern enum rmap_compile_rets
route_map_delete_match(struct route_map_index *index,
const char *match_name, const char *match_arg,
route_map_event_t type);
2002-12-13 21:15:29 +01:00
extern const char *route_map_get_match_arg(struct route_map_index *index,
const char *match_name);
2002-12-13 21:15:29 +01:00
/* Add route-map set statement to the route map. */
extern enum rmap_compile_rets route_map_add_set(struct route_map_index *index,
const char *set_name,
const char *set_arg);
2002-12-13 21:15:29 +01:00
/* Delete route map set rule. */
extern enum rmap_compile_rets
route_map_delete_set(struct route_map_index *index,
const char *set_name, const char *set_arg);
2002-12-13 21:15:29 +01:00
/* struct route_map_rule_cmd is kept const in order to not have writable
* function pointers (which is a security benefit.) Hence, below struct is
* used as proxy for hashing these for by-name lookup.
*/
PREDECL_HASH(rmap_cmd_name);
struct route_map_rule_cmd_proxy {
struct rmap_cmd_name_item itm;
const struct route_map_rule_cmd *cmd;
};
/* ... and just automatically create a proxy struct for each call location
* to route_map_install_{match,set} to avoid unnecessarily added boilerplate
* for each route-map user
*/
#define route_map_install_match(c) \
do { \
static struct route_map_rule_cmd_proxy proxy = {.cmd = c}; \
_route_map_install_match(&proxy); \
} while (0)
#define route_map_install_set(c) \
do { \
static struct route_map_rule_cmd_proxy proxy = {.cmd = c}; \
_route_map_install_set(&proxy); \
} while (0)
2002-12-13 21:15:29 +01:00
/* Install rule command to the match list. */
extern void _route_map_install_match(struct route_map_rule_cmd_proxy *proxy);
2002-12-13 21:15:29 +01:00
/*
* Install rule command to the set list.
*
* When installing a particular item, Allow a difference of handling
* of bad cli inputted(return NULL) -vs- this particular daemon cannot use
* this form of the command(return a pointer and handle it appropriately
* in the apply command). See 'set metric' command
* as it is handled in ripd/ripngd and ospfd.
*/
extern void _route_map_install_set(struct route_map_rule_cmd_proxy *proxy);
2002-12-13 21:15:29 +01:00
/* Lookup route map by name. */
extern struct route_map *route_map_lookup_by_name(const char *name);
2002-12-13 21:15:29 +01:00
/* Simple helper to warn if route-map does not exist. */
struct route_map *route_map_lookup_warn_noexist(struct vty *vty, const char *name);
2002-12-13 21:15:29 +01:00
/* Apply route map to the object. */
extern route_map_result_t route_map_apply_ext(struct route_map *map,
const struct prefix *prefix,
void *match_object,
void *set_object, int *pref);
#define route_map_apply(map, prefix, object) \
route_map_apply_ext(map, prefix, object, object, NULL)
extern void route_map_add_hook(void (*func)(const char *));
extern void route_map_delete_hook(void (*func)(const char *));
/*
* This is the callback for when something has changed about a
* route-map. The interested parties can register to receive
* this data.
*
* name - Is the name of the changed route-map
*/
extern void route_map_event_hook(void (*func)(const char *name));
extern int route_map_mark_updated(const char *name);
extern void route_map_walk_update_list(void (*update_fn)(char *name));
extern void route_map_upd8_dependency(route_map_event_t type, const char *arg,
const char *rmap_name);
extern void route_map_notify_dependencies(const char *affected_name,
route_map_event_t event);
extern void
route_map_notify_pentry_dependencies(const char *affected_name,
struct prefix_list_entry *pentry,
route_map_event_t event);
extern int generic_match_add(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
extern int generic_match_delete(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
extern int generic_set_add(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
extern int generic_set_delete(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* match interface */
extern void route_map_match_interface_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match interface */
extern void route_map_no_match_interface_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ip address */
extern void route_map_match_ip_address_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ip address */
extern void route_map_no_match_ip_address_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ip address prefix list */
extern void route_map_match_ip_address_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ip address prefix list */
extern void route_map_no_match_ip_address_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ip next hop */
extern void route_map_match_ip_next_hop_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ip next hop */
extern void route_map_no_match_ip_next_hop_hook(int (*func)(
struct route_map_index *index, const char *command, const char *arg,
route_map_event_t type, char *errmsg, size_t errmsg_len));
/* match ipv6 next hop */
extern void route_map_match_ipv6_next_hop_hook(int (*func)(
struct route_map_index *index, const char *command, const char *arg,
route_map_event_t type, char *errmsg, size_t errmsg_len));
/* no match ipv6 next hop */
extern void route_map_no_match_ipv6_next_hop_hook(int (*func)(
struct route_map_index *index, const char *command, const char *arg,
route_map_event_t type, char *errmsg, size_t errmsg_len));
/* match ip next hop prefix list */
extern void route_map_match_ip_next_hop_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ip next hop prefix list */
extern void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ip next hop type */
extern void route_map_match_ip_next_hop_type_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ip next hop type */
extern void route_map_no_match_ip_next_hop_type_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ipv6 address */
extern void route_map_match_ipv6_address_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ipv6 address */
extern void route_map_no_match_ipv6_address_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ipv6 address prefix list */
extern void route_map_match_ipv6_address_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ipv6 address prefix list */
extern void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ipv6 next-hop type */
extern void route_map_match_ipv6_next_hop_type_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match ipv6 next-hop type */
extern void route_map_no_match_ipv6_next_hop_type_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match ipv6 next-hop prefix-list */
extern void route_map_match_ipv6_next_hop_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command, const char *arg,
route_map_event_t type, char *errmsg, size_t errmsg_len));
/* no match ipv6 next-hop prefix-list */
extern void route_map_no_match_ipv6_next_hop_prefix_list_hook(int (*func)(
struct route_map_index *index, const char *command, const char *arg,
route_map_event_t type, char *errmsg, size_t errmsg_len));
/* match metric */
extern void route_map_match_metric_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match metric */
extern void route_map_no_match_metric_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* match tag */
extern void route_map_match_tag_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* no match tag */
extern void route_map_no_match_tag_hook(int (*func)(
struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type,
char *errmsg, size_t errmsg_len));
/* set sr-te color */
extern void route_map_set_srte_color_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* no set sr-te color */
extern void route_map_no_set_srte_color_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* set ip nexthop */
extern void route_map_set_ip_nexthop_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* no set ip nexthop */
extern void route_map_no_set_ip_nexthop_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* set ipv6 nexthop local */
extern void route_map_set_ipv6_nexthop_local_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* no set ipv6 nexthop local */
extern void route_map_no_set_ipv6_nexthop_local_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* set metric */
extern void route_map_set_metric_hook(int (*func)(struct route_map_index *index,
const char *command,
const char *arg,
char *errmsg,
size_t errmsg_len));
/* no set metric */
extern void route_map_no_set_metric_hook(
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
/* set tag */
extern void route_map_set_tag_hook(int (*func)(struct route_map_index *index,
const char *command,
const char *arg,
char *errmsg,
size_t errmsg_len));
/* no set tag */
extern void route_map_no_set_tag_hook(int (*func)(struct route_map_index *index,
const char *command,
const char *arg,
char *errmsg,
size_t errmsg_len));
extern void *route_map_rule_tag_compile(const char *arg);
extern void route_map_rule_tag_free(void *rule);
/* Increment the route-map used counter */
extern void route_map_counter_increment(struct route_map *map);
/* Decrement the route-map used counter */
extern void route_map_counter_decrement(struct route_map *map);
/* Route map hooks data structure. */
struct route_map_match_set_hooks {
/* match interface */
int (*match_interface)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match interface */
int (*no_match_interface)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match ip address */
int (*match_ip_address)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ip address */
int (*no_match_ip_address)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match ip address prefix list */
int (*match_ip_address_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ip address prefix list */
int (*no_match_ip_address_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match ip next hop */
int (*match_ip_next_hop)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ip next hop */
int (*no_match_ip_next_hop)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match ipv6 next hop */
int (*match_ipv6_next_hop)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type, char *errmsg,
size_t errmsg_len);
/* no match ipv6 next hop */
int (*no_match_ipv6_next_hop)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type, char *errmsg,
size_t errmsg_len);
/* match ipv6 next hop prefix-list */
int (*match_ipv6_next_hop_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ipv6 next-hop prefix-list */
int (*no_match_ipv6_next_hop_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg,
size_t errmsg_len);
/* match ip next hop prefix list */
int (*match_ip_next_hop_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ip next hop prefix list */
int (*no_match_ip_next_hop_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg,
size_t errmsg_len);
/* match ip next-hop type */
int (*match_ip_next_hop_type)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg,
size_t errmsg_len);
/* no match ip next-hop type */
int (*no_match_ip_next_hop_type)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg,
size_t errmsg_len);
/* match ipv6 address */
int (*match_ipv6_address)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ipv6 address */
int (*no_match_ipv6_address)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match ipv6 address prefix list */
int (*match_ipv6_address_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ipv6 address prefix list */
int (*no_match_ipv6_address_prefix_list)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg,
size_t errmsg_len);
/* match ipv6 next-hop type */
int (*match_ipv6_next_hop_type)(struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match ipv6 next-hop type */
int (*no_match_ipv6_next_hop_type)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match metric */
int (*match_metric)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match metric */
int (*no_match_metric)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* match tag */
int (*match_tag)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* no match tag */
int (*no_match_tag)(struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type,
char *errmsg, size_t errmsg_len);
/* set sr-te color */
int (*set_srte_color)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* no set sr-te color */
int (*no_set_srte_color)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* set ip nexthop */
int (*set_ip_nexthop)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* no set ip nexthop */
int (*no_set_ip_nexthop)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* set ipv6 nexthop local */
int (*set_ipv6_nexthop_local)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* no set ipv6 nexthop local */
int (*no_set_ipv6_nexthop_local)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* set metric */
int (*set_metric)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* no set metric */
int (*no_set_metric)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* set tag */
int (*set_tag)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
/* no set tag */
int (*no_set_tag)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
};
extern struct route_map_match_set_hooks rmap_match_set_hook;
/* Making route map list. */
struct route_map_list {
struct route_map *head;
struct route_map *tail;
void (*add_hook)(const char *);
void (*delete_hook)(const char *);
void (*event_hook)(const char *);
};
extern struct route_map_list route_map_master;
extern struct route_map *route_map_get(const char *name);
extern void route_map_delete(struct route_map *map);
extern struct route_map_index *route_map_index_get(struct route_map *map,
enum route_map_type type,
int pref);
extern void route_map_index_delete(struct route_map_index *index, int notify);
/* routemap_northbound.c */
typedef int (*routemap_match_hook_fun)(struct route_map_index *rmi,
const char *command, const char *arg,
route_map_event_t event,
char *errmsg, size_t errmsg_len);
typedef int (*routemap_set_hook_fun)(struct route_map_index *rmi,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
struct routemap_hook_context {
struct route_map_index *rhc_rmi;
const char *rhc_rule;
route_map_event_t rhc_event;
routemap_set_hook_fun rhc_shook;
routemap_match_hook_fun rhc_mhook;
TAILQ_ENTRY(routemap_hook_context) rhc_entry;
};
int lib_route_map_entry_match_destroy(struct nb_cb_destroy_args *args);
int lib_route_map_entry_set_destroy(struct nb_cb_destroy_args *args);
struct routemap_hook_context *
routemap_hook_context_insert(struct route_map_index *rmi);
void routemap_hook_context_free(struct routemap_hook_context *rhc);
extern const struct frr_yang_module_info frr_route_map_info;
/* routemap_cli.c */
extern int route_map_instance_cmp(const struct lyd_node *dnode1,
const struct lyd_node *dnode2);
extern void route_map_instance_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_instance_show_end(struct vty *vty,
const struct lyd_node *dnode);
extern void route_map_condition_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_action_show(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_exit_policy_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_call_show(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_description_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_optimization_disabled_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern void route_map_cli_init(void);
#ifdef __cplusplus
}
#endif
2002-12-13 21:15:29 +01:00
#endif /* _ZEBRA_ROUTEMAP_H */