Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Add neighbor X send-community extended rpki command #15284

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2670,16 +2670,20 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
* defined as non-transitive in [RFC8097], can be advertised to
* peers in the same OAD.
*/
if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD) {
if ((peer->sort == BGP_PEER_IBGP ||
peer->sub_sort == BGP_PEER_EBGP_OAD) &&
peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI)) {
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)));
bgp_attr_set_ecommunity(attr,
ecommunity_add_origin_validation_state(
rpki_state,
bgp_attr_get_ecommunity(
attr)));
}

/*
Expand Down
21 changes: 10 additions & 11 deletions bgpd/bgp_updgrp.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,16 @@
(PEER_FLAG_LOCAL_AS_NO_PREPEND | PEER_FLAG_LOCAL_AS_REPLACE_AS)

#define PEER_UPDGRP_AF_FLAGS \
(PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY \
| PEER_FLAG_SEND_LARGE_COMMUNITY \
| PEER_FLAG_DEFAULT_ORIGINATE | PEER_FLAG_REFLECTOR_CLIENT \
| PEER_FLAG_RSERVER_CLIENT | PEER_FLAG_NEXTHOP_SELF \
| PEER_FLAG_NEXTHOP_UNCHANGED | PEER_FLAG_FORCE_NEXTHOP_SELF \
| PEER_FLAG_AS_PATH_UNCHANGED | PEER_FLAG_MED_UNCHANGED \
| PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | PEER_FLAG_REMOVE_PRIVATE_AS \
| PEER_FLAG_REMOVE_PRIVATE_AS_ALL \
| PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE \
| PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE \
| PEER_FLAG_AS_OVERRIDE)
(PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY | \
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI | PEER_FLAG_SEND_LARGE_COMMUNITY | \
PEER_FLAG_DEFAULT_ORIGINATE | PEER_FLAG_REFLECTOR_CLIENT | \
PEER_FLAG_RSERVER_CLIENT | PEER_FLAG_NEXTHOP_SELF | \
PEER_FLAG_NEXTHOP_UNCHANGED | PEER_FLAG_FORCE_NEXTHOP_SELF | \
PEER_FLAG_AS_PATH_UNCHANGED | PEER_FLAG_MED_UNCHANGED | \
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED | PEER_FLAG_REMOVE_PRIVATE_AS | \
PEER_FLAG_REMOVE_PRIVATE_AS_ALL | \
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE | \
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE | PEER_FLAG_AS_OVERRIDE)

#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)

Expand Down
45 changes: 43 additions & 2 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -6473,6 +6473,32 @@ ALIAS_HIDDEN(
"Send Standard Community attributes\n"
"Send Large Community attributes\n")

DEFPY (neighbor_ecommunity_rpki,
neighbor_ecommunity_rpki_cmd,
"[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor send-community extended rpki",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Send Community attribute to this neighbor\n"
"Send Extended Community attributes\n"
"Send RPKI Extended Community attributes\n")
{
struct peer *peer;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);

peer = peer_and_group_lookup_vty(vty, neighbor);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;

if (no)
return peer_af_flag_unset_vty(vty, neighbor, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI);
else
return peer_af_flag_set_vty(vty, neighbor, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI);
}

/* neighbor soft-reconfig. */
DEFUN (neighbor_soft_reconfiguration,
neighbor_soft_reconfiguration_cmd,
Expand Down Expand Up @@ -17665,8 +17691,8 @@ bool peergroup_flag_check(struct peer *peer, uint64_t flag)
return !!CHECK_FLAG(peer->flags_override, flag);
}

static bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
uint64_t flag)
bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
uint64_t flag)
{
if (!peer_group_active(peer)) {
if (CHECK_FLAG(peer->af_flags_invert[afi][safi], flag))
Expand Down Expand Up @@ -18442,6 +18468,12 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
if (flag_slcomm)
vty_out(vty, " no neighbor %s send-community large\n",
addr);

if (peergroup_af_flag_check(peer, afi, safi,
ton31337 marked this conversation as resolved.
Show resolved Hide resolved
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI))
vty_out(vty,
" no neighbor %s send-community extended rpki\n",
addr);
}

/* Default information */
Expand Down Expand Up @@ -20327,6 +20359,15 @@ void bgp_vty_init(void)
install_element(BGP_VPNV6_NODE, &neighbor_send_community_type_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_send_community_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_send_community_type_cmd);
install_element(BGP_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_IPV4_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_IPV4M_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_IPV4L_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_IPV6_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_IPV6M_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_IPV6L_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_VPNV4_NODE, &neighbor_ecommunity_rpki_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_ecommunity_rpki_cmd);

/* "neighbor route-reflector" commands.*/
install_element(BGP_NODE, &neighbor_route_reflector_client_hidden_cmd);
Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_vty.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,7 @@ extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
safi_t safi, const char *neighbor, int as_type,
as_t as, uint16_t show_flags);
extern bool peergroup_flag_check(struct peer *peer, uint64_t flag);
extern bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
uint64_t flag);

#endif /* _QUAGGA_BGP_VTY_H */
5 changes: 5 additions & 0 deletions bgpd/bgpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1512,13 +1512,17 @@ struct peer *peer_new(struct bgp *bgp)
SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI);
SET_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_SEND_LARGE_COMMUNITY);

