mirror of https://github.com/FRRouting/frr.git
Merge pull request #11899 from opensourcerouting/feature/route_validation_extended_community
bgpd: Implement Origin Validation State via extended communities
This commit is contained in:
commit
7fa5e07b1c
|
@ -394,6 +394,44 @@ enum ecommunity_token {
|
|||
ecommunity_token_val6,
|
||||
};
|
||||
|
||||
static const char *ecommunity_origin_validation_state2str(
|
||||
enum ecommunity_origin_validation_states state)
|
||||
{
|
||||
switch (state) {
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID:
|
||||
return "valid";
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND:
|
||||
return "not-found";
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID:
|
||||
return "invalid";
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED:
|
||||
return "not-used";
|
||||
}
|
||||
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
static void ecommunity_origin_validation_state_str(char *buf, size_t bufsz,
|
||||
uint8_t *ptr)
|
||||
{
|
||||
/* Origin Validation State is encoded in the last octet
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | 0x43 | 0x00 | Reserved |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reserved |validationstate|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
uint8_t state = *(ptr + ECOMMUNITY_SIZE - 3);
|
||||
|
||||
snprintf(buf, bufsz, "OVS:%s",
|
||||
ecommunity_origin_validation_state2str(state));
|
||||
|
||||
(void)ptr; /* consume value */
|
||||
}
|
||||
|
||||
static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type,
|
||||
int trans, as_t as,
|
||||
struct in_addr *ip,
|
||||
|
@ -1172,6 +1210,13 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||
ecom->disable_ieee_floating);
|
||||
else
|
||||
unk_ecom = 1;
|
||||
} else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) {
|
||||
sub_type = *pnt++;
|
||||
if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE)
|
||||
ecommunity_origin_validation_state_str(
|
||||
encbuf, sizeof(encbuf), pnt);
|
||||
else
|
||||
unk_ecom = 1;
|
||||
} else {
|
||||
sub_type = *pnt++;
|
||||
unk_ecom = 1;
|
||||
|
@ -1541,6 +1586,31 @@ void bgp_remove_ecomm_from_aggregate_hash(struct bgp_aggregate *aggregate,
|
|||
}
|
||||
}
|
||||
|
||||
struct ecommunity *
|
||||
ecommunity_add_origin_validation_state(enum rpki_states rpki_state,
|
||||
struct ecommunity *old)
|
||||
{
|
||||
struct ecommunity *new = NULL;
|
||||
struct ecommunity ovs_ecomm = {0};
|
||||
struct ecommunity_val ovs_eval;
|
||||
|
||||
encode_origin_validation_state(rpki_state, &ovs_eval);
|
||||
|
||||
if (old) {
|
||||
new = ecommunity_dup(old);
|
||||
ecommunity_add_val(new, &ovs_eval, true, true);
|
||||
if (!old->refcnt)
|
||||
ecommunity_free(&old);
|
||||
} else {
|
||||
ovs_ecomm.size = 1;
|
||||
ovs_ecomm.unit_size = ECOMMUNITY_SIZE;
|
||||
ovs_ecomm.val = (uint8_t *)&ovs_eval.val;
|
||||
new = ecommunity_dup(&ovs_ecomm);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
* return the BGP link bandwidth extended community, if present;
|
||||
* the actual bandwidth is returned via param
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define _QUAGGA_BGP_ECOMMUNITY_H
|
||||
|
||||
#include "bgpd/bgp_route.h"
|
||||
#include "bgpd/bgp_rpki.h"
|
||||
#include "bgpd/bgpd.h"
|
||||
|
||||
/* Refer to rfc7153 for the IANA registry definitions. These are
|
||||
|
@ -51,6 +52,7 @@
|
|||
/* Note: This really depends on the high-order octet. This means that
|
||||
* multiple definitions for the same value are possible.
|
||||
*/
|
||||
#define ECOMMUNITY_ORIGIN_VALIDATION_STATE 0x00
|
||||
#define ECOMMUNITY_ROUTE_TARGET 0x02
|
||||
#define ECOMMUNITY_SITE_ORIGIN 0x03
|
||||
#define ECOMMUNITY_LINK_BANDWIDTH 0x04
|
||||
|
@ -100,6 +102,14 @@
|
|||
#define ECOMMUNITY_SIZE 8
|
||||
#define IPV6_ECOMMUNITY_SIZE 20
|
||||
|
||||
/* Extended Community Origin Validation State */
|
||||
enum ecommunity_origin_validation_states {
|
||||
ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID,
|
||||
ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND,
|
||||
ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID,
|
||||
ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED
|
||||
};
|
||||
|
||||
/* Extended Communities type flag. */
|
||||
#define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
|
||||
|
||||
|
@ -236,6 +246,32 @@ static inline void encode_lb_extcomm(as_t as, uint32_t bw, bool non_trans,
|
|||
eval->val[7] = bandwidth & 0xff;
|
||||
}
|
||||
|
||||
static inline void encode_origin_validation_state(enum rpki_states state,
|
||||
struct ecommunity_val *eval)
|
||||
{
|
||||
enum ecommunity_origin_validation_states ovs_state =
|
||||
ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED;
|
||||
|
||||
switch (state) {
|
||||
case RPKI_VALID:
|
||||
ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID;
|
||||
break;
|
||||
case RPKI_NOTFOUND:
|
||||
ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND;
|
||||
break;
|
||||
case RPKI_INVALID:
|
||||
ovs_state = ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID;
|
||||
break;
|
||||
case RPKI_NOT_BEING_USED:
|
||||
break;
|
||||
}
|
||||
|
||||
memset(eval, 0, sizeof(*eval));
|
||||
eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS;
|
||||
eval->val[1] = ECOMMUNITY_ORIGIN_VALIDATION_STATE;
|
||||
eval->val[7] = ovs_state;
|
||||
}
|
||||
|
||||
extern void ecommunity_init(void);
|
||||
extern void ecommunity_finish(void);
|
||||
extern void ecommunity_free(struct ecommunity **);
|
||||
|
@ -314,4 +350,7 @@ static inline void ecommunity_strip_rts(struct ecommunity *ecom)
|
|||
ecommunity_strip(ecom, ECOMMUNITY_ENCODE_IP, subtype);
|
||||
ecommunity_strip(ecom, ECOMMUNITY_ENCODE_AS4, subtype);
|
||||
}
|
||||
extern struct ecommunity *
|
||||
ecommunity_add_origin_validation_state(enum rpki_states rpki_state,
|
||||
struct ecommunity *ecom);
|
||||
#endif /* _QUAGGA_BGP_ECOMMUNITY_H */
|
||||
|
|
|
@ -2486,6 +2486,21 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||
}
|
||||
}
|
||||
|
||||
/* If this is an iBGP, send Origin Validation State (OVS)
|
||||
* extended community (rfc8097).
|
||||
*/
|
||||
if (peer->sort == BGP_PEER_IBGP) {
|
||||
enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
|
||||
|
||||
rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
|
||||
|
||||
if (rpki_state != RPKI_NOT_BEING_USED)
|
||||
bgp_attr_set_ecommunity(
|
||||
attr, ecommunity_add_origin_validation_state(
|
||||
rpki_state,
|
||||
bgp_attr_get_ecommunity(attr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* When the next hop is set to ourselves, if all multipaths have
|
||||
* link-bandwidth announce the cumulative bandwidth as that makes
|
||||
|
|
|
@ -3791,6 +3791,73 @@ static const struct route_map_rule_cmd route_set_originator_id_cmd = {
|
|||
route_set_originator_id_free,
|
||||
};
|
||||
|
||||
static enum route_map_cmd_result_t
|
||||
route_match_rpki_extcommunity(void *rule, const struct prefix *prefix,
|
||||
void *object)
|
||||
{
|
||||
struct bgp_path_info *path;
|
||||
struct ecommunity *ecomm;
|
||||
struct ecommunity_val *ecomm_val;
|
||||
enum rpki_states *rpki_status = rule;
|
||||
enum rpki_states ecomm_rpki_status = RPKI_NOT_BEING_USED;
|
||||
|
||||
path = object;
|
||||
|
||||
ecomm = bgp_attr_get_ecommunity(path->attr);
|
||||
if (!ecomm)
|
||||
return RMAP_NOMATCH;
|
||||
|
||||
ecomm_val = ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS,
|
||||
ECOMMUNITY_ORIGIN_VALIDATION_STATE);
|
||||
if (!ecomm_val)
|
||||
return RMAP_NOMATCH;
|
||||
|
||||
/* The Origin Validation State is encoded in the last octet of
|
||||
* the extended community.
|
||||
*/
|
||||
switch (ecomm_val->val[7]) {
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID:
|
||||
ecomm_rpki_status = RPKI_VALID;
|
||||
break;
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND:
|
||||
ecomm_rpki_status = RPKI_NOTFOUND;
|
||||
break;
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID:
|
||||
ecomm_rpki_status = RPKI_INVALID;
|
||||
break;
|
||||
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ecomm_rpki_status == *rpki_status)
|
||||
return RMAP_MATCH;
|
||||
|
||||
return RMAP_NOMATCH;
|
||||
}
|
||||
|
||||
static void *route_match_extcommunity_compile(const char *arg)
|
||||
{
|
||||
int *rpki_status;
|
||||
|
||||
rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int));
|
||||
|
||||
if (strcmp(arg, "valid") == 0)
|
||||
*rpki_status = RPKI_VALID;
|
||||
else if (strcmp(arg, "invalid") == 0)
|
||||
*rpki_status = RPKI_INVALID;
|
||||
else
|
||||
*rpki_status = RPKI_NOTFOUND;
|
||||
|
||||
return rpki_status;
|
||||
}
|
||||
|
||||
static const struct route_map_rule_cmd route_match_rpki_extcommunity_cmd = {
|
||||
"rpki-extcommunity",
|
||||
route_match_rpki_extcommunity,
|
||||
route_match_extcommunity_compile,
|
||||
route_value_free
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the workhorse routine for processing in/out routemap
|
||||
* modifications.
|
||||
|
@ -6792,6 +6859,34 @@ DEFUN_YANG (no_set_originator_id,
|
|||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFPY_YANG (match_rpki_extcommunity,
|
||||
match_rpki_extcommunity_cmd,
|
||||
"[no$no] match rpki-extcommunity <valid|invalid|notfound>",
|
||||
NO_STR
|
||||
MATCH_STR
|
||||
"BGP RPKI (Origin Validation State) extended community attribute\n"
|
||||
"Valid prefix\n"
|
||||
"Invalid prefix\n"
|
||||
"Prefix not found\n")
|
||||
{
|
||||
const char *xpath =
|
||||
"./match-condition[condition='frr-bgp-route-map:rpki-extcommunity']";
|
||||
char xpath_value[XPATH_MAXLEN];
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
|
||||
if (!no) {
|
||||
snprintf(
|
||||
xpath_value, sizeof(xpath_value),
|
||||
"%s/rmap-match-condition/frr-bgp-route-map:rpki-extcommunity",
|
||||
xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
|
||||
argv[2]->arg);
|
||||
}
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
/* Initialization of route map. */
|
||||
void bgp_route_map_init(void)
|
||||
{
|
||||
|
@ -7030,6 +7125,7 @@ void bgp_route_map_init(void)
|
|||
route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd);
|
||||
route_map_install_set(&route_set_ipv6_nexthop_local_cmd);
|
||||
route_map_install_set(&route_set_ipv6_nexthop_peer_cmd);
|
||||
route_map_install_match(&route_match_rpki_extcommunity_cmd);
|
||||
|
||||
install_element(RMAP_NODE, &match_ipv6_next_hop_cmd);
|
||||
install_element(RMAP_NODE, &match_ipv6_next_hop_address_cmd);
|
||||
|
@ -7047,6 +7143,7 @@ void bgp_route_map_init(void)
|
|||
install_element(RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
|
||||
install_element(RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
|
||||
install_element(RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
|
||||
install_element(RMAP_NODE, &match_rpki_extcommunity_cmd);
|
||||
#ifdef HAVE_SCRIPTING
|
||||
install_element(RMAP_NODE, &match_script_cmd);
|
||||
#endif
|
||||
|
|
|
@ -66,6 +66,13 @@ const struct frr_yang_module_info frr_bgp_route_map_info = {
|
|||
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_rpki_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:rpki-extcommunity",
|
||||
.cbs = {
|
||||
.modify = lib_route_map_entry_match_condition_rmap_match_condition_rpki_extcommunity_modify,
|
||||
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_rpki_extcommunity_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:probability",
|
||||
.cbs = {
|
||||
|
|
|
@ -39,6 +39,10 @@ int lib_route_map_entry_match_condition_rmap_match_condition_origin_modify(struc
|
|||
int lib_route_map_entry_match_condition_rmap_match_condition_origin_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_rpki_modify(struct nb_cb_modify_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_rpki_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_rpki_extcommunity_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_rpki_extcommunity_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_probability_modify(struct nb_cb_modify_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_probability_destroy(struct nb_cb_destroy_args *args);
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_modify(struct nb_cb_modify_args *args);
|
||||
|
|
|
@ -380,6 +380,60 @@ lib_route_map_entry_match_condition_rmap_match_condition_rpki_destroy(
|
|||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath:
|
||||
* /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:rpki-extcommunity
|
||||
*/
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_rpki_extcommunity_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct routemap_hook_context *rhc;
|
||||
const char *rpki;
|
||||
enum rmap_compile_rets ret;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
/* Add configuration. */
|
||||
rhc = nb_running_get_entry(args->dnode, NULL, true);
|
||||
rpki = yang_dnode_get_string(args->dnode, NULL);
|
||||
|
||||
/* Set destroy information. */
|
||||
rhc->rhc_mhook = bgp_route_match_delete;
|
||||
rhc->rhc_rule = "rpki-extcommunity";
|
||||
rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
|
||||
|
||||
ret = bgp_route_match_add(rhc->rhc_rmi, "rpki-extcommunity",
|
||||
rpki, RMAP_EVENT_MATCH_ADDED,
|
||||
args->errmsg, args->errmsg_len);
|
||||
|
||||
if (ret != RMAP_COMPILE_SUCCESS) {
|
||||
rhc->rhc_mhook = NULL;
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
}
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int lib_route_map_entry_match_condition_rmap_match_condition_rpki_extcommunity_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
return lib_route_map_entry_match_destroy(args);
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:probability
|
||||
*/
|
||||
|
|
|
@ -341,6 +341,8 @@ BGP
|
|||
:t:`The Generalized TTL Security Mechanism (GTSM). V. Gill, J. Heasley, D. Meyer, P. Savola, C. Pingnataro. October 2007.`
|
||||
- :rfc:`5575`
|
||||
:t:`Dissemination of Flow Specification Rules. P. Marques, N. Sheth, R. Raszuk, B. Greene, J. Mauch, D. McPherson. August 2009`
|
||||
- :rfc:`5668`
|
||||
:t:`4-Octet AS Specific BGP Extended Community. Y. Rekhter, S. Sangli, D. Tappan October 2009`
|
||||
- :rfc:`6286`
|
||||
:t:`Autonomous-System-Wide Unique BGP Identifier for BGP-4. E. Chen, J. Yuan, June 2011.`
|
||||
- :rfc:`6608`
|
||||
|
@ -367,6 +369,8 @@ BGP
|
|||
:t:`BLACKHOLE Community. T. King, C. Dietzel, J. Snijders, G. Doering, G. Hankins. Oct 2016.`
|
||||
- :rfc:`8092`
|
||||
:t:`BGP Large Communities Attribute. J. Heitz, Ed., J. Snijders, Ed, K. Patel, I. Bagdonas, N. Hilliard. February 2017`
|
||||
- :rfc:`8097`
|
||||
:t:`BGP Prefix Origin Validation State Extended Community. P. Mohapatra, K. Patel, J. Scudder, D. Ward, R. Bush. March 2017`
|
||||
- :rfc:`8195`
|
||||
:t:`Use of BGP Large Communities. J. Snijders, J. Heasley, M. Schmidt, June 2017`
|
||||
- :rfc:`8203`
|
||||
|
|
|
@ -178,6 +178,12 @@ Validating BGP Updates
|
|||
match rpki valid
|
||||
set local-preference 500
|
||||
|
||||
.. clicmd:: match rpki-extcommunity notfound|invalid|valid
|
||||
|
||||
Create a clause for a route map to match prefixes with the specified RPKI
|
||||
state, that is derived from the Origin Validation State extended community
|
||||
attribute (OVS). OVS extended community is non-transitive and is exchanged
|
||||
only between iBGP peers.
|
||||
|
||||
.. _debugging:
|
||||
|
||||
|
|
|
@ -280,6 +280,8 @@ DECLARE_QOBJ_TYPE(route_map);
|
|||
#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_RPKI_EXTCOMMUNITY(C) \
|
||||
(strmatch(C, "frr-bgp-route-map:rpki-extcommunity"))
|
||||
#define IS_MATCH_PROBABILITY(C) \
|
||||
(strmatch(C, "frr-bgp-route-map:probability"))
|
||||
#define IS_MATCH_SRC_VRF(C) \
|
||||
|
|
|
@ -650,6 +650,11 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode,
|
|||
yang_dnode_get_string(
|
||||
dnode,
|
||||
"./rmap-match-condition/frr-bgp-route-map:rpki"));
|
||||
} else if (IS_MATCH_RPKI_EXTCOMMUNITY(condition)) {
|
||||
vty_out(vty, " match rpki-extcommunity %s\n",
|
||||
yang_dnode_get_string(
|
||||
dnode,
|
||||
"./rmap-match-condition/frr-bgp-route-map:rpki-extcommunity"));
|
||||
} else if (IS_MATCH_PROBABILITY(condition)) {
|
||||
vty_out(vty, " match probability %s\n",
|
||||
yang_dnode_get_string(
|
||||
|
|
|
@ -66,6 +66,12 @@ module frr-bgp-route-map {
|
|||
"Control rpki specific settings";
|
||||
}
|
||||
|
||||
identity rpki-extcommunity {
|
||||
base frr-route-map:rmap-match-type;
|
||||
description
|
||||
"Control rpki specific settings derived from extended community";
|
||||
}
|
||||
|
||||
identity probability {
|
||||
base frr-route-map:rmap-match-type;
|
||||
description
|
||||
|
@ -436,6 +442,29 @@ module frr-bgp-route-map {
|
|||
}
|
||||
}
|
||||
|
||||
case rpki-extcommunity {
|
||||
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:rpki-extcommunity')";
|
||||
leaf rpki-extcommunity {
|
||||
type enumeration {
|
||||
enum "valid" {
|
||||
value 0;
|
||||
description
|
||||
"Valid prefix";
|
||||
}
|
||||
enum "notfound" {
|
||||
value 1;
|
||||
description
|
||||
"Prefix not found";
|
||||
}
|
||||
enum "invalid" {
|
||||
value 2;
|
||||
description
|
||||
"Invalid prefix";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case probability {
|
||||
when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:probability')";
|
||||
leaf probability {
|
||||
|
|
Loading…
Reference in New Issue