mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-26 23:23:35 +00:00
Merge pull request #17071 from louis-6wind/fix-ipv6-ll-nexthop-unchanged
bgpd: split nexthop-local unchanged peer subgroup
This commit is contained in:
commit
129c652ff1
@ -455,6 +455,10 @@ static unsigned int updgrp_hash_key_make(const void *p)
|
||||
key = jhash_1word(jhash(soo_str, strlen(soo_str), SEED1), key);
|
||||
}
|
||||
|
||||
if (afi == AFI_IP6 &&
|
||||
(CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
|
||||
key = jhash(&peer->nexthop.v6_global, IPV6_MAX_BYTELEN, key);
|
||||
|
||||
/*
|
||||
* ANY NEW ITEMS THAT ARE ADDED TO THE key, ENSURE DEBUG
|
||||
* STATEMENT STAYS UP TO DATE
|
||||
@ -521,6 +525,12 @@ static unsigned int updgrp_hash_key_make(const void *p)
|
||||
peer->soo[afi][safi]
|
||||
? ecommunity_str(peer->soo[afi][safi])
|
||||
: "(NONE)");
|
||||
zlog_debug("%pBP Update Group Hash: IPv6 nexthop-local unchanged: %d IPv6 global %pI6",
|
||||
peer,
|
||||
afi == AFI_IP6 && (CHECK_FLAG(peer->af_flags[afi][safi],
|
||||
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)),
|
||||
&peer->nexthop.v6_global);
|
||||
|
||||
zlog_debug("%pBP Update Group Hash key: %u", peer, key);
|
||||
}
|
||||
return key;
|
||||
@ -655,6 +665,12 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2)
|
||||
!sockunion_same(&pe1->connection->su, &pe2->connection->su))
|
||||
return false;
|
||||
|
||||
if (afi == AFI_IP6 &&
|
||||
(CHECK_FLAG(flags1, PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) ||
|
||||
CHECK_FLAG(flags2, PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) &&
|
||||
!IPV6_ADDR_SAME(&pe1->nexthop.v6_global, &pe2->nexthop.v6_global))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,13 @@
|
||||
"ip": "fd00:0:2::2",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -48,7 +54,13 @@
|
||||
"ip": "fd00:0:2::4",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -61,7 +73,13 @@
|
||||
"ip": "fd00:0:3::5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -74,7 +92,13 @@
|
||||
"ip": "fd00:0:4::6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -100,7 +124,13 @@
|
||||
"ip": "fd00:0:2::2",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -126,7 +156,13 @@
|
||||
"ip": "fd00:0:2::4",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -139,7 +175,13 @@
|
||||
"ip": "fd00:0:3::5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -152,7 +194,13 @@
|
||||
"ip": "fd00:0:4::6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
|
@ -9,7 +9,13 @@
|
||||
"ip": "fd00:0:2::1",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -48,7 +54,13 @@
|
||||
"ip": "fd00:0:2::4",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -61,7 +73,13 @@
|
||||
"ip": "fd00:0:3::5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -74,7 +92,13 @@
|
||||
"ip": "fd00:0:4::6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -87,7 +111,13 @@
|
||||
"ip": "fd00:0:2::1",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -126,7 +156,13 @@
|
||||
"ip": "fd00:0:2::4",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -139,7 +175,13 @@
|
||||
"ip": "fd00:0:3::5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -152,7 +194,13 @@
|
||||
"ip": "fd00:0:4::6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-sw",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
|
@ -47,13 +47,7 @@
|
||||
"ip": "fd00:0:3::9",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -155,13 +149,7 @@
|
||||
"ip": "fd00:0:3::9",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
|
@ -9,7 +9,13 @@
|
||||
"ip": "fd00:0:2::1",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -22,7 +28,13 @@
|
||||
"ip": "fd00:0:2::2",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -48,7 +60,13 @@
|
||||
"ip": "fd00:0:2::4",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -61,7 +79,13 @@
|
||||
"ip": "fd00:0:3::5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -87,7 +111,13 @@
|
||||
"ip": "fd00:0:2::1",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -100,7 +130,13 @@
|
||||
"ip": "fd00:0:2::2",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -126,7 +162,13 @@
|
||||
"ip": "fd00:0:2::4",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
@ -139,7 +181,13 @@
|
||||
"ip": "fd00:0:3::5",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:rr:eth-r6",
|
||||
"hostname": "rr",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
|
@ -19,12 +19,17 @@ router bgp 65000
|
||||
neighbor fd00:0:4::6 route-reflector-client
|
||||
address-family ipv6 unicast
|
||||
neighbor fd00:0:2::1 route-reflector-client
|
||||
neighbor fd00:0:2::1 nexthop-local unchanged
|
||||
neighbor fd00:0:2::1 activate
|
||||
neighbor fd00:0:2::2 route-reflector-client
|
||||
neighbor fd00:0:2::2 nexthop-local unchanged
|
||||
neighbor fd00:0:2::2 activate
|
||||
neighbor fd00:0:2::3 route-reflector-client
|
||||
neighbor fd00:0:2::3 nexthop-local unchanged
|
||||
neighbor fd00:0:2::3 activate
|
||||
neighbor fd00:0:2::4 nexthop-local unchanged
|
||||
neighbor fd00:0:2::4 activate
|
||||
neighbor fd00:0:3::5 nexthop-local unchanged
|
||||
neighbor fd00:0:3::5 activate
|
||||
neighbor fd00:0:4::6 nexthop-local unchanged
|
||||
neighbor fd00:0:4::6 activate
|
||||
|
@ -165,6 +165,21 @@ def replace_link_local(expected, cache):
|
||||
nexthop["ip"] = ip
|
||||
|
||||
|
||||
def check_rr_sub_group(expected):
|
||||
tgen = get_topogen()
|
||||
|
||||
rr = tgen.gears["rr"]
|
||||
|
||||
output = json.loads(rr.vtysh_cmd("show bgp update-groups json"))
|
||||
actual = [
|
||||
subgroup["peers"]
|
||||
for entry in output.get("default", {}).values()
|
||||
for subgroup in entry["subGroup"]
|
||||
]
|
||||
|
||||
return topotest.json_cmp(actual, expected)
|
||||
|
||||
|
||||
def teardown_module(_mod):
|
||||
"Teardown the pytest environment"
|
||||
tgen = get_topogen()
|
||||
@ -222,6 +237,19 @@ def test_bgp_ipv6_table_step1():
|
||||
assertmsg = "{}: BGP IPv6 Nexthop failure".format(router.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
# check rr sub-groups
|
||||
expected = [
|
||||
["fd00:0:2::1", "fd00:0:2::2"],
|
||||
["fd00:0:2::3"],
|
||||
["fd00:0:2::4"],
|
||||
["fd00:0:3::5"],
|
||||
["fd00:0:4::6"],
|
||||
]
|
||||
|
||||
test_func = partial(check_rr_sub_group, expected)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Peer group split failed"
|
||||
|
||||
|
||||
def test_bgp_ipv6_table_step2():
|
||||
tgen = get_topogen()
|
||||
@ -236,7 +264,12 @@ def test_bgp_ipv6_table_step2():
|
||||
configure terminal
|
||||
router bgp 65000
|
||||
address-family ipv6 unicast
|
||||
no neighbor fd00:0:2::1 nexthop-local unchanged
|
||||
no neighbor fd00:0:2::2 nexthop-local unchanged
|
||||
no neighbor fd00:0:2::3 nexthop-local unchanged
|
||||
no neighbor fd00:0:2::4 nexthop-local unchanged
|
||||
no neighbor fd00:0:3::5 nexthop-local unchanged
|
||||
no neighbor fd00:0:4::6 nexthop-local unchanged
|
||||
"""
|
||||
)
|
||||
|
||||
@ -257,6 +290,71 @@ router bgp 65000
|
||||
assertmsg = "{}: BGP IPv6 Nexthop failure".format(router.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
# check rr sub-groups
|
||||
expected = [
|
||||
["fd00:0:2::1", "fd00:0:2::2"],
|
||||
["fd00:0:2::3"],
|
||||
["fd00:0:3::5", "fd00:0:2::4"],
|
||||
["fd00:0:4::6"],
|
||||
]
|
||||
|
||||
test_func = partial(check_rr_sub_group, expected)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Peer group split failed"
|
||||
|
||||
|
||||
def test_bgp_ipv6_table_step3():
|
||||
tgen = get_topogen()
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
rr = tgen.gears["rr"]
|
||||
rr.vtysh_cmd(
|
||||
"""
|
||||
configure terminal
|
||||
router bgp 65000
|
||||
address-family ipv6 unicast
|
||||
neighbor fd00:0:2::1 nexthop-local unchanged
|
||||
neighbor fd00:0:2::2 nexthop-local unchanged
|
||||
neighbor fd00:0:2::3 nexthop-local unchanged
|
||||
neighbor fd00:0:2::4 nexthop-local unchanged
|
||||
neighbor fd00:0:3::5 nexthop-local unchanged
|
||||
neighbor fd00:0:4::6 nexthop-local unchanged
|
||||
"""
|
||||
)
|
||||
|
||||
router_list = tgen.routers().values()
|
||||
for router in router_list:
|
||||
# router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name)
|
||||
ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name)
|
||||
expected = json.loads(open(ref_file).read())
|
||||
replace_link_local(expected, link_local_cache)
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
router,
|
||||
"show bgp ipv6 unicast json",
|
||||
expected,
|
||||
)
|
||||
_, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}: BGP IPv6 Nexthop failure".format(router.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
# check rr sub-groups
|
||||
expected = [
|
||||
["fd00:0:2::1", "fd00:0:2::2"],
|
||||
["fd00:0:2::3"],
|
||||
["fd00:0:2::4"],
|
||||
["fd00:0:3::5"],
|
||||
["fd00:0:4::6"],
|
||||
]
|
||||
|
||||
test_func = partial(check_rr_sub_group, expected)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Peer group split failed"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = ["-s"] + sys.argv[1:]
|
||||
|
53
tests/topotests/bgp_route_server_client/exabgp.env
Normal file
53
tests/topotests/bgp_route_server_client/exabgp.env
Normal file
@ -0,0 +1,53 @@
|
||||
[exabgp.api]
|
||||
encoder = text
|
||||
highres = false
|
||||
respawn = false
|
||||
socket = ''
|
||||
|
||||
[exabgp.bgp]
|
||||
openwait = 60
|
||||
|
||||
[exabgp.cache]
|
||||
attributes = true
|
||||
nexthops = true
|
||||
|
||||
[exabgp.daemon]
|
||||
daemonize = true
|
||||
pid = '/var/run/exabgp/exabgp.pid'
|
||||
user = 'exabgp'
|
||||
##daemonize = false
|
||||
|
||||
[exabgp.log]
|
||||
all = false
|
||||
configuration = true
|
||||
daemon = true
|
||||
destination = '/var/log/exabgp.log'
|
||||
enable = true
|
||||
level = INFO
|
||||
message = false
|
||||
network = true
|
||||
packets = false
|
||||
parser = false
|
||||
processes = true
|
||||
reactor = true
|
||||
rib = false
|
||||
routes = false
|
||||
short = false
|
||||
timers = false
|
||||
|
||||
[exabgp.pdb]
|
||||
enable = false
|
||||
|
||||
[exabgp.profile]
|
||||
enable = false
|
||||
file = ''
|
||||
|
||||
[exabgp.reactor]
|
||||
speed = 1.0
|
||||
|
||||
[exabgp.tcp]
|
||||
acl = false
|
||||
bind = ''
|
||||
delay = 0
|
||||
once = false
|
||||
port = 179
|
@ -0,0 +1,95 @@
|
||||
{
|
||||
"routerId": "10.10.10.1",
|
||||
"localAS": 65001,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
{
|
||||
"routerId": "10.10.10.1",
|
||||
"localAS": 65001,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:r2-eth0",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:r2-eth0",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -4,14 +4,24 @@ router bgp 65000 view RS
|
||||
neighbor 2001:db8:1::2 remote-as external
|
||||
neighbor 2001:db8:1::2 timers 3 10
|
||||
neighbor 2001:db8:1::2 timers connect 5
|
||||
neighbor 2001:db8:1::3 remote-as external
|
||||
neighbor 2001:db8:1::3 timers 3 10
|
||||
neighbor 2001:db8:1::3 timers connect 5
|
||||
neighbor 2001:db8:1::4 remote-as external
|
||||
neighbor 2001:db8:1::4 timers 3 10
|
||||
neighbor 2001:db8:1::4 timers connect 5
|
||||
neighbor 2001:db8:3::2 remote-as external
|
||||
neighbor 2001:db8:3::2 timers 3 10
|
||||
neighbor 2001:db8:3::2 timers connect 5
|
||||
address-family ipv6 unicast
|
||||
redistribute connected
|
||||
neighbor 2001:db8:1::2 activate
|
||||
neighbor 2001:db8:1::3 activate
|
||||
neighbor 2001:db8:1::4 activate
|
||||
neighbor 2001:db8:3::2 activate
|
||||
neighbor 2001:db8:1::2 route-server-client
|
||||
neighbor 2001:db8:1::3 route-server-client
|
||||
neighbor 2001:db8:1::4 route-server-client
|
||||
neighbor 2001:db8:3::2 route-server-client
|
||||
exit-address-family
|
||||
!
|
||||
|
@ -0,0 +1,208 @@
|
||||
{
|
||||
"routerId": "10.10.10.2",
|
||||
"localAS": 65000,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r3:r3-eth0",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r3:r3-eth0",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,208 @@
|
||||
{
|
||||
"routerId": "10.10.10.2",
|
||||
"localAS": 65000,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r3:r3-eth0",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r3:r3-eth0",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r1",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r4:r4-eth0",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"ipv6Unicast": {
|
||||
"failedPeers": 0,
|
||||
"totalPeers": 4
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
router bgp 65003
|
||||
bgp router-id 10.10.10.3
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp enforce-first-as
|
||||
neighbor 2001:db8:3::1 remote-as external
|
||||
neighbor 2001:db8:3::1 timers 3 10
|
||||
neighbor 2001:db8:3::1 timers connect 5
|
||||
|
@ -0,0 +1,84 @@
|
||||
{
|
||||
"routerId": "10.10.10.3",
|
||||
"localAS": 65003,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
{
|
||||
"routerId": "10.10.10.3",
|
||||
"localAS": 65003,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:r2-eth1",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::3",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:r2-eth1",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
13
tests/topotests/bgp_route_server_client/r4/bgpd.conf
Normal file
13
tests/topotests/bgp_route_server_client/r4/bgpd.conf
Normal file
@ -0,0 +1,13 @@
|
||||
!
|
||||
router bgp 65004
|
||||
bgp router-id 10.10.10.4
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp enforce-first-as
|
||||
neighbor 2001:db8:1::1 remote-as external
|
||||
neighbor 2001:db8:1::1 timers 3 10
|
||||
neighbor 2001:db8:1::1 timers connect 5
|
||||
address-family ipv6 unicast
|
||||
redistribute connected
|
||||
neighbor 2001:db8:1::1 activate
|
||||
exit-address-family
|
||||
!
|
@ -0,0 +1,95 @@
|
||||
{
|
||||
"routerId": "10.10.10.4",
|
||||
"localAS": 65004,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
{
|
||||
"routerId": "10.10.10.4",
|
||||
"localAS": 65004,
|
||||
"routes": {
|
||||
"2001:db8:1::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:3::/64": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:r2-eth0",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::1/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r1:r1-eth0",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::3/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global"
|
||||
},
|
||||
{
|
||||
"ip": "link-local:r2:r2-eth0",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "link-local",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::4/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "::",
|
||||
"hostname": "r4",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db8:f::5/128": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:1::4",
|
||||
"hostname": "r2",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
"used": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
7
tests/topotests/bgp_route_server_client/r4/zebra.conf
Normal file
7
tests/topotests/bgp_route_server_client/r4/zebra.conf
Normal file
@ -0,0 +1,7 @@
|
||||
!
|
||||
int lo
|
||||
ipv6 address 2001:db8:f::4/128
|
||||
!
|
||||
int r4-eth0
|
||||
ipv6 address 2001:db8:1::3/64
|
||||
!
|
16
tests/topotests/bgp_route_server_client/r5/exabgp.cfg
Normal file
16
tests/topotests/bgp_route_server_client/r5/exabgp.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
neighbor 2001:db8:1::1{
|
||||
router-id 10.10.10.5;
|
||||
local-address 2001:db8:1::4;
|
||||
local-as 65005;
|
||||
peer-as 65000;
|
||||
|
||||
family {
|
||||
ipv6 unicast;
|
||||
}
|
||||
|
||||
static {
|
||||
route 2001:db8:1::0/64 next-hop 2001:db8:1::4;
|
||||
route 2001:db8:f::5/128 next-hop 2001:db8:1::4;
|
||||
}
|
||||
hold-time 10;
|
||||
}
|
@ -13,6 +13,7 @@ import os
|
||||
import sys
|
||||
import json
|
||||
import pytest
|
||||
from functools import partial
|
||||
import functools
|
||||
|
||||
pytestmark = [pytest.mark.bgpd]
|
||||
@ -26,16 +27,49 @@ from lib.topogen import Topogen, TopoRouter, get_topogen
|
||||
|
||||
|
||||
def build_topo(tgen):
|
||||
for routern in range(1, 4):
|
||||
"""
|
||||
All peers are FRR BGP peers except r5 that is a exabgp peer.
|
||||
Exabgp does not send any IPv6 Link-Local nexthop
|
||||
|
||||
r2 is a route-server view RS AS 65000
|
||||
Other routers rX has AS 6500X
|
||||
|
||||
+---+
|
||||
| r3|
|
||||
+---+
|
||||
|
|
||||
2001:db8:3::0/64
|
||||
|
|
||||
eth1
|
||||
+---+
|
||||
|r2 |
|
||||
+---+
|
||||
eth0
|
||||
|
|
||||
2001:db8:1::0/64
|
||||
/ | \
|
||||
+---+ +---+ +---+
|
||||
| r1| | r4| |r5 |
|
||||
+---+ +---+ +---+
|
||||
"""
|
||||
|
||||
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"])
|
||||
sw1 = tgen.add_switch("s1")
|
||||
sw1.add_link(tgen.gears["r1"])
|
||||
sw1.add_link(tgen.gears["r2"])
|
||||
sw1.add_link(tgen.gears["r4"])
|
||||
|
||||
switch = tgen.add_switch("s2")
|
||||
switch.add_link(tgen.gears["r2"])
|
||||
switch.add_link(tgen.gears["r3"])
|
||||
sw2 = tgen.add_switch("s2")
|
||||
sw2.add_link(tgen.gears["r2"])
|
||||
sw2.add_link(tgen.gears["r3"])
|
||||
|
||||
## Add iBGP ExaBGP neighbor
|
||||
peer_ip = "2001:db8:1::4" ## peer
|
||||
peer_route = "via 2001:db8:1::1" ## router
|
||||
r5 = tgen.add_exabgp_peer("r5", ip=peer_ip, defaultRoute=peer_route)
|
||||
sw1.add_link(r5)
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
@ -54,73 +88,225 @@ def setup_module(mod):
|
||||
|
||||
tgen.start_router()
|
||||
|
||||
# Start r5 exabgp peer
|
||||
r5 = tgen.gears["r5"]
|
||||
r5.start(os.path.join(CWD, "r5"), os.path.join(CWD, "exabgp.env"))
|
||||
|
||||
|
||||
def teardown_module(mod):
|
||||
tgen = get_topogen()
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
def test_bgp_route_server_client():
|
||||
def get_link_local(rname, ifname, cache):
|
||||
ip = cache.get(rname, {}).get(ifname)
|
||||
if ip:
|
||||
return ip
|
||||
|
||||
tgen = get_topogen()
|
||||
out = tgen.gears[rname].vtysh_cmd("show interface %s json" % ifname, isjson=True)
|
||||
for address in out[ifname]["ipAddresses"]:
|
||||
if not address["address"].startswith("fe80::"):
|
||||
continue
|
||||
ip = address["address"].split("/")[0]
|
||||
cache.setdefault(rname, {})[ifname] = ip
|
||||
return ip
|
||||
|
||||
|
||||
def replace_link_local(expected, cache):
|
||||
for prefix, prefix_infos in expected.get("routes", {}).items():
|
||||
for prefix_info in prefix_infos:
|
||||
for nexthop in prefix_info.get("nexthops", []):
|
||||
ip = nexthop.get("ip", "")
|
||||
if not ip.startswith("link-local:"):
|
||||
continue
|
||||
rname = ip.split(":")[1]
|
||||
ifname = ip.split(":")[2]
|
||||
ip = get_link_local(rname, ifname, cache)
|
||||
nexthop["ip"] = ip
|
||||
|
||||
|
||||
def check_r2_sub_group(expected):
|
||||
tgen = get_topogen()
|
||||
|
||||
r2 = tgen.gears["r2"]
|
||||
|
||||
output = json.loads(r2.vtysh_cmd("show bgp view RS update-groups json"))
|
||||
actual = [
|
||||
subgroup["peers"]
|
||||
for entry in output.get("RS", {}).values()
|
||||
for subgroup in entry["subGroup"]
|
||||
]
|
||||
|
||||
return topotest.json_cmp(actual, expected)
|
||||
|
||||
|
||||
def test_converge_protocols():
|
||||
"Wait for protocol convergence"
|
||||
|
||||
tgen = get_topogen()
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
r2 = tgen.gears["r2"]
|
||||
ref_file = "{}/{}/show_bgp_ipv6_summary.json".format(CWD, r2.name)
|
||||
expected = json.loads(open(ref_file).read())
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
r2,
|
||||
"show bgp view RS ipv6 summary json",
|
||||
expected,
|
||||
)
|
||||
_, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}: BGP convergence failed".format(r2.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
|
||||
def test_bgp_route_server_client_step1():
|
||||
tgen = get_topogen()
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
global link_local_cache
|
||||
link_local_cache = {}
|
||||
router_list = tgen.routers().values()
|
||||
for router in router_list:
|
||||
if router.name == "r2":
|
||||
# route-server
|
||||
cmd = "show bgp view RS ipv6 unicast json"
|
||||
else:
|
||||
cmd = "show bgp ipv6 unicast json"
|
||||
|
||||
# router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name)
|
||||
ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name)
|
||||
expected = json.loads(open(ref_file).read())
|
||||
replace_link_local(expected, link_local_cache)
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
router,
|
||||
cmd,
|
||||
expected,
|
||||
)
|
||||
_, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}: BGP IPv6 table failure".format(router.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
# check r2 sub-groups
|
||||
expected = [["2001:db8:1::4"], ["2001:db8:1::3", "2001:db8:1::2", "2001:db8:3::2"]]
|
||||
|
||||
test_func = functools.partial(check_r2_sub_group, expected)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Peer group split failed"
|
||||
|
||||
|
||||
def test_bgp_route_server_client_step2():
|
||||
tgen = get_topogen()
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
r1 = tgen.gears["r1"]
|
||||
r2 = tgen.gears["r2"]
|
||||
r2.vtysh_cmd(
|
||||
"""
|
||||
configure terminal
|
||||
router bgp 65000 view RS
|
||||
address-family ipv6 unicast
|
||||
neighbor 2001:db8:1::2 nexthop-local unchanged
|
||||
neighbor 2001:db8:1::3 nexthop-local unchanged
|
||||
neighbor 2001:db8:1::4 nexthop-local unchanged
|
||||
neighbor 2001:db8:3::2 nexthop-local unchanged
|
||||
"""
|
||||
)
|
||||
|
||||
def _bgp_converge(router):
|
||||
output = json.loads(router.vtysh_cmd("show bgp ipv6 unicast summary json"))
|
||||
expected = {"peers": {"2001:db8:1::1": {"state": "Established", "pfxRcd": 2}}}
|
||||
return topotest.json_cmp(output, expected)
|
||||
router_list = tgen.routers().values()
|
||||
for router in router_list:
|
||||
if router.name == "r2":
|
||||
# route-server
|
||||
cmd = "show bgp view RS ipv6 unicast json"
|
||||
else:
|
||||
cmd = "show bgp ipv6 unicast json"
|
||||
|
||||
test_func = functools.partial(_bgp_converge, r1)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Cannot see BGP sessions to be up"
|
||||
# router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name)
|
||||
ref_file = "{}/{}/show_bgp_ipv6_step2.json".format(CWD, router.name)
|
||||
expected = json.loads(open(ref_file).read())
|
||||
replace_link_local(expected, link_local_cache)
|
||||
|
||||
def _bgp_prefix_received(router):
|
||||
output = json.loads(router.vtysh_cmd("show bgp 2001:db8:f::3/128 json"))
|
||||
expected = {
|
||||
"prefix": "2001:db8:f::3/128",
|
||||
"paths": [{"nexthops": [{"ip": "2001:db8:3::2"}]}],
|
||||
}
|
||||
return topotest.json_cmp(output, expected)
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
router,
|
||||
cmd,
|
||||
expected,
|
||||
)
|
||||
_, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}: BGP IPv6 table failure".format(router.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
test_func = functools.partial(_bgp_prefix_received, r1)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Cannot see BGP GUA next hop from r3 in r1"
|
||||
|
||||
def _bgp_single_next_hop(router):
|
||||
output = json.loads(router.vtysh_cmd("show bgp 2001:db8:f::3/128 json"))
|
||||
return len(output["paths"][0]["nexthops"])
|
||||
|
||||
assert (
|
||||
_bgp_single_next_hop(r1) == 1
|
||||
), "Not ONLY one Next Hop received for 2001:db8:f::3/128"
|
||||
|
||||
def _bgp_gua_lla_next_hop(router):
|
||||
output = json.loads(router.vtysh_cmd("show bgp view RS 2001:db8:f::3/128 json"))
|
||||
expected = {
|
||||
"prefix": "2001:db8:f::3/128",
|
||||
"paths": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"ip": "2001:db8:3::2",
|
||||
"hostname": "r3",
|
||||
"afi": "ipv6",
|
||||
"scope": "global",
|
||||
},
|
||||
{"hostname": "r3", "afi": "ipv6", "scope": "link-local"},
|
||||
# check r2 sub-groups
|
||||
expected = [
|
||||
["2001:db8:1::4"],
|
||||
["2001:db8:1::3", "2001:db8:1::2"],
|
||||
["2001:db8:3::2"],
|
||||
]
|
||||
}
|
||||
],
|
||||
}
|
||||
return topotest.json_cmp(output, expected)
|
||||
|
||||
test_func = functools.partial(_bgp_gua_lla_next_hop, r2)
|
||||
test_func = functools.partial(check_r2_sub_group, expected)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Cannot see BGP LLA next hop from r3 in r2"
|
||||
assert result is None, "Peer group split failed"
|
||||
|
||||
|
||||
def test_bgp_route_server_client_step3():
|
||||
tgen = get_topogen()
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
r2 = tgen.gears["r2"]
|
||||
r2.vtysh_cmd(
|
||||
"""
|
||||
configure terminal
|
||||
router bgp 65000 view RS
|
||||
address-family ipv6 unicast
|
||||
no neighbor 2001:db8:1::2 nexthop-local unchanged
|
||||
no neighbor 2001:db8:1::3 nexthop-local unchanged
|
||||
no neighbor 2001:db8:1::4 nexthop-local unchanged
|
||||
no neighbor 2001:db8:3::2 nexthop-local unchanged
|
||||
"""
|
||||
)
|
||||
|
||||
global link_local_cache
|
||||
link_local_cache = {}
|
||||
router_list = tgen.routers().values()
|
||||
for router in router_list:
|
||||
if router.name == "r2":
|
||||
# route-server
|
||||
cmd = "show bgp view RS ipv6 unicast json"
|
||||
else:
|
||||
cmd = "show bgp ipv6 unicast json"
|
||||
|
||||
# router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name)
|
||||
ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name)
|
||||
expected = json.loads(open(ref_file).read())
|
||||
replace_link_local(expected, link_local_cache)
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
router,
|
||||
cmd,
|
||||
expected,
|
||||
)
|
||||
_, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}: BGP IPv6 table failure".format(router.name)
|
||||
assert res is None, assertmsg
|
||||
|
||||
# check r2 sub-groups
|
||||
expected = [["2001:db8:1::4"], ["2001:db8:1::3", "2001:db8:1::2", "2001:db8:3::2"]]
|
||||
|
||||
test_func = functools.partial(check_r2_sub_group, expected)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
|
||||
assert result is None, "Peer group split failed"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user