SET_FLAG(peer->af_flags_invert[afi][safi],
PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(peer->af_flags_invert[afi][safi],
PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(peer->af_flags_invert[afi][safi],
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI);
SET_FLAG(peer->af_flags_invert[afi][safi],
PEER_FLAG_SEND_LARGE_COMMUNITY);
peer->addpath_type[afi][safi] = BGP_ADDPATH_NONE;
Expand Down Expand Up @@ -4608,6 +4612,7 @@ static const struct peer_flag_action peer_af_flag_action_list[] = {
{PEER_FLAG_DISABLE_ADDPATH_RX, 0, peer_change_none},
{PEER_FLAG_SOO, 0, peer_change_reset},
{PEER_FLAG_ACCEPT_OWN, 0, peer_change_reset},
{PEER_FLAG_SEND_EXT_COMMUNITY_RPKI, 1, peer_change_reset_out},
{0, 0, 0}};

/* Proper action set. */
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1527,6 +1527,7 @@ struct peer {
#define PEER_FLAG_MAX_PREFIX_FORCE (1ULL << 26)
#define PEER_FLAG_DISABLE_ADDPATH_RX (1ULL << 27)
#define PEER_FLAG_SOO (1ULL << 28)
#define PEER_FLAG_SEND_EXT_COMMUNITY_RPKI (1ULL << 29)
#define PEER_FLAG_ACCEPT_OWN (1ULL << 63)

enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX];
Expand Down
13 changes: 12 additions & 1 deletion doc/user/bgp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1674,7 +1674,18 @@ Configuring Peers
modifying the `net.core.optmem_max` sysctl to a larger value to
avoid out of memory errors from the linux kernel.

.. clicmd:: neighbor PEER send-community
.. clicmd:: neighbor PEER send-community <both|all|extended|standard|large>

Send the communities to the peer.

Default: enabled.

.. clicmd:: neighbor PEER send-community extended rpki

Send the extended RPKI communities to the peer. RPKI extended community
can be send only to iBGP and eBGP-OAD peers.

Default: enabled.

.. clicmd:: neighbor PEER weight WEIGHT

Expand Down
6 changes: 6 additions & 0 deletions tests/topotests/bgp_rpki_topo1/r2/bgpd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ router bgp 65002
neighbor 192.0.2.1 timers connect 1
neighbor 192.0.2.1 ebgp-multihop 3
neighbor 192.0.2.1 update-source 192.0.2.2
neighbor 192.168.4.4 remote-as internal
neighbor 192.168.4.4 timers 1 3
neighbor 192.168.4.4 timers connect 1
address-family ipv4 unicast
neighbor 192.168.4.4 next-hop-self
exit-address-family
!
router bgp 65002 vrf vrf10
no bgp ebgp-requires-policy
Expand Down
3 changes: 3 additions & 0 deletions tests/topotests/bgp_rpki_topo1/r2/zebra.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ interface r2-eth0
interface r2-eth1 vrf vrf10
ip address 192.168.2.2/24
!
interface r2-eth2
ip address 192.168.4.2/24
!
6 changes: 6 additions & 0 deletions tests/topotests/bgp_rpki_topo1/r4/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
router bgp 65002
no bgp ebgp-requires-policy
neighbor 192.168.4.2 remote-as internal
neighbor 192.168.4.2 timers 1 3
neighbor 192.168.4.2 timers connect 1
!
4 changes: 4 additions & 0 deletions tests/topotests/bgp_rpki_topo1/r4/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
!
interface r4-eth0
ip address 192.168.4.4/24
!
48 changes: 47 additions & 1 deletion tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


def build_topo(tgen):
for routern in range(1, 4):
for routern in range(1, 5):
tgen.add_router("r{}".format(routern))

switch = tgen.add_switch("s1")
Expand All @@ -33,6 +33,10 @@ def build_topo(tgen):
switch.add_link(tgen.gears["r2"])
switch.add_link(tgen.gears["r3"])

switch = tgen.add_switch("s3")
switch.add_link(tgen.gears["r2"])
switch.add_link(tgen.gears["r4"])


def setup_module(mod):
tgen = Topogen(build_topo, mod.__name__)
Expand Down Expand Up @@ -402,6 +406,48 @@ def test_show_bgp_rpki_route_map_vrf():
assert result is None, "Unexpected prefixes RPKI state on {}".format(rname)


def test_bgp_ecommunity_rpki():
tgen = get_topogen()

if tgen.routers_have_failure():
pytest.skip(tgen.errors)

r2 = tgen.gears["r2"]
r4 = tgen.gears["r4"]

# Flush all the states what was before and try sending out the prefixes
# with RPKI extended community.
r2.vtysh_cmd("clear ip bgp 192.168.4.4 soft out")

def _bgp_check_ecommunity_rpki(community=None):
output = json.loads(r4.vtysh_cmd("show bgp ipv4 unicast 198.51.100.0/24 json"))
expected = {
"paths": [
{
"extendedCommunity": community,
}
]
}
return topotest.json_cmp(output, expected)

test_func = functools.partial(_bgp_check_ecommunity_rpki, {"string": "OVS:valid"})
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Didn't receive RPKI extended community"

r2.vtysh_cmd(
"""
configure terminal
router bgp 65002
address-family ipv4 unicast
no neighbor 192.168.4.4 send-community extended rpki
"""
)

test_func = functools.partial(_bgp_check_ecommunity_rpki)
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
assert result is None, "Received RPKI extended community"


if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
Loading