summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2024-10-08 15:04:34 +0200
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2024-10-11 05:36:39 +0000
commitead451f63393b47ca9a6989b3d864b521bdb64f2 (patch)
treee18778b9602a5a3167cc61a9e669dcd964180e56
parent74d91dea4be3812d80ae59bd931428fd2c503e25 (diff)
topotests: add bgp_nexthop_ipv6
Add bgp_nexthop_ipv6 to check the ipv6 link-local nexthop conformity in several situations. Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com> (cherry picked from commit 6dc4d9506181e370680283a4f9ec34d84b06d5e2)
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/exabgp.env53
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf22
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json162
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step2.json162
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r1/zebra.conf14
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf22
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json162
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step2.json162
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r2/zebra.conf14
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r3/exabgp.cfg16
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step1.json0
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step2.json0
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf22
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step1.json210
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json222
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r4/zebra.conf14
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf22
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json222
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json222
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r5/zebra.conf14
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf22
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json162
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step2.json162
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/r6/zebra.conf14
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf30
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step1.json220
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step2.json220
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_summary.json6
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/rr/zebra.conf18
-rw-r--r--tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py263
30 files changed, 2854 insertions, 0 deletions
diff --git a/tests/topotests/bgp_nexthop_ipv6/exabgp.env b/tests/topotests/bgp_nexthop_ipv6/exabgp.env
new file mode 100644
index 0000000000..28e642360a
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/exabgp.env
@@ -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
diff --git a/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf
new file mode 100644
index 0000000000..7efa1b79fa
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r1/bgpd.conf
@@ -0,0 +1,22 @@
+router bgp 65000
+ no bgp ebgp-requires-policy
+ neighbor fd00:0:2::9 remote-as internal
+ neighbor fd00:0:2::9 timers 3 10
+ address-family ipv4 unicast
+ redistribute connected route-map RMAP4
+ !
+ address-family ipv6 unicast
+ redistribute connected route-map RMAP6
+ neighbor fd00:0:2::9 activate
+
+ip prefix-list RANGE4 seq 10 permit 172.16.0.0/16 le 24
+ip prefix-list RANGE4 seq 20 permit 10.0.0.0/8 ge 32
+
+ipv6 prefix-list RANGE6 seq 10 permit fd00:100::0/64
+ipv6 prefix-list RANGE6 seq 20 permit 2001:db8::0/64 ge 128
+
+route-map RMAP4 permit 10
+ match ip address prefix-list RANGE4
+!
+route-map RMAP6 permit 10
+ match ipv6 address prefix-list RANGE6
diff --git a/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..9923edb348
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step1.json
@@ -0,0 +1,162 @@
+{
+ "routerId": "10.1.1.1",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..9923edb348
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r1/show_bgp_ipv6_step2.json
@@ -0,0 +1,162 @@
+{
+ "routerId": "10.1.1.1",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r1/zebra.conf b/tests/topotests/bgp_nexthop_ipv6/r1/zebra.conf
new file mode 100644
index 0000000000..d06a3e194b
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r1/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+ipv6 forwarding
+
+int eth-dummy
+ ip addr 172.16.1.1/24
+ ip addr fd00:100::1/64
+
+int eth-sw
+ ip addr 192.168.2.1/24
+ ipv6 address fd00:0:2::1/64
+
+int lo
+ ip addr 10.1.1.1/32
+ ipv6 address 2001:db8::1/128
diff --git a/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf
new file mode 100644
index 0000000000..4d4ae44e28
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r2/bgpd.conf
@@ -0,0 +1,22 @@
+router bgp 65000
+ no bgp ebgp-requires-policy
+ neighbor fd00:0:2::9 remote-as internal
+ neighbor fd00:0:2::9 timers 3 10
+ address-family ipv4 unicast
+ redistribute connected route-map RMAP4
+ !
+ address-family ipv6 unicast
+ redistribute connected route-map RMAP6
+ neighbor fd00:0:2::9 activate
+
+ip prefix-list RANGE4 seq 10 permit 172.16.0.0/16 le 24
+ip prefix-list RANGE4 seq 20 permit 10.0.0.0/8 ge 32
+
+ipv6 prefix-list RANGE6 seq 10 permit fd00:200::0/64
+ipv6 prefix-list RANGE6 seq 20 permit 2001:db8::0/64 ge 128
+
+route-map RMAP4 permit 10
+ match ip address prefix-list RANGE4
+!
+route-map RMAP6 permit 10
+ match ipv6 address prefix-list RANGE6
diff --git a/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..bb2efa16d9
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step1.json
@@ -0,0 +1,162 @@
+{
+ "routerId": "10.2.2.2",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..bb2efa16d9
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r2/show_bgp_ipv6_step2.json
@@ -0,0 +1,162 @@
+{
+ "routerId": "10.2.2.2",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r2/zebra.conf b/tests/topotests/bgp_nexthop_ipv6/r2/zebra.conf
new file mode 100644
index 0000000000..de8746df98
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r2/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+ipv6 forwarding
+
+int eth-dummy
+ ip addr 172.16.2.2/24
+ ip addr fd00:200::1/64
+
+int eth-sw
+ ip addr 192.168.2.2/24
+ ipv6 address fd00:0:2::2/64
+
+int lo
+ ip addr 10.2.2.2/32
+ ipv6 address 2001:db8::2/128 \ No newline at end of file
diff --git a/tests/topotests/bgp_nexthop_ipv6/r3/exabgp.cfg b/tests/topotests/bgp_nexthop_ipv6/r3/exabgp.cfg
new file mode 100644
index 0000000000..373169bcba
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r3/exabgp.cfg
@@ -0,0 +1,16 @@
+neighbor fd00:0:2::9 {
+ router-id 10.3.3.3;
+ local-address fd00:0:2::3;
+ local-as 65000;
+ peer-as 65000;
+
+ family {
+ ipv6 unicast;
+ }
+
+ static {
+ route fd00:300::0/64 next-hop fd00:0:2::3;
+ route 2001:db8::3/128 next-hop fd00:0:2::3;
+ }
+ hold-time 10;
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step1.json
diff --git a/tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r3/show_bgp_ipv6_step2.json
diff --git a/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf
new file mode 100644
index 0000000000..b14c9bace4
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r4/bgpd.conf
@@ -0,0 +1,22 @@
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor fd00:0:2::9 remote-as external
+ neighbor fd00:0:2::9 timers 3 10
+ address-family ipv4 unicast
+ redistribute connected route-map RMAP4
+ !
+ address-family ipv6 unicast
+ redistribute connected route-map RMAP6
+ neighbor fd00:0:2::9 activate
+
+ip prefix-list RANGE4 seq 10 permit 172.16.0.0/16 le 24
+ip prefix-list RANGE4 seq 20 permit 10.0.0.0/8 ge 32
+
+ipv6 prefix-list RANGE6 seq 10 permit fd00:400::0/64
+ipv6 prefix-list RANGE6 seq 20 permit 2001:db8::0/64 ge 128
+
+route-map RMAP4 permit 10
+ match ip address prefix-list RANGE4
+!
+route-map RMAP6 permit 10
+ match ipv6 address prefix-list RANGE6
diff --git a/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..dd8603f4e3
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step1.json
@@ -0,0 +1,210 @@
+{
+ "routerId": "10.4.4.4",
+ "localAS": 65001,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r1:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r2:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r1:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r2:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..35a31e63f9
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r4/show_bgp_ipv6_step2.json
@@ -0,0 +1,222 @@
+{
+ "routerId": "10.4.4.4",
+ "localAS": 65001,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-sw",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r4/zebra.conf b/tests/topotests/bgp_nexthop_ipv6/r4/zebra.conf
new file mode 100644
index 0000000000..edc39684e1
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r4/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+ipv6 forwarding
+
+int eth-dummy
+ ip addr 172.16.4.4/24
+ ip addr fd00:400::4/64
+
+int eth-sw
+ ip addr 192.168.2.4/24
+ ipv6 address fd00:0:2::4/64
+
+int lo
+ ip addr 10.4.4.4/32
+ ipv6 address 2001:db8::4/128 \ No newline at end of file
diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf
new file mode 100644
index 0000000000..becea2bbe6
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r5/bgpd.conf
@@ -0,0 +1,22 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor fd00:0:3::9 remote-as external
+ neighbor fd00:0:3::9 timers 3 10
+ address-family ipv4 unicast
+ redistribute connected route-map RMAP4
+ !
+ address-family ipv6 unicast
+ redistribute connected route-map RMAP6
+ neighbor fd00:0:3::9 activate
+
+ip prefix-list RANGE4 seq 10 permit 172.16.0.0/16 le 24
+ip prefix-list RANGE4 seq 20 permit 10.0.0.0/8 ge 32
+
+ipv6 prefix-list RANGE6 seq 10 permit fd00:500::0/64
+ipv6 prefix-list RANGE6 seq 20 permit 2001:db8::0/64 ge 128
+
+route-map RMAP4 permit 10
+ match ip address prefix-list RANGE4
+!
+route-map RMAP6 permit 10
+ match ipv6 address prefix-list RANGE6
diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..d0875474ae
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step1.json
@@ -0,0 +1,222 @@
+{
+ "routerId": "10.5.5.5",
+ "localAS": 65002,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..d0875474ae
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r5/show_bgp_ipv6_step2.json
@@ -0,0 +1,222 @@
+{
+ "routerId": "10.5.5.5",
+ "localAS": 65002,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::9",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:rr:eth-r5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r5/zebra.conf b/tests/topotests/bgp_nexthop_ipv6/r5/zebra.conf
new file mode 100644
index 0000000000..d278889ed9
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r5/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+ipv6 forwarding
+
+int eth-dummy
+ ip addr 172.16.5.5/24
+ ip addr fd00:500::5/64
+
+int eth-rr
+ ip addr 192.168.3.5/24
+ ipv6 address fd00:0:3::5/64
+
+int lo
+ ip addr 10.5.5.5/32
+ ipv6 address 2001:db8::5/128
diff --git a/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf
new file mode 100644
index 0000000000..801736ab98
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r6/bgpd.conf
@@ -0,0 +1,22 @@
+router bgp 65000
+ no bgp ebgp-requires-policy
+ neighbor fd00:0:4::9 remote-as internal
+ neighbor fd00:0:4::9 timers 3 10
+ address-family ipv4 unicast
+ redistribute connected route-map RMAP4
+ !
+ address-family ipv6 unicast
+ redistribute connected route-map RMAP6
+ neighbor fd00:0:4::9 activate
+
+ip prefix-list RANGE4 seq 10 permit 172.16.0.0/16 le 24
+ip prefix-list RANGE4 seq 20 permit 10.0.0.0/8 ge 32
+
+ipv6 prefix-list RANGE6 seq 10 permit fd00:600::0/64
+ipv6 prefix-list RANGE6 seq 20 permit 2001:db8::0/64 ge 128
+
+route-map RMAP4 permit 10
+ match ip address prefix-list RANGE4
+!
+route-map RMAP6 permit 10
+ match ipv6 address prefix-list RANGE6
diff --git a/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..cd48dd4697
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step1.json
@@ -0,0 +1,162 @@
+{
+ "routerId": "10.6.6.6",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..cd48dd4697
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r6/show_bgp_ipv6_step2.json
@@ -0,0 +1,162 @@
+{
+ "routerId": "10.6.6.6",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "rr",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/r6/zebra.conf b/tests/topotests/bgp_nexthop_ipv6/r6/zebra.conf
new file mode 100644
index 0000000000..84bbb95a83
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/r6/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+ipv6 forwarding
+
+int eth-dummy
+ ip addr 172.16.6.6/24
+ ip addr fd00:600::6/64
+
+int eth-rr
+ ip addr 192.168.4.6/24
+ ipv6 address fd00:0:4::6/64
+
+int lo
+ ip addr 10.6.6.6/32
+ ipv6 address 2001:db8::6/128
diff --git a/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf b/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf
new file mode 100644
index 0000000000..6dcded1525
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/rr/bgpd.conf
@@ -0,0 +1,30 @@
+router bgp 65000
+ no bgp ebgp-requires-policy
+ neighbor fd00:0:2::1 remote-as internal
+ neighbor fd00:0:2::1 timers 3 10
+ neighbor fd00:0:2::2 remote-as internal
+ neighbor fd00:0:2::2 timers 3 10
+ neighbor fd00:0:2::3 remote-as internal
+ neighbor fd00:0:2::3 timers 3 10
+ neighbor fd00:0:2::4 remote-as external
+ neighbor fd00:0:2::4 timers 3 10
+ neighbor fd00:0:3::5 remote-as external
+ neighbor fd00:0:3::5 timers 3 10
+ neighbor fd00:0:4::6 remote-as internal
+ neighbor fd00:0:4::6 timers 3 10
+ address-family ipv4 unicast
+ neighbor fd00:0:2::1 route-reflector-client
+ neighbor fd00:0:2::2 route-reflector-client
+ neighbor fd00:0:2::3 route-reflector-client
+ 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 activate
+ neighbor fd00:0:2::2 route-reflector-client
+ neighbor fd00:0:2::2 activate
+ neighbor fd00:0:2::3 route-reflector-client
+ 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 activate
+ neighbor fd00:0:4::6 activate
diff --git a/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step1.json
new file mode 100644
index 0000000000..c8b8e1e893
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step1.json
@@ -0,0 +1,220 @@
+{
+ "routerId": "10.9.9.9",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r1:eth-sw",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r2:eth-sw",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r4:eth-sw",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r5:eth-rr",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r6:eth-rr",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r1:eth-sw",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r2:eth-sw",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r4:eth-sw",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r5:eth-rr",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r6:eth-rr",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step2.json
new file mode 100644
index 0000000000..c8b8e1e893
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_step2.json
@@ -0,0 +1,220 @@
+{
+ "routerId": "10.9.9.9",
+ "localAS": 65000,
+ "routes": {
+ "2001:db8::1/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r1:eth-sw",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::2/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r2:eth-sw",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::3/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::4/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r4:eth-sw",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::5/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r5:eth-rr",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:db8::6/128": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r6:eth-rr",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:100::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r1:eth-sw",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:200::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r2:eth-sw",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:300::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::3",
+ "afi": "ipv6",
+ "scope": "global",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:400::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:2::4",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r4:eth-sw",
+ "hostname": "r4",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:500::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:3::5",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r5:eth-rr",
+ "hostname": "r5",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "fd00:600::/64": [
+ {
+ "nexthops": [
+ {
+ "ip": "fd00:0:4::6",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "ip": "link-local:r6:eth-rr",
+ "hostname": "r6",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_summary.json b/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_summary.json
new file mode 100644
index 0000000000..ceac91215d
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/rr/show_bgp_ipv6_summary.json
@@ -0,0 +1,6 @@
+{
+ "ipv6Unicast": {
+ "failedPeers": 0,
+ "totalPeers": 6
+ }
+}
diff --git a/tests/topotests/bgp_nexthop_ipv6/rr/zebra.conf b/tests/topotests/bgp_nexthop_ipv6/rr/zebra.conf
new file mode 100644
index 0000000000..21d44f3a15
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/rr/zebra.conf
@@ -0,0 +1,18 @@
+ip forwarding
+ipv6 forwarding
+
+int eth-sw
+ ip addr 192.168.2.9/24
+ ipv6 address fd00:0:2::9/64
+
+int eth-r5
+ ip addr 192.168.3.9/24
+ ipv6 address fd00:0:3::9/64
+
+int eth-r6
+ ip addr 192.168.4.9/24
+ ipv6 address fd00:0:4::9/64
+
+int lo
+ ip addr 10.9.9.9/32
+ ipv6 address 2001:db8::9/128
diff --git a/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py b/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py
new file mode 100644
index 0000000000..24d71f5622
--- /dev/null
+++ b/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py
@@ -0,0 +1,263 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+#
+# test_bgp_nexthop_ipv6_topo1.py
+#
+# Copyright (c) 2024 by
+# Cumulus Networks, Inc.
+# 6WIND S.A.
+#
+
+"""
+Ensure that BGP ipv6 nexthops are correct
+"""
+
+import os
+import sys
+import pytest
+from functools import partial
+import json
+
+# 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
+
+# Required to instantiate the topology builder class.
+
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+ """
+ All peers are FRR BGP peers except r3 that is a exabgp peer.
+ rr is a route-reflector for AS 65000 iBGP peers.
+ Exabgp does not send any IPv6 Link-Local nexthop
+
+ iBGP peers | eBGP peers
+ |
+ AS 65000 |
+ |
+ +---+ |
+ | r6| |
+ +---+ |
+ | |
+ fd00:0:3::0/64 |
+ | | AS 65002
+ +---+ | +---+
+ |rr |----fd00:0:4::0/64---| r5|
+ +---+ |_________+---+
+ | | +---+
+ fd00:0:2::0/64----------------| r4|
+ / | \ | +---+
+ +---+ +---+ +---+ | AS 65001
+ | r1| | r2| |r3 | |
+ +---+ +---+ +---+
+ """
+
+ def connect_routers(tgen, left, right):
+ for rname in [left, right]:
+ if rname not in tgen.routers().keys():
+ tgen.add_router(rname)
+
+ switch = tgen.add_switch("s-{}-{}".format(left, right))
+ switch.add_link(tgen.gears[left], nodeif="eth-{}".format(right))
+ switch.add_link(tgen.gears[right], nodeif="eth-{}".format(left))
+
+ def connect_switchs(tgen, rname, switch):
+ if rname not in tgen.routers().keys():
+ tgen.add_router(rname)
+
+ switch.add_link(tgen.gears[rname], nodeif="eth-{}".format(switch.name))
+
+ def connect_dummy(tgen, rname, switch):
+ if rname not in tgen.routers().keys():
+ tgen.add_router(rname)
+
+ switch.add_link(tgen.gears[rname], nodeif="eth-dummy")
+
+ # sw_du switch is for a dummy interface (for local network)
+ for i in range(1, 7):
+ if i == 3:
+ # r3 is an exabgp peer
+ continue
+ sw_du = tgen.add_switch("sw%s" % i)
+ connect_dummy(tgen, "r%s" % i, sw_du)
+
+ # sw switch is for interconnecting peers on the same subnet
+ sw = tgen.add_switch("sw")
+ connect_switchs(tgen, "rr", sw)
+ connect_switchs(tgen, "r1", sw)
+ connect_switchs(tgen, "r2", sw)
+ connect_switchs(tgen, "r4", sw)
+
+ # directly connected without switch routers
+ connect_routers(tgen, "rr", "r5")
+ connect_routers(tgen, "rr", "r6")
+
+ ## Add iBGP ExaBGP neighbor
+ peer_ip = "fd00:0:2::3" ## peer
+ peer_route = "via fd00:0:2::9" ## router
+ r3 = tgen.add_exabgp_peer("r3", ip=peer_ip, defaultRoute=peer_route)
+ sw.add_link(r3)
+
+
+#####################################################
+##
+## Tests starting
+##
+#####################################################
+
+
+def setup_module(module):
+ "Setup topology"
+ tgen = Topogen(build_topo, module.__name__)
+ tgen.start_topology()
+
+ # This is a sample of configuration loading.
+ 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_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+ # Start r3 exabgp peer
+ r3 = tgen.gears["r3"]
+ r3.start(os.path.join(CWD, "r3"), os.path.join(CWD, "exabgp.env"))
+
+
+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_info in expected.get("routes", {}).items():
+ for nexthop in prefix_info[0].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 teardown_module(_mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ tgen.stop_topology()
+
+
+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)
+
+ rr = tgen.gears["rr"]
+ ref_file = "{}/{}/show_bgp_ipv6_summary.json".format(CWD, rr.name)
+ expected = json.loads(open(ref_file).read())
+
+ test_func = partial(
+ topotest.router_json_cmp,
+ rr,
+ "show bgp ipv6 summary json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assertmsg = "{}: BGP convergence".format(rr.name)
+ assert res is None, assertmsg
+
+
+def test_bgp_ipv6_table_step1():
+ tgen = get_topogen()
+
+ # Don't run this test if we have any failure.
+ 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:
+ # 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
+
+
+def test_bgp_ipv6_table_step2():
+ 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
+ no neighbor fd00:0:2::4 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_step2.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
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))