Skip to content

Commit

Permalink
Merge pull request #16946 from opensourcerouting/fix/match_src-peer
Browse files Browse the repository at this point in the history
bgpd: Implement match src-peer ... command
  • Loading branch information
riw777 authored Oct 16, 2024
2 parents 40dce0b + 6e4bee2 commit 80dc863
Show file tree
Hide file tree
Showing 14 changed files with 408 additions and 22 deletions.
8 changes: 4 additions & 4 deletions bgpd/bgp_conditional_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table,
dummy_attr = *pi->attr;

/* Fill temp path_info */
prep_for_rmap_apply(&path, &path_extra, dest, pi,
pi->peer, &dummy_attr);
prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, NULL,
&dummy_attr);

RESET_FLAG(dummy_attr.rmap_change_flags);

Expand Down Expand Up @@ -99,8 +99,8 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
advmap_attr = *pi->attr;

/* Fill temp path_info */
prep_for_rmap_apply(&path, &path_extra, dest, pi,
pi->peer, &advmap_attr);
prep_for_rmap_apply(&path, &path_extra, dest, pi, pi->peer, NULL,
&advmap_attr);

RESET_FLAG(advmap_attr.rmap_change_flags);

Expand Down
5 changes: 2 additions & 3 deletions bgpd/bgp_evpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -5392,9 +5392,8 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
tmp_attr = *pi->attr;

/* Fill temp path_info */
prep_for_rmap_apply(&tmp_pi, &tmp_pie,
dest, pi, pi->peer,
&tmp_attr);
prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi, pi->peer,
NULL, &tmp_attr);

RESET_FLAG(tmp_attr.rmap_change_flags);

Expand Down
23 changes: 13 additions & 10 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2512,8 +2512,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
struct attr dummy_attr = *attr;

/* Fill temp path_info */
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
pi, peer, &dummy_attr);
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest, pi, peer, NULL,
&dummy_attr);

struct route_map *amap =
route_map_lookup_by_name(filter->advmap.aname);
Expand All @@ -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 attr dummy_attr = {0};

/* Fill temp path_info */
prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
pi, peer, attr);
/* Fill temp path_info.
* Inject the peer structure of the source peer (from).
* 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
* of the reflected IBGP routes unless explicitly allowed.
Expand Down Expand Up @@ -3426,9 +3430,8 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
dummy_attr = *new_select->attr;

/* Fill temp path_info */
prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
new_select, new_select->peer,
&dummy_attr);
prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest, new_select,
new_select->peer, NULL, &dummy_attr);

RESET_FLAG(dummy_attr.rmap_change_flags);

Expand Down Expand Up @@ -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;

prep_for_rmap_apply(&path, &extra, dest, pi,
pi->peer, &dummy_attr);
prep_for_rmap_apply(&path, &extra, dest, pi, pi->peer, NULL,
&dummy_attr);

ret = route_map_apply(rmap, dest_p, &path);
bgp_attr_flush(&dummy_attr);
Expand Down
11 changes: 7 additions & 4 deletions bgpd/bgp_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ struct bgp_path_info {
/* Peer structure. */
struct peer *peer;

/* From peer structure */
struct peer *from;

/* Attribute structure. */
struct attr *attr;

Expand Down Expand Up @@ -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,
struct bgp_path_info_extra *dst_pie,
struct bgp_dest *dest,
struct bgp_path_info *src_pi,
struct peer *peer, struct attr *attr)
struct bgp_path_info_extra *dst_pie, struct bgp_dest *dest,
struct bgp_path_info *src_pi, struct peer *peer,
struct peer *from, struct attr *attr)
{
memset(dst_pi, 0, sizeof(struct bgp_path_info));
dst_pi->peer = peer;
dst_pi->from = from;
dst_pi->attr = attr;
dst_pi->net = dest;
dst_pi->flags = src_pi->flags;
Expand Down
109 changes: 109 additions & 0 deletions bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,66 @@ static const struct route_map_rule_cmd route_match_peer_cmd = {
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

enum frrlua_rm_status {
Expand Down Expand Up @@ -5287,6 +5347,52 @@ DEFUN_YANG (no_match_peer,
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
DEFUN_YANG (match_script,
match_script_cmd,
Expand Down Expand Up @@ -7778,6 +7884,7 @@ void bgp_route_map_init(void)
route_map_no_set_tag_hook(generic_set_delete);

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_local_pref_cmd);
#ifdef HAVE_SCRIPTING
Expand Down Expand Up @@ -7845,6 +7952,8 @@ void bgp_route_map_init(void)

install_element(RMAP_NODE, &match_peer_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, &match_ip_route_source_cmd);
install_element(RMAP_NODE, &no_match_ip_route_source_cmd);
Expand Down
21 changes: 21 additions & 0 deletions bgpd/bgp_routemap_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
},
{
.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",
.cbs = {
Expand Down
12 changes: 12 additions & 0 deletions bgpd/bgp_routemap_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_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_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);
Expand Down
Loading

0 comments on commit 80dc863

Please sign in to comment.