mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 18:37:06 +00:00
Merge pull request #16946 from opensourcerouting/fix/match_src-peer
bgpd: Implement match src-peer ... command
This commit is contained in:
commit
80dc863d92
@ -30,8 +30,8 @@ bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table,
|
|||||||
dummy_attr = *pi->attr;
|
dummy_attr = *pi->attr;
|
||||||
|
|
||||||
/* Fill temp path_info */
|
/* Fill temp path_info */
|
||||||
prep_for_rmap_apply(&path, &path_extra, dest, pi,
|
prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, NULL,
|
||||||
pi->peer, &dummy_attr);
|
&dummy_attr);
|
||||||
|
|
||||||
RESET_FLAG(dummy_attr.rmap_change_flags);
|
RESET_FLAG(dummy_attr.rmap_change_flags);
|
||||||
|
|
||||||
@ -99,8 +99,8 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
|
|||||||
advmap_attr = *pi->attr;
|
advmap_attr = *pi->attr;
|
||||||
|
|
||||||
/* Fill temp path_info */
|
/* Fill temp path_info */
|
||||||
prep_for_rmap_apply(&path, &path_extra, dest, pi,
|
prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, NULL,
|
||||||
pi->peer, &advmap_attr);
|
&advmap_attr);
|
||||||
|
|
||||||
RESET_FLAG(advmap_attr.rmap_change_flags);
|
RESET_FLAG(advmap_attr.rmap_change_flags);
|
||||||
|
|
||||||
|
@ -5392,9 +5392,8 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
|
|||||||
tmp_attr = *pi->attr;
|
tmp_attr = *pi->attr;
|
||||||
|
|
||||||
/* Fill temp path_info */
|
/* Fill temp path_info */
|
||||||
prep_for_rmap_apply(&tmp_pi, &tmp_pie,
|
prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, pi->peer,
|
||||||
dest, pi, pi->peer,
|
NULL, &tmp_attr);
|
||||||
&tmp_attr);
|
|
||||||
|
|
||||||
RESET_FLAG(tmp_attr.rmap_change_flags);
|
RESET_FLAG(tmp_attr.rmap_change_flags);
|
||||||
|
|
||||||
|
@ -2512,8 +2512,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||||||
struct attr dummy_attr = *attr;
|
struct attr dummy_attr = *attr;
|
||||||
|
|
||||||
/* Fill temp path_info */
|
/* Fill temp path_info */
|
||||||
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
|
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, NULL,
|
||||||
pi, peer, &dummy_attr);
|
&dummy_attr);
|
||||||
|
|
||||||
struct route_map *amap =
|
struct route_map *amap =
|
||||||
route_map_lookup_by_name(filter->advmap.aname);
|
route_map_lookup_by_name(filter->advmap.aname);
|
||||||
@ -2537,9 +2537,13 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||||||
struct bgp_path_info_extra dummy_rmap_path_extra = {0};
|
struct bgp_path_info_extra dummy_rmap_path_extra = {0};
|
||||||
struct attr dummy_attr = {0};
|
struct attr dummy_attr = {0};
|
||||||
|
|
||||||
/* Fill temp path_info */
|
/* Fill temp path_info.
|
||||||
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
|
* Inject the peer structure of the source peer (from).
|
||||||
pi, peer, attr);
|
* This is useful for e.g. `match peer ...` in outgoing
|
||||||
|
* direction.
|
||||||
|
*/
|
||||||
|
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, from, attr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The route reflector is not allowed to modify the attributes
|
* The route reflector is not allowed to modify the attributes
|
||||||
* of the reflected IBGP routes unless explicitly allowed.
|
* of the reflected IBGP routes unless explicitly allowed.
|
||||||
@ -3426,9 +3430,8 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
|
|||||||
dummy_attr = *new_select->attr;
|
dummy_attr = *new_select->attr;
|
||||||
|
|
||||||
/* Fill temp path_info */
|
/* Fill temp path_info */
|
||||||
prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
|
prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest, new_select,
|
||||||
new_select, new_select->peer,
|
new_select->peer, NULL, &dummy_attr);
|
||||||
&dummy_attr);
|
|
||||||
|
|
||||||
RESET_FLAG(dummy_attr.rmap_change_flags);
|
RESET_FLAG(dummy_attr.rmap_change_flags);
|
||||||
|
|
||||||
@ -11784,8 +11787,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa
|
|||||||
|
|
||||||
dummy_attr = *pi->attr;
|
dummy_attr = *pi->attr;
|
||||||
|
|
||||||
prep_for_rmap_apply(&path, &extra, dest, pi,
|
prep_for_rmap_apply(&path, &extra, dest, pi, pi->peer, NULL,
|
||||||
pi->peer, &dummy_attr);
|
&dummy_attr);
|
||||||
|
|
||||||
ret = route_map_apply(rmap, dest_p, &path);
|
ret = route_map_apply(rmap, dest_p, &path);
|
||||||
bgp_attr_flush(&dummy_attr);
|
bgp_attr_flush(&dummy_attr);
|
||||||
|
@ -284,6 +284,9 @@ struct bgp_path_info {
|
|||||||
/* Peer structure. */
|
/* Peer structure. */
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
|
|
||||||
|
/* From peer structure */
|
||||||
|
struct peer *from;
|
||||||
|
|
||||||
/* Attribute structure. */
|
/* Attribute structure. */
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
@ -619,13 +622,13 @@ static inline bool is_pi_family_matching(struct bgp_path_info *pi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi,
|
static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi,
|
||||||
struct bgp_path_info_extra *dst_pie,
|
struct bgp_path_info_extra *dst_pie, struct bgp_dest *dest,
|
||||||
struct bgp_dest *dest,
|
struct bgp_path_info *src_pi, struct peer *peer,
|
||||||
struct bgp_path_info *src_pi,
|
struct peer *from, struct attr *attr)
|
||||||
struct peer *peer, struct attr *attr)
|
|
||||||
{
|
{
|
||||||
memset(dst_pi, 0, sizeof(struct bgp_path_info));
|
memset(dst_pi, 0, sizeof(struct bgp_path_info));
|
||||||
dst_pi->peer = peer;
|
dst_pi->peer = peer;
|
||||||
|
dst_pi->from = from;
|
||||||
dst_pi->attr = attr;
|
dst_pi->attr = attr;
|
||||||
dst_pi->net = dest;
|
dst_pi->net = dest;
|
||||||
dst_pi->flags = src_pi->flags;
|
dst_pi->flags = src_pi->flags;
|
||||||
|
@ -347,6 +347,66 @@ static const struct route_map_rule_cmd route_match_peer_cmd = {
|
|||||||
route_match_peer_free
|
route_match_peer_free
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static enum route_map_cmd_result_t route_match_src_peer(void *rule, const struct prefix *prefix,
|
||||||
|
void *object)
|
||||||
|
{
|
||||||
|
struct bgp_match_peer_compiled *pc;
|
||||||
|
union sockunion *su;
|
||||||
|
struct peer_group *group;
|
||||||
|
struct peer *peer;
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct bgp_path_info *bpi;
|
||||||
|
|
||||||
|
pc = rule;
|
||||||
|
su = &pc->su;
|
||||||
|
bpi = object;
|
||||||
|
peer = bpi->from;
|
||||||
|
|
||||||
|
/* Fallback to destination (current) peer. This is mostly
|
||||||
|
* happens if `match src-peer ...` is used at incoming direction.
|
||||||
|
*/
|
||||||
|
if (!peer)
|
||||||
|
peer = bpi->peer;
|
||||||
|
|
||||||
|
if (!peer)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
|
if (pc->interface) {
|
||||||
|
if (!peer->conf_if && !peer->group)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
|
if (peer->conf_if && strcmp(peer->conf_if, pc->interface) == 0)
|
||||||
|
return RMAP_MATCH;
|
||||||
|
|
||||||
|
if (peer->group && strcmp(peer->group->name, pc->interface) == 0)
|
||||||
|
return RMAP_MATCH;
|
||||||
|
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
||||||
|
if (sockunion_same(su, &peer->connection->su))
|
||||||
|
return RMAP_MATCH;
|
||||||
|
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
group = peer->group;
|
||||||
|
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
|
||||||
|
if (sockunion_same(su, &peer->connection->su))
|
||||||
|
return RMAP_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct route_map_rule_cmd route_match_src_peer_cmd = {
|
||||||
|
"src-peer",
|
||||||
|
route_match_src_peer,
|
||||||
|
route_match_peer_compile,
|
||||||
|
route_match_peer_free
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef HAVE_SCRIPTING
|
#ifdef HAVE_SCRIPTING
|
||||||
|
|
||||||
enum frrlua_rm_status {
|
enum frrlua_rm_status {
|
||||||
@ -5287,6 +5347,52 @@ DEFUN_YANG (no_match_peer,
|
|||||||
return nb_cli_apply_changes(vty, NULL);
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFPY_YANG (match_src_peer,
|
||||||
|
match_src_peer_cmd,
|
||||||
|
"match src-peer <A.B.C.D$addrv4|X:X::X:X$addrv6|WORD$intf>",
|
||||||
|
MATCH_STR
|
||||||
|
"Match source peer address\n"
|
||||||
|
"IP address of peer\n"
|
||||||
|
"IPv6 address of peer\n"
|
||||||
|
"Interface name of peer or peer group name\n")
|
||||||
|
{
|
||||||
|
const char *xpath = "./match-condition[condition='frr-bgp-route-map:src-peer']";
|
||||||
|
char xpath_value[XPATH_MAXLEN];
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||||
|
|
||||||
|
snprintf(xpath_value, sizeof(xpath_value),
|
||||||
|
"%s/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address", xpath);
|
||||||
|
nb_cli_enqueue_change(vty, xpath_value, addrv4_str ? NB_OP_MODIFY : NB_OP_DESTROY,
|
||||||
|
addrv4_str);
|
||||||
|
snprintf(xpath_value, sizeof(xpath_value),
|
||||||
|
"%s/rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address", xpath);
|
||||||
|
nb_cli_enqueue_change(vty, xpath_value, addrv6_str ? NB_OP_MODIFY : NB_OP_DESTROY,
|
||||||
|
addrv6_str);
|
||||||
|
snprintf(xpath_value, sizeof(xpath_value),
|
||||||
|
"%s/rmap-match-condition/frr-bgp-route-map:src-peer-interface", xpath);
|
||||||
|
nb_cli_enqueue_change(vty, xpath_value, intf ? NB_OP_MODIFY : NB_OP_DESTROY, intf);
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN_YANG (no_match_src_peer,
|
||||||
|
no_match_src_peer_cmd,
|
||||||
|
"no match src-peer [<A.B.C.D|X:X::X:X|WORD>]",
|
||||||
|
NO_STR
|
||||||
|
MATCH_STR
|
||||||
|
"Match peer address\n"
|
||||||
|
"IP address of peer\n"
|
||||||
|
"IPv6 address of peer\n"
|
||||||
|
"Interface name of peer\n")
|
||||||
|
{
|
||||||
|
const char *xpath = "./match-condition[condition='frr-bgp-route-map:src-peer']";
|
||||||
|
|
||||||
|
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SCRIPTING
|
#ifdef HAVE_SCRIPTING
|
||||||
DEFUN_YANG (match_script,
|
DEFUN_YANG (match_script,
|
||||||
match_script_cmd,
|
match_script_cmd,
|
||||||
@ -7778,6 +7884,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_src_peer_cmd);
|
||||||
route_map_install_match(&route_match_alias_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
|
||||||
@ -7845,6 +7952,8 @@ void bgp_route_map_init(void)
|
|||||||
|
|
||||||
install_element(RMAP_NODE, &match_peer_cmd);
|
install_element(RMAP_NODE, &match_peer_cmd);
|
||||||
install_element(RMAP_NODE, &match_peer_local_cmd);
|
install_element(RMAP_NODE, &match_peer_local_cmd);
|
||||||
|
install_element(RMAP_NODE, &match_src_peer_cmd);
|
||||||
|
install_element(RMAP_NODE, &no_match_src_peer_cmd);
|
||||||
install_element(RMAP_NODE, &no_match_peer_cmd);
|
install_element(RMAP_NODE, &no_match_peer_cmd);
|
||||||
install_element(RMAP_NODE, &match_ip_route_source_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_cmd);
|
||||||
|
@ -109,6 +109,27 @@ const struct frr_yang_module_info frr_bgp_route_map_info = {
|
|||||||
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy,
|
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address",
|
||||||
|
.cbs = {
|
||||||
|
.modify = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_modify,
|
||||||
|
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_destroy,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-interface",
|
||||||
|
.cbs = {
|
||||||
|
.modify = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_modify,
|
||||||
|
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_destroy,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address",
|
||||||
|
.cbs = {
|
||||||
|
.modify = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_modify,
|
||||||
|
.destroy = lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_destroy,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name",
|
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
|
@ -46,6 +46,18 @@ int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_m
|
|||||||
int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_destroy(struct nb_cb_destroy_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_destroy(struct nb_cb_destroy_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_modify(struct nb_cb_modify_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_modify(struct nb_cb_modify_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy(struct nb_cb_destroy_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy(struct nb_cb_destroy_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_destroy(
|
||||||
|
struct nb_cb_destroy_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_destroy(
|
||||||
|
struct nb_cb_destroy_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_modify(
|
||||||
|
struct nb_cb_modify_args *args);
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_destroy(
|
||||||
|
struct nb_cb_destroy_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_modify(struct nb_cb_modify_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_modify(struct nb_cb_modify_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_destroy(struct nb_cb_destroy_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_destroy(struct nb_cb_destroy_args *args);
|
||||||
int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_extended_modify(struct nb_cb_modify_args *args);
|
int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_extended_modify(struct nb_cb_modify_args *args);
|
||||||
|
@ -808,6 +808,162 @@ lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy(
|
|||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address
|
||||||
|
*/
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv4_address_modify(
|
||||||
|
struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct routemap_hook_context *rhc;
|
||||||
|
const char *peer;
|
||||||
|
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);
|
||||||
|
peer = yang_dnode_get_string(args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Set destroy information. */
|
||||||
|
rhc->rhc_mhook = bgp_route_match_delete;
|
||||||
|
rhc->rhc_rule = "src-peer";
|
||||||
|
rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
|
||||||
|
|
||||||
|
ret = bgp_route_match_add(rhc->rhc_rmi, "src-peer", peer, 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_src_peer_ipv4_address_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:src-peer-interface
|
||||||
|
*/
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_interface_modify(
|
||||||
|
struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct routemap_hook_context *rhc;
|
||||||
|
const char *peer;
|
||||||
|
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);
|
||||||
|
peer = yang_dnode_get_string(args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Set destroy information. */
|
||||||
|
rhc->rhc_mhook = bgp_route_match_delete;
|
||||||
|
rhc->rhc_rule = "src-peer";
|
||||||
|
rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
|
||||||
|
|
||||||
|
ret = bgp_route_match_add(rhc->rhc_rmi, "src-peer", peer, 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_src_peer_interface_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:src-peer-ipv6-address
|
||||||
|
*/
|
||||||
|
int lib_route_map_entry_match_condition_rmap_match_condition_src_peer_ipv6_address_modify(
|
||||||
|
struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct routemap_hook_context *rhc;
|
||||||
|
const char *peer;
|
||||||
|
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);
|
||||||
|
peer = yang_dnode_get_string(args->dnode, NULL);
|
||||||
|
|
||||||
|
/* Set destroy information. */
|
||||||
|
rhc->rhc_mhook = bgp_route_match_delete;
|
||||||
|
rhc->rhc_rule = "src-peer";
|
||||||
|
rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
|
||||||
|
|
||||||
|
ret = bgp_route_match_add(rhc->rhc_rmi, "src-peer", peer, 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_src_peer_ipv6_address_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:list-name
|
* XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name
|
||||||
*/
|
*/
|
||||||
|
@ -190,6 +190,12 @@ Route Map Match Command
|
|||||||
do the exact matching of the communities, while ``any`` - can match any
|
do the exact matching of the communities, while ``any`` - can match any
|
||||||
community specified in COMMUNITY_LIST.
|
community specified in COMMUNITY_LIST.
|
||||||
|
|
||||||
|
.. clicmd:: match src-peer [IPV4_ADDR|IPV6_ADDR|INTERFACE_NAME|PEER_GROUP_NAME]
|
||||||
|
|
||||||
|
This is a BGP specific match command. Matches the source peer if the neighbor
|
||||||
|
was specified in this manner. Useful to announce the routes that was originated
|
||||||
|
by the source peer.
|
||||||
|
|
||||||
.. clicmd:: match peer IPV4_ADDR
|
.. clicmd:: match peer IPV4_ADDR
|
||||||
|
|
||||||
This is a BGP specific match command. Matches the peer ip address
|
This is a BGP specific match command. Matches the peer ip address
|
||||||
|
@ -278,6 +278,7 @@ DECLARE_QOBJ_TYPE(route_map);
|
|||||||
#define IS_MATCH_SRC_VRF(C) \
|
#define IS_MATCH_SRC_VRF(C) \
|
||||||
(strmatch(C, "frr-bgp-route-map:source-vrf"))
|
(strmatch(C, "frr-bgp-route-map:source-vrf"))
|
||||||
#define IS_MATCH_PEER(C) (strmatch(C, "frr-bgp-route-map:peer"))
|
#define IS_MATCH_PEER(C) (strmatch(C, "frr-bgp-route-map:peer"))
|
||||||
|
#define IS_MATCH_SRC_PEER(C) (strmatch(C, "frr-bgp-route-map:src-peer"))
|
||||||
#define IS_MATCH_AS_LIST(C) \
|
#define IS_MATCH_AS_LIST(C) \
|
||||||
(strmatch(C, "frr-bgp-route-map:as-path-list"))
|
(strmatch(C, "frr-bgp-route-map:as-path-list"))
|
||||||
#define IS_MATCH_MAC_LIST(C) \
|
#define IS_MATCH_MAC_LIST(C) \
|
||||||
|
@ -756,6 +756,18 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode,
|
|||||||
acl = "local";
|
acl = "local";
|
||||||
|
|
||||||
vty_out(vty, " match peer %s\n", acl);
|
vty_out(vty, " match peer %s\n", acl);
|
||||||
|
} else if (IS_MATCH_SRC_PEER(condition)) {
|
||||||
|
acl = NULL;
|
||||||
|
ln = yang_dnode_get(dnode,
|
||||||
|
"./rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address");
|
||||||
|
if (!ln)
|
||||||
|
ln = yang_dnode_get(dnode,
|
||||||
|
"./rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address");
|
||||||
|
if (!ln)
|
||||||
|
ln = yang_dnode_get(dnode,
|
||||||
|
"./rmap-match-condition/frr-bgp-route-map:src-peer-interface");
|
||||||
|
acl = yang_dnode_get_string(ln, NULL);
|
||||||
|
vty_out(vty, " match src-peer %s\n", acl);
|
||||||
} else if (IS_MATCH_AS_LIST(condition)) {
|
} else if (IS_MATCH_AS_LIST(condition)) {
|
||||||
vty_out(vty, " match as-path %s\n",
|
vty_out(vty, " match as-path %s\n",
|
||||||
yang_dnode_get_string(
|
yang_dnode_get_string(
|
||||||
|
@ -17,6 +17,7 @@ router bgp 65001
|
|||||||
neighbor 192.168.1.2 route-map all in
|
neighbor 192.168.1.2 route-map all in
|
||||||
neighbor r3 route-map all in
|
neighbor r3 route-map all in
|
||||||
neighbor r4 route-map all in
|
neighbor r4 route-map all in
|
||||||
|
neighbor r4 route-map r4 out
|
||||||
exit-address-family
|
exit-address-family
|
||||||
!
|
!
|
||||||
route-map all permit 5
|
route-map all permit 5
|
||||||
@ -24,7 +25,7 @@ route-map all permit 5
|
|||||||
set metric 1
|
set metric 1
|
||||||
!
|
!
|
||||||
route-map all permit 10
|
route-map all permit 10
|
||||||
match peer 192.168.1.2
|
match src-peer 192.168.1.2
|
||||||
set metric 2
|
set metric 2
|
||||||
!
|
!
|
||||||
route-map all permit 15
|
route-map all permit 15
|
||||||
@ -35,3 +36,6 @@ route-map all permit 20
|
|||||||
match peer r4
|
match peer r4
|
||||||
set metric 4
|
set metric 4
|
||||||
!
|
!
|
||||||
|
route-map r4 permit 10
|
||||||
|
match src-peer r3
|
||||||
|
!
|
||||||
|
@ -82,6 +82,29 @@ def test_bgp_match_peer():
|
|||||||
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||||
assert result is None, "Can't converge"
|
assert result is None, "Can't converge"
|
||||||
|
|
||||||
|
def _bgp_show_advertised_routes():
|
||||||
|
output = json.loads(
|
||||||
|
r1.vtysh_cmd("show bgp ipv4 unicast neighbors r4 advertised-routes json")
|
||||||
|
)
|
||||||
|
expected = {
|
||||||
|
"advertisedRoutes": {
|
||||||
|
"10.0.0.3/32": {
|
||||||
|
"network": "10.0.0.3/32",
|
||||||
|
"nextHop": "192.168.1.3",
|
||||||
|
"path": "65003",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"totalPrefixCounter": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
return topotest.json_cmp(output, expected)
|
||||||
|
|
||||||
|
test_func = functools.partial(
|
||||||
|
_bgp_show_advertised_routes,
|
||||||
|
)
|
||||||
|
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||||
|
assert result is None, "Can't filter by source peer"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
args = ["-s"] + sys.argv[1:]
|
args = ["-s"] + sys.argv[1:]
|
||||||
|
@ -94,6 +94,12 @@ module frr-bgp-route-map {
|
|||||||
"Match peer address";
|
"Match peer address";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
identity src-peer {
|
||||||
|
base frr-route-map:rmap-match-type;
|
||||||
|
description
|
||||||
|
"Match source peer address";
|
||||||
|
}
|
||||||
|
|
||||||
identity mac-address-list {
|
identity mac-address-list {
|
||||||
base frr-route-map:rmap-match-type;
|
base frr-route-map:rmap-match-type;
|
||||||
description
|
description
|
||||||
@ -688,6 +694,37 @@ identity set-extcommunity-color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case src-peer {
|
||||||
|
when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:src-peer')";
|
||||||
|
choice peer {
|
||||||
|
description
|
||||||
|
"Value of the peer";
|
||||||
|
case src-peer-ipv4-address {
|
||||||
|
description
|
||||||
|
"IP address of peer";
|
||||||
|
leaf src-peer-ipv4-address {
|
||||||
|
type inet:ipv4-address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case src-peer-interface {
|
||||||
|
description
|
||||||
|
"Interface name of peer";
|
||||||
|
leaf src-peer-interface {
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case src-peer-ipv6-address {
|
||||||
|
description
|
||||||
|
"IPv6 address of peer";
|
||||||
|
leaf src-peer-ipv6-address {
|
||||||
|
type inet:ipv6-address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case access-list-name {
|
case access-list-name {
|
||||||
when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:mac-address-list') or "
|
when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:mac-address-list') or "
|
||||||
+ "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:as-path-list') or "
|
+ "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:as-path-list') or "
|
||||||
|
Loading…
Reference in New Issue
Block a user