mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 17:48:35 +00:00
bgpd: Add route-map match alias
command
Will be handy to filter BGP prefixes by using BGP community alias instead of numerical community values. Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
This commit is contained in:
parent
2e69d1e4f3
commit
2690f18cc8
@ -52,6 +52,7 @@
|
|||||||
#include "bgpd/bgp_zebra.h"
|
#include "bgpd/bgp_zebra.h"
|
||||||
#include "bgpd/bgp_regex.h"
|
#include "bgpd/bgp_regex.h"
|
||||||
#include "bgpd/bgp_community.h"
|
#include "bgpd/bgp_community.h"
|
||||||
|
#include "bgpd/bgp_community_alias.h"
|
||||||
#include "bgpd/bgp_clist.h"
|
#include "bgpd/bgp_clist.h"
|
||||||
#include "bgpd/bgp_filter.h"
|
#include "bgpd/bgp_filter.h"
|
||||||
#include "bgpd/bgp_mplsvpn.h"
|
#include "bgpd/bgp_mplsvpn.h"
|
||||||
@ -1179,6 +1180,55 @@ static const struct route_map_rule_cmd route_match_vrl_source_vrf_cmd = {
|
|||||||
route_match_vrl_source_vrf_free
|
route_match_vrl_source_vrf_free
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* `match alias` */
|
||||||
|
static enum route_map_cmd_result_t
|
||||||
|
route_match_alias(void *rule, const struct prefix *prefix, void *object)
|
||||||
|
{
|
||||||
|
char *alias = rule;
|
||||||
|
struct bgp_path_info *path = object;
|
||||||
|
char **communities;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
if (path->attr->community) {
|
||||||
|
frrstr_split(path->attr->community->str, " ", &communities,
|
||||||
|
&num);
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
const char *com2alias =
|
||||||
|
bgp_community2alias(communities[i]);
|
||||||
|
if (strncmp(alias, com2alias, strlen(com2alias)) == 0)
|
||||||
|
return RMAP_MATCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path->attr->lcommunity) {
|
||||||
|
frrstr_split(path->attr->lcommunity->str, " ", &communities,
|
||||||
|
&num);
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
const char *com2alias =
|
||||||
|
bgp_community2alias(communities[i]);
|
||||||
|
if (strncmp(alias, com2alias, strlen(com2alias)) == 0)
|
||||||
|
return RMAP_MATCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *route_match_alias_compile(const char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void route_match_alias_free(void *rule)
|
||||||
|
{
|
||||||
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct route_map_rule_cmd route_match_alias_cmd = {
|
||||||
|
"alias", route_match_alias, route_match_alias_compile,
|
||||||
|
route_match_alias_free};
|
||||||
|
|
||||||
/* `match local-preference LOCAL-PREF' */
|
/* `match local-preference LOCAL-PREF' */
|
||||||
|
|
||||||
/* Match function return 1 if match is success else return zero. */
|
/* Match function return 1 if match is success else return zero. */
|
||||||
@ -4597,6 +4647,58 @@ DEFUN_YANG (no_match_local_pref,
|
|||||||
return nb_cli_apply_changes(vty, NULL);
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN_YANG(match_alias, match_alias_cmd, "match alias ALIAS_NAME",
|
||||||
|
MATCH_STR
|
||||||
|
"Match BGP community alias name\n"
|
||||||
|
"BGP community alias name\n")
|
||||||
|
{
|
||||||
|
const char *alias = argv[2]->arg;
|
||||||
|
struct community_alias ca1;
|
||||||
|
struct community_alias *lookup_alias;
|
||||||
|
|
||||||
|
const char *xpath =
|
||||||
|
"./match-condition[condition='frr-bgp-route-map:match-alias']";
|
||||||
|
char xpath_value[XPATH_MAXLEN];
|
||||||
|
|
||||||
|
memset(&ca1, 0, sizeof(ca1));
|
||||||
|
strlcpy(ca1.alias, alias, sizeof(ca1.alias));
|
||||||
|
lookup_alias = bgp_ca_alias_lookup(&ca1);
|
||||||
|
if (!lookup_alias) {
|
||||||
|
vty_out(vty, "%% BGP alias name '%s' does not exist\n", alias);
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||||
|
snprintf(xpath_value, sizeof(xpath_value),
|
||||||
|
"%s/rmap-match-condition/frr-bgp-route-map:alias", xpath);
|
||||||
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, alias);
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFUN_YANG(no_match_alias, no_match_alias_cmd, "no match alias [ALIAS_NAME]",
|
||||||
|
NO_STR MATCH_STR
|
||||||
|
"Match BGP community alias name\n"
|
||||||
|
"BGP community alias name\n")
|
||||||
|
{
|
||||||
|
int idx_alias = 3;
|
||||||
|
const char *xpath =
|
||||||
|
"./match-condition[condition='frr-bgp-route-map:match-alias']";
|
||||||
|
char xpath_value[XPATH_MAXLEN];
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||||
|
|
||||||
|
if (argc <= idx_alias)
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
|
||||||
|
snprintf(xpath_value, sizeof(xpath_value),
|
||||||
|
"%s/rmap-match-condition/frr-bgp-route-map:alias", xpath);
|
||||||
|
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
|
||||||
|
argv[idx_alias]->arg);
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
DEFPY_YANG (match_community,
|
DEFPY_YANG (match_community,
|
||||||
match_community_cmd,
|
match_community_cmd,
|
||||||
@ -6286,6 +6388,7 @@ void bgp_route_map_init(void)
|
|||||||
route_map_no_set_tag_hook(generic_set_delete);
|
route_map_no_set_tag_hook(generic_set_delete);
|
||||||
|
|
||||||
route_map_install_match(&route_match_peer_cmd);
|
route_map_install_match(&route_match_peer_cmd);
|
||||||
|
route_map_install_match(&route_match_alias_cmd);
|
||||||
route_map_install_match(&route_match_local_pref_cmd);
|
route_map_install_match(&route_match_local_pref_cmd);
|
||||||
#ifdef HAVE_SCRIPTING
|
#ifdef HAVE_SCRIPTING
|
||||||
route_map_install_match(&route_match_script_cmd);
|
route_map_install_match(&route_match_script_cmd);
|
||||||
@ -6370,6 +6473,8 @@ void bgp_route_map_init(void)
|
|||||||
install_element(RMAP_NODE, &no_match_aspath_cmd);
|
install_element(RMAP_NODE, &no_match_aspath_cmd);
|
||||||
install_element(RMAP_NODE, &match_local_pref_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_cmd);
|
||||||
|
install_element(RMAP_NODE, &match_alias_cmd);
|
||||||
|
install_element(RMAP_NODE, &no_match_alias_cmd);
|
||||||
install_element(RMAP_NODE, &match_community_cmd);
|
install_element(RMAP_NODE, &match_community_cmd);
|
||||||
install_element(RMAP_NODE, &no_match_community_cmd);
|
install_element(RMAP_NODE, &no_match_community_cmd);
|
||||||
install_element(RMAP_NODE, &match_lcommunity_cmd);
|
install_element(RMAP_NODE, &match_lcommunity_cmd);
|
||||||
|
@ -38,6 +38,13 @@ const struct frr_yang_module_info frr_bgp_route_map_info = {
|
|||||||
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy,
|
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:alias",
|
||||||
|
.cbs = {
|
||||||
|
.modify = lib_route_map_entry_match_condition_rmap_match_condition_alias_modify,
|
||||||
|
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_alias_destroy,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:script",
|
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:script",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
|
@ -29,6 +29,10 @@ extern const struct frr_yang_module_info frr_bgp_route_map_info;
|
|||||||
/* prototypes */
|
/* prototypes */
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_local_preference_modify(struct nb_cb_modify_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_local_preference_modify(struct nb_cb_modify_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy(struct nb_cb_destroy_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy(struct nb_cb_destroy_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_alias_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_alias_destroy(
|
||||||
|
struct nb_cb_destroy_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_script_modify(struct nb_cb_modify_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_script_modify(struct nb_cb_modify_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_script_destroy(struct nb_cb_destroy_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_script_destroy(struct nb_cb_destroy_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_origin_modify(struct nb_cb_modify_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_origin_modify(struct nb_cb_modify_args *args);
|
||||||
|
@ -159,6 +159,62 @@ lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destro
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:alias
|
||||||
|
*/
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_alias_modify(
|
||||||
|
struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct routemap_hook_context *rhc;
|
||||||
|
const char *alias;
|
||||||
|
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);
|
||||||
|
alias = yang_dnode_get_string(args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Set destroy information. */
|
||||||
|
rhc->rhc_mhook = bgp_route_match_delete;
|
||||||
|
rhc->rhc_rule = "alias";
|
||||||
|
rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
|
||||||
|
|
||||||
|
ret = bgp_route_match_add(rhc->rhc_rmi, "alias", alias,
|
||||||
|
RMAP_EVENT_MATCH_ADDED, args->errmsg,
|
||||||
|
args->errmsg_len);
|
||||||
|
|
||||||
|
if (ret != RMAP_COMPILE_SUCCESS) {
|
||||||
|
rhc->rhc_mhook = NULL;
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_alias_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:script
|
* XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:script
|
||||||
*/
|
*/
|
||||||
|
@ -270,6 +270,7 @@ DECLARE_QOBJ_TYPE(route_map);
|
|||||||
/* BGP route-map match conditions */
|
/* BGP route-map match conditions */
|
||||||
#define IS_MATCH_LOCAL_PREF(C) \
|
#define IS_MATCH_LOCAL_PREF(C) \
|
||||||
(strmatch(C, "frr-bgp-route-map:match-local-preference"))
|
(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_ORIGIN(C) \
|
#define IS_MATCH_ORIGIN(C) \
|
||||||
(strmatch(C, "frr-bgp-route-map:match-origin"))
|
(strmatch(C, "frr-bgp-route-map:match-origin"))
|
||||||
#define IS_MATCH_RPKI(C) (strmatch(C, "frr-bgp-route-map:rpki"))
|
#define IS_MATCH_RPKI(C) (strmatch(C, "frr-bgp-route-map:rpki"))
|
||||||
|
@ -634,6 +634,11 @@ void route_map_condition_show(struct vty *vty, struct lyd_node *dnode,
|
|||||||
yang_dnode_get_string(
|
yang_dnode_get_string(
|
||||||
dnode,
|
dnode,
|
||||||
"./rmap-match-condition/frr-bgp-route-map:local-preference"));
|
"./rmap-match-condition/frr-bgp-route-map:local-preference"));
|
||||||
|
} else if (IS_MATCH_ALIAS(condition)) {
|
||||||
|
vty_out(vty, " match alias %s\n",
|
||||||
|
yang_dnode_get_string(
|
||||||
|
dnode,
|
||||||
|
"./rmap-match-condition/frr-bgp-route-map:alias"));
|
||||||
} else if (IS_MATCH_ORIGIN(condition)) {
|
} else if (IS_MATCH_ORIGIN(condition)) {
|
||||||
vty_out(vty, " match origin %s\n",
|
vty_out(vty, " match origin %s\n",
|
||||||
yang_dnode_get_string(
|
yang_dnode_get_string(
|
||||||
|
@ -36,6 +36,12 @@ module frr-bgp-route-map {
|
|||||||
"Initial revision";
|
"Initial revision";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
identity match-alias {
|
||||||
|
base frr-route-map:rmap-match-type;
|
||||||
|
description
|
||||||
|
"Match BGP community alias name";
|
||||||
|
}
|
||||||
|
|
||||||
identity match-local-preference {
|
identity match-local-preference {
|
||||||
base frr-route-map:rmap-match-type;
|
base frr-route-map:rmap-match-type;
|
||||||
description
|
description
|
||||||
@ -352,6 +358,13 @@ module frr-bgp-route-map {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case alias {
|
||||||
|
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:match-alias')";
|
||||||
|
leaf alias {
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case script {
|
case script {
|
||||||
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:match-script')";
|
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:match-script')";
|
||||||
leaf script {
|
leaf script {
|
||||||
|
Loading…
Reference in New Issue
Block a user