mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 12:50:04 +00:00
Merge pull request #15284 from opensourcerouting/feature/bgpd_announce_rpki_state_knob
bgpd: Add neighbor X send-community extended rpki command
This commit is contained in:
commit
17a0a625f0
@ -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(
|
||||
bgp_attr_set_ecommunity(attr,
|
||||
ecommunity_add_origin_validation_state(
|
||||
rpki_state,
|
||||
bgp_attr_get_ecommunity(attr)));
|
||||
bgp_attr_get_ecommunity(
|
||||
attr)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
@ -17665,7 +17691,7 @@ 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,
|
||||
bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
|
||||
uint64_t flag)
|
||||
{
|
||||
if (!peer_group_active(peer)) {
|
||||
@ -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,
|
||||
PEER_FLAG_SEND_EXT_COMMUNITY_RPKI))
|
||||
vty_out(vty,
|
||||
" no neighbor %s send-community extended rpki\n",
|
||||
addr);
|
||||
}
|
||||
|
||||
/* Default information */
|
||||
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -1512,6 +1512,8 @@ 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);
|
||||
|
||||
@ -1519,6 +1521,8 @@ struct peer *peer_new(struct bgp *bgp)
|
||||
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;
|
||||
@ -4609,6 +4613,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. */
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
tests/topotests/bgp_rpki_topo1/r4/bgpd.conf
Normal file
6
tests/topotests/bgp_rpki_topo1/r4/bgpd.conf
Normal file
@ -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
tests/topotests/bgp_rpki_topo1/r4/zebra.conf
Normal file
4
tests/topotests/bgp_rpki_topo1/r4/zebra.conf
Normal file
@ -0,0 +1,4 @@
|
||||
!
|
||||
interface r4-eth0
|
||||
ip address 192.168.4.4/24
|
||||
!
|
@ -22,7 +22,7 @@ pytestmark = [pytest.mark.bgpd]
|
||||
|
||||
|
||||
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")
|
||||
@ -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__)
|
||||
@ -402,6 +406,48 @@ router bgp 65002 vrf vrf10
|
||||
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…
Reference in New Issue
Block a user