mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 07:23:41 +00:00
Merge pull request #12322 from fdumontet6WIND/confed_num
bgp: fix case where confederation id same as member-as
This commit is contained in:
commit
17ccfbb6c2
@ -1187,6 +1187,33 @@ int aspath_loop_check(struct aspath *aspath, as_t asno)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AS path loop check. If aspath contains asno
|
||||||
|
* that is a confed id then return >= 1.
|
||||||
|
*/
|
||||||
|
int aspath_loop_check_confed(struct aspath *aspath, as_t asno)
|
||||||
|
{
|
||||||
|
struct assegment *seg;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (aspath == NULL || aspath->segments == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
seg = aspath->segments;
|
||||||
|
|
||||||
|
while (seg) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < seg->length; i++)
|
||||||
|
if (seg->type != AS_CONFED_SEQUENCE &&
|
||||||
|
seg->type != AS_CONFED_SET && seg->as[i] == asno)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
seg = seg->next;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* When all of AS path is private AS return 1. */
|
/* When all of AS path is private AS return 1. */
|
||||||
bool aspath_private_as_check(struct aspath *aspath)
|
bool aspath_private_as_check(struct aspath *aspath)
|
||||||
{
|
{
|
||||||
|
@ -111,6 +111,7 @@ extern unsigned int aspath_key_make(const void *p);
|
|||||||
extern unsigned int aspath_get_first_as(struct aspath *aspath);
|
extern unsigned int aspath_get_first_as(struct aspath *aspath);
|
||||||
extern unsigned int aspath_get_last_as(struct aspath *aspath);
|
extern unsigned int aspath_get_last_as(struct aspath *aspath);
|
||||||
extern int aspath_loop_check(struct aspath *aspath, as_t asno);
|
extern int aspath_loop_check(struct aspath *aspath, as_t asno);
|
||||||
|
extern int aspath_loop_check_confed(struct aspath *aspath, as_t asno);
|
||||||
extern bool aspath_private_as_check(struct aspath *aspath);
|
extern bool aspath_private_as_check(struct aspath *aspath);
|
||||||
extern struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
|
extern struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
|
||||||
as_t target_asn,
|
as_t target_asn,
|
||||||
|
@ -2197,7 +2197,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||||||
|
|
||||||
/* If we're a CONFED we need to loop check the CONFED ID too */
|
/* If we're a CONFED we need to loop check the CONFED ID too */
|
||||||
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
|
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
|
||||||
if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
|
if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
|
||||||
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
|
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
|
"%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
|
||||||
@ -4114,16 +4114,23 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
|||||||
|
|
||||||
/* AS path loop check. */
|
/* AS path loop check. */
|
||||||
if (do_loop_check) {
|
if (do_loop_check) {
|
||||||
if (aspath_loop_check(attr->aspath, bgp->as) > allowas_in ||
|
if (aspath_loop_check(attr->aspath, bgp->as) >
|
||||||
(CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) &&
|
peer->allowas_in[afi][safi]) {
|
||||||
(aspath_loop_check(attr->aspath, bgp->confed_id) >
|
|
||||||
allowas_in))) {
|
|
||||||
peer->stat_pfx_aspath_loop++;
|
peer->stat_pfx_aspath_loop++;
|
||||||
reason = "as-path contains our own AS;";
|
reason = "as-path contains our own AS;";
|
||||||
goto filtered;
|
goto filtered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we're a CONFED we need to loop check the CONFED ID too */
|
||||||
|
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
|
||||||
|
if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
|
||||||
|
peer->allowas_in[afi][safi]) {
|
||||||
|
peer->stat_pfx_aspath_loop++;
|
||||||
|
reason = "as-path contains our own confed AS;";
|
||||||
|
goto filtered;
|
||||||
|
}
|
||||||
|
|
||||||
/* Route reflector originator ID check. If ACCEPT_OWN mechanism is
|
/* Route reflector originator ID check. If ACCEPT_OWN mechanism is
|
||||||
* enabled, then take care of that too.
|
* enabled, then take care of that too.
|
||||||
*/
|
*/
|
||||||
|
@ -1960,13 +1960,6 @@ DEFUN (bgp_confederation_peers,
|
|||||||
|
|
||||||
for (i = idx_asn; i < argc; i++) {
|
for (i = idx_asn; i < argc; i++) {
|
||||||
as = strtoul(argv[i]->arg, NULL, 10);
|
as = strtoul(argv[i]->arg, NULL, 10);
|
||||||
|
|
||||||
if (bgp->as == as) {
|
|
||||||
vty_out(vty,
|
|
||||||
"%% Local member-AS not allowed in confed peer list\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bgp_confederation_peers_add(bgp, as);
|
bgp_confederation_peers_add(bgp, as);
|
||||||
}
|
}
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
@ -671,7 +671,7 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as)
|
|||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (bgp->as == as)
|
if (!bgp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bgp_confederation_peers_check(bgp, as))
|
if (bgp_confederation_peers_check(bgp, as))
|
||||||
@ -687,8 +687,8 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as)
|
|||||||
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
|
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
|
||||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||||
if (peer->as == as) {
|
if (peer->as == as) {
|
||||||
(void)peer_sort(peer);
|
|
||||||
peer->local_as = bgp->as;
|
peer->local_as = bgp->as;
|
||||||
|
(void)peer_sort(peer);
|
||||||
if (BGP_IS_VALID_STATE_FOR_NOTIF(
|
if (BGP_IS_VALID_STATE_FOR_NOTIF(
|
||||||
peer->status)) {
|
peer->status)) {
|
||||||
peer->last_reset =
|
peer->last_reset =
|
||||||
@ -738,8 +738,8 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
|
|||||||
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
|
if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
|
||||||
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
|
||||||
if (peer->as == as) {
|
if (peer->as == as) {
|
||||||
(void)peer_sort(peer);
|
|
||||||
peer->local_as = bgp->confed_id;
|
peer->local_as = bgp->confed_id;
|
||||||
|
(void)peer_sort(peer);
|
||||||
if (BGP_IS_VALID_STATE_FOR_NOTIF(
|
if (BGP_IS_VALID_STATE_FOR_NOTIF(
|
||||||
peer->status)) {
|
peer->status)) {
|
||||||
peer->last_reset =
|
peer->last_reset =
|
||||||
|
0
tests/topotests/bgp_confed1/__init__.py
Normal file
0
tests/topotests/bgp_confed1/__init__.py
Normal file
63
tests/topotests/bgp_confed1/r1/bgp_ipv4_unicast.json
Normal file
63
tests/topotests/bgp_confed1/r1/bgp_ipv4_unicast.json
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"vrfId":0,
|
||||||
|
"vrfName":"default",
|
||||||
|
"routerId":"203.0.113.1",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":100,
|
||||||
|
"routes":{"203.0.113.0/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.0\/28",
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"0.0.0.0",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.16/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.16\/28",
|
||||||
|
"peerId":"192.0.2.2",
|
||||||
|
"path":"300",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.32/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.32\/28",
|
||||||
|
"peerId":"192.0.2.2",
|
||||||
|
"path":"300",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.48/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.48\/28",
|
||||||
|
"peerId":"192.0.2.2",
|
||||||
|
"path":"300 400",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
] } }
|
13
tests/topotests/bgp_confed1/r1/bgp_summary.json
Normal file
13
tests/topotests/bgp_confed1/r1/bgp_summary.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"routerId":"203.0.113.1",
|
||||||
|
"as":100,
|
||||||
|
"peers":{
|
||||||
|
"192.0.2.2":{
|
||||||
|
"remoteAs": 300,
|
||||||
|
"state": "Established",
|
||||||
|
"peerState":"OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
tests/topotests/bgp_confed1/r1/bgpd.conf
Normal file
13
tests/topotests/bgp_confed1/r1/bgpd.conf
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
debug bgp neighbor-events
|
||||||
|
debug bgp nht
|
||||||
|
debug bgp updates in
|
||||||
|
debug bgp updates out
|
||||||
|
!
|
||||||
|
router bgp 100
|
||||||
|
no bgp ebgp-requires-policy
|
||||||
|
!
|
||||||
|
neighbor 192.0.2.2 remote-as 300
|
||||||
|
address-family ipv4 unicast
|
||||||
|
network 203.0.113.0/28
|
||||||
|
exit-address-family
|
||||||
|
!
|
0
tests/topotests/bgp_confed1/r1/isisd.conf
Normal file
0
tests/topotests/bgp_confed1/r1/isisd.conf
Normal file
6
tests/topotests/bgp_confed1/r1/zebra.conf
Normal file
6
tests/topotests/bgp_confed1/r1/zebra.conf
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
interface r1-eth0
|
||||||
|
ip address 192.0.2.1/28
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 203.0.113.1/28
|
||||||
|
!
|
63
tests/topotests/bgp_confed1/r2/bgp_ipv4_unicast.json
Normal file
63
tests/topotests/bgp_confed1/r2/bgp_ipv4_unicast.json
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"vrfId":0,
|
||||||
|
"vrfName":"default",
|
||||||
|
"routerId":"203.0.113.17",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":200,
|
||||||
|
"routes":{"203.0.113.0/28": [
|
||||||
|
{
|
||||||
|
"network":"203.0.113.0\/28",
|
||||||
|
"peerId":"192.0.2.1",
|
||||||
|
"path":"100",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.16/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.16\/28",
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"0.0.0.0",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.32/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.32\/28",
|
||||||
|
"peerId":"192.0.2.18",
|
||||||
|
"path":"(300)",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.18",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.48/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.48\/28",
|
||||||
|
"peerId":"192.0.2.18",
|
||||||
|
"path":"(300) 400",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.50",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
] } }
|
18
tests/topotests/bgp_confed1/r2/bgp_summary.json
Normal file
18
tests/topotests/bgp_confed1/r2/bgp_summary.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"routerId":"203.0.113.17",
|
||||||
|
"as":200,
|
||||||
|
"peers":{
|
||||||
|
"192.0.2.1":{
|
||||||
|
"remoteAs":100,
|
||||||
|
"state":"Established",
|
||||||
|
"peerState":"OK"
|
||||||
|
},
|
||||||
|
"192.0.2.18":{
|
||||||
|
"remoteAs":300,
|
||||||
|
"state":"Established",
|
||||||
|
"peerState":"OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
tests/topotests/bgp_confed1/r2/bgpd.conf
Normal file
18
tests/topotests/bgp_confed1/r2/bgpd.conf
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
debug bgp neighbor-events
|
||||||
|
debug bgp nht
|
||||||
|
debug bgp updates in
|
||||||
|
debug bgp updates out
|
||||||
|
!
|
||||||
|
router bgp 200
|
||||||
|
no bgp ebgp-requires-policy
|
||||||
|
bgp confederation identifier 300
|
||||||
|
bgp confederation peers 300
|
||||||
|
neighbor 192.0.2.1 remote-as 100
|
||||||
|
neighbor 192.0.2.18 remote-as 300
|
||||||
|
!
|
||||||
|
address-family ipv4 unicast
|
||||||
|
network 203.0.113.16/28
|
||||||
|
neighbor 192.0.2.18 default-originate
|
||||||
|
exit-address-family
|
||||||
|
!
|
||||||
|
|
8
tests/topotests/bgp_confed1/r2/isisd.conf
Normal file
8
tests/topotests/bgp_confed1/r2/isisd.conf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
interface r2-eth1
|
||||||
|
ip router isis 1
|
||||||
|
isis circuit-type level-2-only
|
||||||
|
|
||||||
|
router isis 1
|
||||||
|
is-type level-2-only
|
||||||
|
net 49.0001.0002.0002.0002.00
|
||||||
|
redistribute ipv4 connected level-2
|
9
tests/topotests/bgp_confed1/r2/zebra.conf
Normal file
9
tests/topotests/bgp_confed1/r2/zebra.conf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
interface r2-eth0
|
||||||
|
ip address 192.0.2.2/28
|
||||||
|
!
|
||||||
|
interface r2-eth1
|
||||||
|
ip address 192.0.2.17/28
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 203.0.113.17/28
|
||||||
|
!
|
77
tests/topotests/bgp_confed1/r3/bgp_ipv4_unicast.json
Normal file
77
tests/topotests/bgp_confed1/r3/bgp_ipv4_unicast.json
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"vrfId":0,
|
||||||
|
"vrfName":"default",
|
||||||
|
"routerId":"203.0.113.33",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":300,
|
||||||
|
"routes":{"0.0.0.0/0":[
|
||||||
|
{
|
||||||
|
"network":"0.0.0.0\/0",
|
||||||
|
"peerId":"192.0.2.17",
|
||||||
|
"path":"(200)",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.17",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.0/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.0\/28",
|
||||||
|
"peerId":"192.0.2.17",
|
||||||
|
"path":"(200) 100",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.16/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.16\/28",
|
||||||
|
"peerId":"192.0.2.17",
|
||||||
|
"path":"(200)",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.17",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.32/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.32\/28",
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"0.0.0.0",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.48/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.48\/28",
|
||||||
|
"peerId":"192.0.2.50",
|
||||||
|
"path":"400",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.50",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
] } }
|
18
tests/topotests/bgp_confed1/r3/bgp_summary.json
Normal file
18
tests/topotests/bgp_confed1/r3/bgp_summary.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"routerId":"203.0.113.33",
|
||||||
|
"as":300,
|
||||||
|
"peers":{
|
||||||
|
"192.0.2.17":{
|
||||||
|
"remoteAs":200,
|
||||||
|
"state":"Established",
|
||||||
|
"peerState":"OK"
|
||||||
|
},
|
||||||
|
"192.0.2.50":{
|
||||||
|
"remoteAs":400,
|
||||||
|
"state":"Established",
|
||||||
|
"peerState":"OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
tests/topotests/bgp_confed1/r3/bgpd.conf
Normal file
17
tests/topotests/bgp_confed1/r3/bgpd.conf
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
debug bgp neighbor-events
|
||||||
|
debug bgp nht
|
||||||
|
debug bgp updates in
|
||||||
|
debug bgp updates out
|
||||||
|
!
|
||||||
|
router bgp 300
|
||||||
|
no bgp ebgp-requires-policy
|
||||||
|
bgp confederation identifier 300
|
||||||
|
bgp confederation peers 200
|
||||||
|
neighbor 192.0.2.17 remote-as 200
|
||||||
|
neighbor 192.0.2.50 remote-as 400
|
||||||
|
!
|
||||||
|
address-family ipv4 unicast
|
||||||
|
network 203.0.113.32/28
|
||||||
|
exit-address-family
|
||||||
|
!
|
||||||
|
|
8
tests/topotests/bgp_confed1/r3/isisd.conf
Normal file
8
tests/topotests/bgp_confed1/r3/isisd.conf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
interface r3-eth1
|
||||||
|
ip router isis 1
|
||||||
|
isis circuit-type level-2-only
|
||||||
|
|
||||||
|
router isis 1
|
||||||
|
is-type level-2-only
|
||||||
|
net 49.0001.0003.0003.0003.00
|
||||||
|
redistribute ipv4 connected level-2
|
10
tests/topotests/bgp_confed1/r3/zebra.conf
Normal file
10
tests/topotests/bgp_confed1/r3/zebra.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
!
|
||||||
|
interface r3-eth0
|
||||||
|
ip address 192.0.2.49/28
|
||||||
|
!
|
||||||
|
interface r3-eth1
|
||||||
|
ip address 192.0.2.18/28
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 203.0.113.33/28
|
||||||
|
!
|
77
tests/topotests/bgp_confed1/r4/bgp_ipv4_unicast.json
Normal file
77
tests/topotests/bgp_confed1/r4/bgp_ipv4_unicast.json
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"vrfId":0,
|
||||||
|
"vrfName":"default",
|
||||||
|
"routerId":"203.0.113.49",
|
||||||
|
"defaultLocPrf":100,
|
||||||
|
"localAS":400,
|
||||||
|
"routes":{"0.0.0.0/0":[
|
||||||
|
{
|
||||||
|
"network":"0.0.0.0\/0",
|
||||||
|
"peerId":"192.0.2.49",
|
||||||
|
"path":"300",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.49",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.0/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.0\/28",
|
||||||
|
"peerId":"192.0.2.49",
|
||||||
|
"path":"300 100",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.49",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.16/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.16\/28",
|
||||||
|
"peerId":"192.0.2.49",
|
||||||
|
"path":"300",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.49",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.32/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.32\/28",
|
||||||
|
"peerId":"192.0.2.49",
|
||||||
|
"path":"300",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"192.0.2.49",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],"203.0.113.48/28":[
|
||||||
|
{
|
||||||
|
"network":"203.0.113.48\/28",
|
||||||
|
"peerId":"(unspec)",
|
||||||
|
"path":"",
|
||||||
|
"origin":"IGP",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"0.0.0.0",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"used":true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
] } }
|
13
tests/topotests/bgp_confed1/r4/bgp_summary.json
Normal file
13
tests/topotests/bgp_confed1/r4/bgp_summary.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"ipv4Unicast":{
|
||||||
|
"routerId":"203.0.113.49",
|
||||||
|
"as":400,
|
||||||
|
"peers":{
|
||||||
|
"192.0.2.49":{
|
||||||
|
"remoteAs":300,
|
||||||
|
"state":"Established",
|
||||||
|
"peerState":"OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
tests/topotests/bgp_confed1/r4/bgpd.conf
Normal file
14
tests/topotests/bgp_confed1/r4/bgpd.conf
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
debug bgp neighbor-events
|
||||||
|
debug bgp nht
|
||||||
|
debug bgp updates in
|
||||||
|
debug bgp updates out
|
||||||
|
!
|
||||||
|
router bgp 400
|
||||||
|
no bgp ebgp-requires-policy
|
||||||
|
bgp disable-ebgp-connected-route-check
|
||||||
|
!
|
||||||
|
neighbor 192.0.2.49 remote-as 300
|
||||||
|
address-family ipv4 unicast
|
||||||
|
network 203.0.113.48/28
|
||||||
|
exit-address-family
|
||||||
|
!
|
0
tests/topotests/bgp_confed1/r4/isisd.conf
Normal file
0
tests/topotests/bgp_confed1/r4/isisd.conf
Normal file
6
tests/topotests/bgp_confed1/r4/zebra.conf
Normal file
6
tests/topotests/bgp_confed1/r4/zebra.conf
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
interface r4-eth0
|
||||||
|
ip address 192.0.2.50/28
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 203.0.113.49/28
|
||||||
|
!
|
129
tests/topotests/bgp_confed1/test_bgp_confed1.py
Normal file
129
tests/topotests/bgp_confed1/test_bgp_confed1.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#
|
||||||
|
# test_bgp_confed1.py
|
||||||
|
#
|
||||||
|
# Copyright 2022 6WIND S.A.
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or distribute this software
|
||||||
|
# for any purpose with or without fee is hereby granted, provided
|
||||||
|
# that the above copyright notice and this permission notice appear
|
||||||
|
# in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND 6WIND DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 6WIND BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
|
||||||
|
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||||
|
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
# OF THIS SOFTWARE.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
test_bgp_confed1.py: Test the FRR BGP confederations with AS member
|
||||||
|
same as confederation Id, verify BGP prefixes and path distribution
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from functools import partial
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
# Save the Current Working Directory to find configuration files.
|
||||||
|
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
sys.path.append(os.path.join(CWD, "../"))
|
||||||
|
|
||||||
|
# pylint: disable=C0413
|
||||||
|
# Import topogen and topotest helpers
|
||||||
|
from lib import topotest
|
||||||
|
from lib.topogen import Topogen, TopoRouter, get_topogen
|
||||||
|
from lib.topolog import logger
|
||||||
|
|
||||||
|
pytestmark = [pytest.mark.bgpd]
|
||||||
|
|
||||||
|
|
||||||
|
def build_topo(tgen):
|
||||||
|
for routern in range(1, 5):
|
||||||
|
tgen.add_router("r{}".format(routern))
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s1")
|
||||||
|
switch.add_link(tgen.gears["r1"])
|
||||||
|
switch.add_link(tgen.gears["r2"])
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s3")
|
||||||
|
switch.add_link(tgen.gears["r3"])
|
||||||
|
switch.add_link(tgen.gears["r4"])
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s2")
|
||||||
|
switch.add_link(tgen.gears["r2"])
|
||||||
|
switch.add_link(tgen.gears["r3"])
|
||||||
|
|
||||||
|
def setup_module(mod):
|
||||||
|
|
||||||
|
tgen = Topogen(build_topo, mod.__name__)
|
||||||
|
tgen.start_topology()
|
||||||
|
|
||||||
|
router_list = tgen.routers()
|
||||||
|
for rname, router in router_list.items():
|
||||||
|
router.load_config(
|
||||||
|
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
|
||||||
|
)
|
||||||
|
router.load_config(
|
||||||
|
TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
|
||||||
|
)
|
||||||
|
router.load_config(
|
||||||
|
TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialize all routers.
|
||||||
|
tgen.start_router()
|
||||||
|
|
||||||
|
def teardown_module(_mod):
|
||||||
|
"Teardown the pytest environment"
|
||||||
|
tgen = get_topogen()
|
||||||
|
tgen.stop_topology()
|
||||||
|
|
||||||
|
|
||||||
|
def test_bgp_convergence():
|
||||||
|
"Assert that BGP is converging."
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
logger.info("waiting for bgp peers to go up")
|
||||||
|
|
||||||
|
for router in tgen.routers().values():
|
||||||
|
ref_file = "{}/{}/bgp_summary.json".format(CWD, router.name)
|
||||||
|
expected = json.loads(open(ref_file).read())
|
||||||
|
test_func = partial(
|
||||||
|
topotest.router_json_cmp, router, "show ip bgp summary json", expected
|
||||||
|
)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=125, wait=2.0)
|
||||||
|
assertmsg = "{}: bgp did not converge".format(router.name)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
|
||||||
|
def test_bgp_confed_ipv4_unicast():
|
||||||
|
"Assert that BGP is exchanging BGP route."
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
logger.info("waiting for bgp peers exchanging UPDATES")
|
||||||
|
|
||||||
|
for router in tgen.routers().values():
|
||||||
|
ref_file = "{}/{}/bgp_ipv4_unicast.json".format(CWD, router.name)
|
||||||
|
expected = json.loads(open(ref_file).read())
|
||||||
|
test_func = partial(
|
||||||
|
topotest.router_json_cmp, router, "show bgp ipv4 unicast json", expected
|
||||||
|
)
|
||||||
|
_, res = topotest.run_and_expect(test_func, None, count=40, wait=2.5)
|
||||||
|
assertmsg = "{}: BGP UPDATE exchange failure".format(router.name)
|
||||||
|
assert res is None, assertmsg
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = ["-s"] + sys.argv[1:]
|
||||||
|
sys.exit(pytest.main(args))
|
Loading…
Reference in New Issue
Block a user