summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json34
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json43
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json36
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json45
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json36
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json45
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json28
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json34
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json30
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json36
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json30
-rw-r--r--tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json36
-rw-r--r--tests/topotests/bgp_bmp/r1/bgpd.conf14
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json21
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json25
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json6
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json10
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json27
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json25
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json6
-rw-r--r--tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json10
-rw-r--r--tests/topotests/bgp_bmp/test_bgp_bmp.py310
-rw-r--r--tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-loc-rib-step1.json32
-rw-r--r--tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-post-policy-step1.json36
-rw-r--r--tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-pre-policy-step1.json36
-rw-r--r--tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-loc-rib-step1.json26
-rw-r--r--tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-post-policy-step1.json30
-rw-r--r--tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-pre-policy-step1.json30
-rw-r--r--tests/topotests/bgp_bmp_vrf/r1/bgpd.conf6
-rw-r--r--tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-update-step1.json21
-rw-r--r--tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-withdraw-step1.json6
-rw-r--r--tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-update-step1.json27
-rw-r--r--tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-withdraw-step1.json6
-rw-r--r--tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py220
34 files changed, 1200 insertions, 163 deletions
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json
new file mode 100644
index 0000000000..27f1fe6e27
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step1.json
@@ -0,0 +1,34 @@
+{
+ "loc-rib": {
+ "update": {
+ "172.31.0.15/32": {
+ "as_path": "65501 65502",
+ "bgp_nexthop": "192.168.0.2",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "is_filtered": false,
+ "origin": "IGP",
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib"
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2001::1111/128",
+ "is_filtered": false,
+ "nxhp_ip": "192:168::2",
+ "origin": "IGP",
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json
new file mode 100644
index 0000000000..0aa6bd4fea
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-loc-rib-step2.json
@@ -0,0 +1,43 @@
+{
+ "loc-rib": {
+ "update": {
+ "2001::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2001::1111/128",
+ "is_filtered": false,
+ "label": 105,
+ "nxhp_ip": "192:168::2",
+ "nxhp_rd1": "0:0",
+ "nxhp_rd2": "0:0",
+ "origin": "IGP",
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "rd": "555:2",
+ "safi": 128
+ },
+ "172.31.0.15/32": {
+ "afi": 1,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "is_filtered": false,
+ "label": 102,
+ "nxhp_ip": "192.168.0.2",
+ "nxhp_rd": "0:0",
+ "origin": "IGP",
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "rd": "444:2",
+ "safi": 128
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json
new file mode 100644
index 0000000000..d30ef9fd32
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step1.json
@@ -0,0 +1,36 @@
+{
+ "post-policy": {
+ "update": {
+ "172.31.0.15/32": {
+ "as_path": "65501 65502",
+ "bgp_nexthop": "192.168.0.2",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "post-policy"
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "nxhp_ip": "192:168::2",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json
new file mode 100644
index 0000000000..9bf2d57769
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-post-policy-step2.json
@@ -0,0 +1,45 @@
+{
+ "post-policy": {
+ "update": {
+ "172.31.0.15/32": {
+ "afi": 1,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "label": 102,
+ "nxhp_ip": "192.168.0.2",
+ "nxhp_rd": "0:0",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "rd": "444:2",
+ "safi": 128
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "label": 105,
+ "nxhp_ip": "192:168::2",
+ "nxhp_rd1": "0:0",
+ "nxhp_rd2": "0:0",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "rd": "555:2",
+ "safi": 128
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json
new file mode 100644
index 0000000000..fafe6f7c21
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step1.json
@@ -0,0 +1,36 @@
+{
+ "pre-policy": {
+ "update": {
+ "172.31.0.15/32": {
+ "as_path": "65501 65502",
+ "bgp_nexthop": "192.168.0.2",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "pre-policy"
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "nxhp_ip": "192:168::2",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json
new file mode 100644
index 0000000000..95acb5903a
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-update-pre-policy-step2.json
@@ -0,0 +1,45 @@
+{
+ "pre-policy": {
+ "update": {
+ "172.31.0.15/32": {
+ "afi": 1,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "label": 102,
+ "nxhp_ip": "192.168.0.2",
+ "nxhp_rd": "0:0",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "rd": "444:2",
+ "safi": 128
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "label": 105,
+ "nxhp_ip": "192:168::2",
+ "nxhp_rd1": "0:0",
+ "nxhp_rd2": "0:0",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "rd": "555:2",
+ "safi": 128
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json
new file mode 100644
index 0000000000..3891fbb15e
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step1.json
@@ -0,0 +1,28 @@
+{
+ "loc-rib": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "is_filtered": false,
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib"
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2001::1111/128",
+ "is_filtered": false,
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json
new file mode 100644
index 0000000000..1e5040ba60
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-loc-rib-step2.json
@@ -0,0 +1,34 @@
+{
+ "loc-rib": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "afi": 1,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "is_filtered": false,
+ "label": 0,
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "rd": "444:2",
+ "safi": 128
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2001::1111/128",
+ "is_filtered": false,
+ "label": 0,
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_distinguisher": "0:0",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "rd": "555:2",
+ "safi": 128
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json
new file mode 100644
index 0000000000..3224b525e2
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step1.json
@@ -0,0 +1,30 @@
+{
+ "post-policy": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "post-policy"
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json
new file mode 100644
index 0000000000..9eb221d4d0
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-post-policy-step2.json
@@ -0,0 +1,36 @@
+{
+ "post-policy": {
+ "withdraw": {
+ "2001::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "label": 0,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "rd": "555:2",
+ "safi": 128
+ },
+ "172.31.0.15/32": {
+ "afi": 1,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "label": 0,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "rd": "444:2",
+ "safi": 128
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json
new file mode 100644
index 0000000000..8add68c022
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step1.json
@@ -0,0 +1,30 @@
+{
+ "pre-policy": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "pre-policy"
+ },
+ "2001::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json
new file mode 100644
index 0000000000..eea7501b22
--- /dev/null
+++ b/tests/topotests/bgp_bmp/bmp1/bmp-withdraw-pre-policy-step2.json
@@ -0,0 +1,36 @@
+{
+ "pre-policy": {
+ "withdraw": {
+ "2001::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2001::1111/128",
+ "ipv6": true,
+ "label": 0,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "rd": "555:2",
+ "safi": 128
+ },
+ "172.31.0.15/32": {
+ "afi": 1,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "label": 0,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "rd": "444:2",
+ "safi": 128
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp/r1/bgpd.conf b/tests/topotests/bgp_bmp/r1/bgpd.conf
index 24505de4a8..485c217096 100644
--- a/tests/topotests/bgp_bmp/r1/bgpd.conf
+++ b/tests/topotests/bgp_bmp/r1/bgpd.conf
@@ -7,6 +7,18 @@ router bgp 65501
!
bmp targets bmp1
bmp connect 192.0.2.10 port 1789 min-retry 100 max-retry 10000
+ bmp monitor ipv4 unicast pre-policy
+ bmp monitor ipv6 unicast pre-policy
+ bmp monitor ipv4 vpn pre-policy
+ bmp monitor ipv6 vpn pre-policy
+ bmp monitor ipv4 unicast post-policy
+ bmp monitor ipv6 unicast post-policy
+ bmp monitor ipv4 vpn post-policy
+ bmp monitor ipv6 vpn post-policy
+ bmp monitor ipv4 unicast loc-rib
+ bmp monitor ipv6 unicast loc-rib
+ bmp monitor ipv4 vpn loc-rib
+ bmp monitor ipv6 vpn loc-rib
exit
!
address-family ipv4 vpn
@@ -28,7 +40,7 @@ router bgp 65501
neighbor 192:168::2 soft-reconfiguration inbound
exit-address-family
!
-router bgp 65502 vrf vrf1
+router bgp 65501 vrf vrf1
bgp router_id 192.168.0.1
bgp log-neighbor-changes
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json
new file mode 100644
index 0000000000..038c87ca9d
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step1.json
@@ -0,0 +1,21 @@
+{
+ "routes": {
+ "172.31.0.15/32": [
+ {
+ "bestpath": true,
+ "pathFrom": "external",
+ "path": "65502",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "192.168.0.2",
+ "hostname": "r2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json
new file mode 100644
index 0000000000..275f7f30e9
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-update-step2.json
@@ -0,0 +1,25 @@
+{
+ "routes": {
+ "routeDistinguishers": {
+ "444:2": {
+ "172.31.0.15/32": [
+ {
+ "bestpath": true,
+ "pathFrom": "external",
+ "path": "65502",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "192.168.0.2",
+ "hostname": "r2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json
new file mode 100644
index 0000000000..22a6c605c1
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step1.json
@@ -0,0 +1,6 @@
+{
+ "routes": {
+ "2001::1111/128": null
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json
new file mode 100644
index 0000000000..0f930ee71f
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv4-withdraw-step2.json
@@ -0,0 +1,10 @@
+{
+ "routes": {
+ "routeDistinguishers": {
+ "444:2": {
+ "2001::1111/128": null
+ }
+ }
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json
new file mode 100644
index 0000000000..ed5cea68ce
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step1.json
@@ -0,0 +1,27 @@
+{
+ "routes": {
+ "2001::1111/128": [
+ {
+ "bestpath": true,
+ "pathFrom": "external",
+ "path": "65502",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "192:168::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json
new file mode 100644
index 0000000000..c4c0c16284
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-update-step2.json
@@ -0,0 +1,25 @@
+{
+ "routes": {
+ "routeDistinguishers": {
+ "555:2": {
+ "2001::1111/128": [
+ {
+ "bestpath": true,
+ "pathFrom": "external",
+ "path": "65502",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "192:168::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json
new file mode 100644
index 0000000000..22a6c605c1
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step1.json
@@ -0,0 +1,6 @@
+{
+ "routes": {
+ "2001::1111/128": null
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json
new file mode 100644
index 0000000000..7b652afca6
--- /dev/null
+++ b/tests/topotests/bgp_bmp/r1/show-bgp-ipv6-withdraw-step2.json
@@ -0,0 +1,10 @@
+{
+ "routes": {
+ "routeDistinguishers": {
+ "555:2": {
+ "2001::1111/128": null
+ }
+ }
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp.py b/tests/topotests/bgp_bmp/test_bgp_bmp.py
index 1cf6a0e7f8..658ad2b99a 100644
--- a/tests/topotests/bgp_bmp/test_bgp_bmp.py
+++ b/tests/topotests/bgp_bmp/test_bgp_bmp.py
@@ -50,6 +50,9 @@ PRE_POLICY = "pre-policy"
POST_POLICY = "post-policy"
LOC_RIB = "loc-rib"
+UPDATE_EXPECTED_JSON = False
+DEBUG_PCAP = False
+
def build_topo(tgen):
tgen.add_router("r1")
@@ -67,6 +70,12 @@ def setup_module(mod):
tgen = Topogen(build_topo, mod.__name__)
tgen.start_topology()
+ if DEBUG_PCAP:
+ tgen.gears["r1"].run("rm /tmp/bmp.pcap")
+ tgen.gears["r1"].run(
+ "tcpdump -nni r1-eth0 -s 0 -w /tmp/bmp.pcap &", stdout=None
+ )
+
for rname, router in tgen.routers().items():
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
@@ -122,42 +131,181 @@ def get_bmp_messages():
return messages
-def check_for_prefixes(expected_prefixes, bmp_log_type, policy, labels=None):
+def update_seq():
+ global SEQ
+
+ messages = get_bmp_messages()
+
+ if len(messages):
+ SEQ = messages[-1]["seq"]
+
+
+def update_expected_files(bmp_actual, expected_prefixes, bmp_log_type, policy, step):
+ tgen = get_topogen()
+
+ with open(f"/tmp/bmp-{bmp_log_type}-{policy}-step{step}.json", "w") as json_file:
+ json.dump(bmp_actual, json_file, indent=4)
+
+ if step == 2: # vpn
+ rd = "444:2"
+ out = tgen.gears["r1"].vtysh_cmd("show bgp ipv4 vpn json", isjson=True)
+ filtered_out = {
+ "routes": {
+ "routeDistinguishers": {
+ rd: {
+ prefix: route_info
+ for prefix, route_info in out["routes"]
+ .get("routeDistinguishers", {})
+ .get(rd, {})
+ .items()
+ if prefix in expected_prefixes
+ }
+ }
+ }
+ }
+ if bmp_log_type == "withdraw":
+ for pfx in expected_prefixes:
+ if "::" in pfx:
+ continue
+ filtered_out["routes"]["routeDistinguishers"][rd][pfx] = None
+
+ # ls /tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done
+ with open(
+ f"/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w"
+ ) as json_file:
+ json.dump(filtered_out, json_file, indent=4)
+
+ rd = "555:2"
+ out = tgen.gears["r1"].vtysh_cmd("show bgp ipv6 vpn json", isjson=True)
+ filtered_out = {
+ "routes": {
+ "routeDistinguishers": {
+ rd: {
+ prefix: route_info
+ for prefix, route_info in out["routes"]
+ .get("routeDistinguishers", {})
+ .get(rd, {})
+ .items()
+ if prefix in expected_prefixes
+ }
+ }
+ }
+ }
+ if bmp_log_type == "withdraw":
+ for pfx in expected_prefixes:
+ if "::" not in pfx:
+ continue
+ filtered_out["routes"]["routeDistinguishers"][rd][pfx] = None
+ with open(
+ f"/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w"
+ ) as json_file:
+ json.dump(filtered_out, json_file, indent=4)
+
+ return
+
+ out = tgen.gears["r1"].vtysh_cmd("show bgp ipv4 json", isjson=True)
+ filtered_out = {
+ "routes": {
+ prefix: route_info
+ for prefix, route_info in out["routes"].items()
+ if prefix in expected_prefixes
+ }
+ }
+ if bmp_log_type == "withdraw":
+ for pfx in expected_prefixes:
+ if "::" in pfx:
+ continue
+ filtered_out["routes"][pfx] = None
+
+ # ls /tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done
+ with open(f"/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w") as json_file:
+ json.dump(filtered_out, json_file, indent=4)
+
+ out = tgen.gears["r1"].vtysh_cmd("show bgp ipv6 json", isjson=True)
+ filtered_out = {
+ "routes": {
+ prefix: route_info
+ for prefix, route_info in out["routes"].items()
+ if prefix in expected_prefixes
+ }
+ }
+ if bmp_log_type == "withdraw":
+ for pfx in expected_prefixes:
+ if "::" not in pfx:
+ continue
+ filtered_out["routes"][pfx] = None
+ with open(f"/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w") as json_file:
+ json.dump(filtered_out, json_file, indent=4)
+
+
+def check_for_prefixes(expected_prefixes, bmp_log_type, policy, step):
"""
Check for the presence of the given prefixes in the BMP server logs with
the given message type and the set policy.
+
"""
global SEQ
+
# we care only about the new messages
messages = [
m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ
]
- # get the list of pairs (prefix, policy, seq) for the given message type
- prefixes = [
- m["ip_prefix"]
- for m in messages
- if "ip_prefix" in m.keys()
- and "bmp_log_type" in m.keys()
- and m["bmp_log_type"] == bmp_log_type
- and m["policy"] == policy
- and (
- labels is None
- or (
- m["ip_prefix"] in labels.keys() and m["label"] == labels[m["ip_prefix"]]
- )
- )
- ]
-
- # check for prefixes
- for ep in expected_prefixes:
- if ep not in prefixes:
- msg = "The prefix {} is not present in the {} log messages."
- logger.debug(msg.format(ep, bmp_log_type))
- return False
-
- SEQ = messages[-1]["seq"]
- return True
+ # create empty initial files
+ # for step in $(seq 2); do
+ # for i in "update" "withdraw"; do
+ # for j in "pre-policy" "post-policy" "loc-rib"; do
+ # echo '{"null": {}}'> bmp-$i-$j-step$step.json
+ # done
+ # done
+ # done
+
+ ref_file = f"{CWD}/bmp1/bmp-{bmp_log_type}-{policy}-step{step}.json"
+ expected = json.loads(open(ref_file).read())
+
+ # Build actual json from logs
+ actual = {}
+ for m in messages:
+ if (
+ "bmp_log_type" in m.keys()
+ and "ip_prefix" in m.keys()
+ and m["ip_prefix"] in expected_prefixes
+ and m["bmp_log_type"] == bmp_log_type
+ and m["policy"] == policy
+ ):
+ policy_dict = actual.setdefault(m["policy"], {})
+ bmp_log_type_dict = policy_dict.setdefault(m["bmp_log_type"], {})
+
+ # Add or update the ip_prefix dictionary with filtered key-value pairs
+ bmp_log_type_dict[m["ip_prefix"]] = {
+ k: v
+ for k, v in sorted(m.items())
+ # filter out variable keys
+ if k not in ["timestamp", "seq", "nxhp_link-local"]
+ and (
+ # When policy is loc-rib, the peer-distinguisher is 0:0
+ # for the default VRF or the RD if any or the 0:<vrf_id>.
+ # 0:<vrf_id> is used to distinguished. RFC7854 says: "If the
+ # peer is a "Local Instance Peer", it is set to a unique,
+ # locally defined value." The value is not tested because it
+ # is variable.
+ k != "peer_distinguisher"
+ or policy != LOC_RIB
+ or v == "0:0"
+ or not v.startswith("0:")
+ )
+ }
+
+ # build expected JSON files
+ if (
+ UPDATE_EXPECTED_JSON
+ and actual
+ and set(actual.get(policy, {}).get(bmp_log_type, {}).keys())
+ == set(expected_prefixes)
+ ):
+ update_expected_files(actual, expected_prefixes, bmp_log_type, policy, step)
+
+ return topotest.json_cmp(actual, expected, exact=True)
def check_for_peer_message(expected_peers, bmp_log_type):
@@ -188,22 +336,6 @@ def check_for_peer_message(expected_peers, bmp_log_type):
return True
-def set_bmp_policy(tgen, node, asn, target, safi, policy, vrf=None):
- """
- Configure the bmp policy.
- """
- vrf = " vrf {}" if vrf else ""
- cmd = [
- "con t\n",
- "router bgp {}{}\n".format(asn, vrf),
- "bmp targets {}\n".format(target),
- "bmp monitor ipv4 {} {}\n".format(safi, policy),
- "bmp monitor ipv6 {} {}\n".format(safi, policy),
- "end\n",
- ]
- tgen.gears[node].vtysh_cmd("".join(cmd))
-
-
def configure_prefixes(tgen, node, asn, safi, prefixes, vrf=None, update=True):
"""
Configure the bgp prefixes.
@@ -223,67 +355,49 @@ def configure_prefixes(tgen, node, asn, safi, prefixes, vrf=None, update=True):
tgen.gears[node].vtysh_cmd("".join(cmd))
-def unicast_prefixes(policy):
+def _test_prefixes(policy, vrf=None, step=0):
"""
Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes.
Check if the previous actions are logged in the BMP server with the right
message type and the right policy.
"""
tgen = get_topogen()
- set_bmp_policy(tgen, "r1", 65501, "bmp1", "unicast", policy)
- prefixes = ["172.31.0.15/32", "2111::1111/128"]
- # add prefixes
- configure_prefixes(tgen, "r2", 65502, "unicast", prefixes)
+ safi = "vpn" if vrf else "unicast"
- logger.info("checking for updated prefixes")
- # check
- test_func = partial(check_for_prefixes, prefixes, "update", policy)
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
- assert success, "Checking the updated prefixes has been failed !."
-
- # withdraw prefixes
- configure_prefixes(tgen, "r2", 65502, "unicast", prefixes, update=False)
- logger.info("checking for withdrawed prefxies")
- # check
- test_func = partial(check_for_prefixes, prefixes, "withdraw", policy)
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
- assert success, "Checking the withdrawed prefixes has been failed !."
+ prefixes = ["172.31.0.15/32", "2001::1111/128"]
+ for type in ("update", "withdraw"):
+ update_seq()
-def vpn_prefixes(policy):
- """
- Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes.
- Check if the previous actions are logged in the BMP server with the right
- message type and the right policy.
- """
- tgen = get_topogen()
- set_bmp_policy(tgen, "r1", 65501, "bmp1", "vpn", policy)
-
- prefixes = ["172.31.10.1/32", "2001::2222/128"]
+ configure_prefixes(
+ tgen, "r2", 65502, "unicast", prefixes, vrf=vrf, update=(type == "update")
+ )
- # "label vpn export" value in r2/bgpd.conf
- labels = {
- "172.31.10.1/32": 102,
- "2001::2222/128": 105,
- }
+ logger.info(f"checking for prefixes {type}")
- # add prefixes
- configure_prefixes(tgen, "r2", 65502, "unicast", prefixes, vrf="vrf1")
+ for ipver in [4, 6]:
+ if UPDATE_EXPECTED_JSON:
+ continue
+ ref_file = "{}/r1/show-bgp-ipv{}-{}-step{}.json".format(
+ CWD, ipver, type, step
+ )
+ expected = json.loads(open(ref_file).read())
- logger.info("checking for updated prefixes")
- # check
- test_func = partial(check_for_prefixes, prefixes, "update", policy, labels=labels)
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
- assert success, "Checking the updated prefixes has been failed !."
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears["r1"],
+ f"show bgp ipv{ipver} {safi} json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assertmsg = f"r1: BGP IPv{ipver} convergence failed"
+ assert res is None, assertmsg
- # withdraw prefixes
- configure_prefixes(tgen, "r2", 65502, "unicast", prefixes, vrf="vrf1", update=False)
- logger.info("checking for withdrawed prefixes")
- # check
- test_func = partial(check_for_prefixes, prefixes, "withdraw", policy)
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
- assert success, "Checking the withdrawed prefixes has been failed !."
+ # check
+ test_func = partial(check_for_prefixes, prefixes, type, policy, step)
+ success, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert success, "Checking the updated prefixes has failed ! %s" % res
def test_bmp_server_logging():
@@ -300,7 +414,7 @@ def test_bmp_server_logging():
return False
return True
- success, _ = topotest.run_and_expect(check_for_log_file, True, wait=0.5)
+ success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1)
assert success, "The BMP server is not logging"
@@ -314,7 +428,7 @@ def test_peer_up():
logger.info("checking for BMP peers up messages")
test_func = partial(check_for_peer_message, peers, "peer up")
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
+ success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1)
assert success, "Checking the updated prefixes has been failed !."
@@ -323,21 +437,21 @@ def test_bmp_bgp_unicast():
Add/withdraw bgp unicast prefixes and check the bmp logs.
"""
logger.info("*** Unicast prefixes pre-policy logging ***")
- unicast_prefixes(PRE_POLICY)
+ _test_prefixes(PRE_POLICY, step=1)
logger.info("*** Unicast prefixes post-policy logging ***")
- unicast_prefixes(POST_POLICY)
+ _test_prefixes(POST_POLICY, step=1)
logger.info("*** Unicast prefixes loc-rib logging ***")
- unicast_prefixes(LOC_RIB)
+ _test_prefixes(LOC_RIB, step=1)
def test_bmp_bgp_vpn():
# check for the prefixes in the BMP server logging file
logger.info("***** VPN prefixes pre-policy logging *****")
- vpn_prefixes(PRE_POLICY)
+ _test_prefixes(PRE_POLICY, vrf="vrf1", step=2)
logger.info("***** VPN prefixes post-policy logging *****")
- vpn_prefixes(POST_POLICY)
+ _test_prefixes(POST_POLICY, vrf="vrf1", step=2)
logger.info("***** VPN prefixes loc-rib logging *****")
- vpn_prefixes(LOC_RIB)
+ _test_prefixes(LOC_RIB, vrf="vrf1", step=2)
def test_peer_down():
@@ -353,7 +467,7 @@ def test_peer_down():
logger.info("checking for BMP peers down messages")
test_func = partial(check_for_peer_message, peers, "peer down")
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
+ success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1)
assert success, "Checking the updated prefixes has been failed !."
diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-loc-rib-step1.json b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-loc-rib-step1.json
new file mode 100644
index 0000000000..ba31bf1d5d
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-loc-rib-step1.json
@@ -0,0 +1,32 @@
+{
+ "loc-rib": {
+ "update": {
+ "172.31.0.15/32": {
+ "as_path": "65501 65502",
+ "bgp_nexthop": "192.168.0.2",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "is_filtered": false,
+ "origin": "IGP",
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib"
+ },
+ "2111::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2111::1111/128",
+ "is_filtered": false,
+ "nxhp_ip": "192:168::2",
+ "origin": "IGP",
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-post-policy-step1.json b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-post-policy-step1.json
new file mode 100644
index 0000000000..d5d9d65182
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-post-policy-step1.json
@@ -0,0 +1,36 @@
+{
+ "post-policy": {
+ "update": {
+ "172.31.0.15/32": {
+ "as_path": "65501 65502",
+ "bgp_nexthop": "192.168.0.2",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "post-policy"
+ },
+ "2111::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2111::1111/128",
+ "ipv6": true,
+ "nxhp_ip": "192:168::2",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-pre-policy-step1.json b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-pre-policy-step1.json
new file mode 100644
index 0000000000..e11badc040
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-pre-policy-step1.json
@@ -0,0 +1,36 @@
+{
+ "pre-policy": {
+ "update": {
+ "172.31.0.15/32": {
+ "as_path": "65501 65502",
+ "bgp_nexthop": "192.168.0.2",
+ "bmp_log_type": "update",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "pre-policy"
+ },
+ "2111::1111/128": {
+ "afi": 2,
+ "as_path": "65501 65502",
+ "bmp_log_type": "update",
+ "ip_prefix": "2111::1111/128",
+ "ipv6": true,
+ "nxhp_ip": "192:168::2",
+ "origin": "IGP",
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-loc-rib-step1.json b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-loc-rib-step1.json
new file mode 100644
index 0000000000..37ddc09ff8
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-loc-rib-step1.json
@@ -0,0 +1,26 @@
+{
+ "loc-rib": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "is_filtered": false,
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib"
+ },
+ "2111::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2111::1111/128",
+ "is_filtered": false,
+ "peer_asn": 65501,
+ "peer_bgp_id": "192.168.0.1",
+ "peer_type": "loc-rib instance",
+ "policy": "loc-rib",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-post-policy-step1.json b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-post-policy-step1.json
new file mode 100644
index 0000000000..de84307a4e
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-post-policy-step1.json
@@ -0,0 +1,30 @@
+{
+ "post-policy": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "post-policy"
+ },
+ "2111::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2111::1111/128",
+ "ipv6": true,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "post-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-pre-policy-step1.json b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-pre-policy-step1.json
new file mode 100644
index 0000000000..1c34498b7a
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-pre-policy-step1.json
@@ -0,0 +1,30 @@
+{
+ "pre-policy": {
+ "withdraw": {
+ "172.31.0.15/32": {
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "172.31.0.15/32",
+ "ipv6": false,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192.168.0.2",
+ "peer_type": "global instance",
+ "policy": "pre-policy"
+ },
+ "2111::1111/128": {
+ "afi": 2,
+ "bmp_log_type": "withdraw",
+ "ip_prefix": "2111::1111/128",
+ "ipv6": true,
+ "peer_asn": 65502,
+ "peer_bgp_id": "192.168.0.2",
+ "peer_distinguisher": "0:0",
+ "peer_ip": "192:168::2",
+ "peer_type": "global instance",
+ "policy": "pre-policy",
+ "safi": 1
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_bmp_vrf/r1/bgpd.conf b/tests/topotests/bgp_bmp_vrf/r1/bgpd.conf
index 994cdbf68e..961e20498b 100644
--- a/tests/topotests/bgp_bmp_vrf/r1/bgpd.conf
+++ b/tests/topotests/bgp_bmp_vrf/r1/bgpd.conf
@@ -7,6 +7,12 @@ router bgp 65501 vrf vrf1
!
bmp targets bmp1
bmp connect 192.0.2.10 port 1789 min-retry 100 max-retry 10000
+ bmp monitor ipv4 unicast pre-policy
+ bmp monitor ipv6 unicast pre-policy
+ bmp monitor ipv4 unicast post-policy
+ bmp monitor ipv6 unicast post-policy
+ bmp monitor ipv4 unicast loc-rib
+ bmp monitor ipv6 unicast loc-rib
exit
!
diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-update-step1.json b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-update-step1.json
new file mode 100644
index 0000000000..038c87ca9d
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-update-step1.json
@@ -0,0 +1,21 @@
+{
+ "routes": {
+ "172.31.0.15/32": [
+ {
+ "bestpath": true,
+ "pathFrom": "external",
+ "path": "65502",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "192.168.0.2",
+ "hostname": "r2",
+ "afi": "ipv4",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-withdraw-step1.json b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-withdraw-step1.json
new file mode 100644
index 0000000000..6a77813776
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-withdraw-step1.json
@@ -0,0 +1,6 @@
+{
+ "routes": {
+ "172.31.0.15/32": null
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-update-step1.json b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-update-step1.json
new file mode 100644
index 0000000000..db34220149
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-update-step1.json
@@ -0,0 +1,27 @@
+{
+ "routes": {
+ "2111::1111/128": [
+ {
+ "bestpath": true,
+ "pathFrom": "external",
+ "path": "65502",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "192:168::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "global"
+ },
+ {
+ "hostname": "r2",
+ "afi": "ipv6",
+ "scope": "link-local",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-withdraw-step1.json b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-withdraw-step1.json
new file mode 100644
index 0000000000..93f4a75e8c
--- /dev/null
+++ b/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-withdraw-step1.json
@@ -0,0 +1,6 @@
+{
+ "routes": {
+ "2111::1111/128": null
+ }
+}
+
diff --git a/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py b/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py
index b683920d2e..d31328bdb6 100644
--- a/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py
+++ b/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py
@@ -51,6 +51,9 @@ PRE_POLICY = "pre-policy"
POST_POLICY = "post-policy"
LOC_RIB = "loc-rib"
+UPDATE_EXPECTED_JSON = False
+DEBUG_PCAP = False
+
def build_topo(tgen):
tgen.add_router("r1")
@@ -76,6 +79,12 @@ ip link set r1-eth1 master vrf1
"""
)
+ if DEBUG_PCAP:
+ tgen.gears["r1"].run("rm /tmp/bmp_vrf.pcap")
+ tgen.gears["r1"].run(
+ "tcpdump -nni r1-eth0 -s 0 -w /tmp/bmp_vrf.pcap &", stdout=None
+ )
+
for rname, router in tgen.routers().items():
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
@@ -131,42 +140,125 @@ def get_bmp_messages():
return messages
-def check_for_prefixes(expected_prefixes, bmp_log_type, policy, labels=None):
+def update_seq():
+ global SEQ
+
+ messages = get_bmp_messages()
+
+ if len(messages):
+ SEQ = messages[-1]["seq"]
+
+
+def update_expected_files(bmp_actual, expected_prefixes, bmp_log_type, policy, step):
+ tgen = get_topogen()
+
+ with open(f"/tmp/bmp-{bmp_log_type}-{policy}-step{step}.json", "w") as json_file:
+ json.dump(bmp_actual, json_file, indent=4)
+
+ out = tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv4 json", isjson=True)
+ filtered_out = {
+ "routes": {
+ prefix: route_info
+ for prefix, route_info in out["routes"].items()
+ if prefix in expected_prefixes
+ }
+ }
+ if bmp_log_type == "withdraw":
+ for pfx in expected_prefixes:
+ if "::" in pfx:
+ continue
+ filtered_out["routes"][pfx] = None
+
+ # ls /tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done
+ with open(f"/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w") as json_file:
+ json.dump(filtered_out, json_file, indent=4)
+
+ out = tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv6 json", isjson=True)
+ filtered_out = {
+ "routes": {
+ prefix: route_info
+ for prefix, route_info in out["routes"].items()
+ if prefix in expected_prefixes
+ }
+ }
+ if bmp_log_type == "withdraw":
+ for pfx in expected_prefixes:
+ if "::" not in pfx:
+ continue
+ filtered_out["routes"][pfx] = None
+
+ with open(f"/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w") as json_file:
+ json.dump(filtered_out, json_file, indent=4)
+
+
+def check_for_prefixes(expected_prefixes, bmp_log_type, policy, step):
"""
Check for the presence of the given prefixes in the BMP server logs with
the given message type and the set policy.
+
"""
global SEQ
+
# we care only about the new messages
messages = [
m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ
]
- # get the list of pairs (prefix, policy, seq) for the given message type
- prefixes = [
- m["ip_prefix"]
- for m in messages
- if "ip_prefix" in m.keys()
- and "bmp_log_type" in m.keys()
- and m["bmp_log_type"] == bmp_log_type
- and m["policy"] == policy
- and (
- labels is None
- or (
- m["ip_prefix"] in labels.keys() and m["label"] == labels[m["ip_prefix"]]
- )
- )
- ]
-
- # check for prefixes
- for ep in expected_prefixes:
- if ep not in prefixes:
- msg = "The prefix {} is not present in the {} log messages."
- logger.debug(msg.format(ep, bmp_log_type))
- return False
-
- SEQ = messages[-1]["seq"]
- return True
+ # create empty initial files
+ # for step in $(seq 1); do
+ # for i in "update" "withdraw"; do
+ # for j in "pre-policy" "post-policy" "loc-rib"; do
+ # echo '{"null": {}}'> bmp-$i-$j-step$step.json
+ # done
+ # done
+ # done
+
+ ref_file = f"{CWD}/bmp1/bmp-{bmp_log_type}-{policy}-step{step}.json"
+ expected = json.loads(open(ref_file).read())
+
+ # Build actual json from logs
+ actual = {}
+ for m in messages:
+ if (
+ "bmp_log_type" in m.keys()
+ and "ip_prefix" in m.keys()
+ and m["ip_prefix"] in expected_prefixes
+ and m["bmp_log_type"] == bmp_log_type
+ and m["policy"] == policy
+ ):
+ policy_dict = actual.setdefault(m["policy"], {})
+ bmp_log_type_dict = policy_dict.setdefault(m["bmp_log_type"], {})
+
+ # Add or update the ip_prefix dictionary with filtered key-value pairs
+ bmp_log_type_dict[m["ip_prefix"]] = {
+ k: v
+ for k, v in sorted(m.items())
+ # filter out variable keys
+ if k not in ["timestamp", "seq", "nxhp_link-local"]
+ and (
+ # When policy is loc-rib, the peer-distinguisher is 0:0
+ # for the default VRF or the RD if any or the 0:<vrf_id>.
+ # 0:<vrf_id> is used to distinguished. RFC7854 says: "If the
+ # peer is a "Local Instance Peer", it is set to a unique,
+ # locally defined value." The value is not tested because it
+ # is variable.
+ k != "peer_distinguisher"
+ or policy != LOC_RIB
+ or v == "0:0"
+ or not v.startswith("0:")
+ )
+ }
+
+ # build expected JSON files
+ if (
+ UPDATE_EXPECTED_JSON
+ and actual
+ and set(actual.get(policy, {}).get(bmp_log_type, {}).keys())
+ == set(expected_prefixes)
+ ):
+ update_expected_files(actual, expected_prefixes, bmp_log_type, policy, step)
+
+ return topotest.json_cmp(actual, expected, exact=True)
def check_for_peer_message(expected_peers, bmp_log_type):
@@ -197,22 +289,6 @@ def check_for_peer_message(expected_peers, bmp_log_type):
return True
-def set_bmp_policy(tgen, node, asn, target, safi, policy, vrf=None):
- """
- Configure the bmp policy.
- """
- vrf = " vrf {}".format(vrf) if vrf else ""
- cmd = [
- "con t\n",
- "router bgp {}{}\n".format(asn, vrf),
- "bmp targets {}\n".format(target),
- "bmp monitor ipv4 {} {}\n".format(safi, policy),
- "bmp monitor ipv6 {} {}\n".format(safi, policy),
- "end\n",
- ]
- tgen.gears[node].vtysh_cmd("".join(cmd))
-
-
def configure_prefixes(tgen, node, asn, safi, prefixes, vrf=None, update=True):
"""
Configure the bgp prefixes.
@@ -232,32 +308,48 @@ def configure_prefixes(tgen, node, asn, safi, prefixes, vrf=None, update=True):
tgen.gears[node].vtysh_cmd("".join(cmd))
-def unicast_prefixes(policy):
+def _test_prefixes(policy, step=1):
"""
Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes.
Check if the previous actions are logged in the BMP server with the right
message type and the right policy.
"""
tgen = get_topogen()
- set_bmp_policy(tgen, "r1", 65501, "bmp1", "unicast", policy, vrf="vrf1")
prefixes = ["172.31.0.15/32", "2111::1111/128"]
- # add prefixes
- configure_prefixes(tgen, "r2", 65502, "unicast", prefixes)
- logger.info("checking for updated prefixes")
- # check
- test_func = partial(check_for_prefixes, prefixes, "update", policy)
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
- assert success, "Checking the updated prefixes has been failed !."
+ for type in ("update", "withdraw"):
+ update_seq()
+
+ # add prefixes
+ configure_prefixes(
+ tgen, "r2", 65502, "unicast", prefixes, update=(type == "update")
+ )
+
+ logger.info(f"checking for prefixes {type}")
+
+ for ipver in [4, 6]:
+ if UPDATE_EXPECTED_JSON:
+ continue
+ ref_file = "{}/r1/show-bgp-ipv{}-{}-step{}.json".format(
+ CWD, ipver, type, step
+ )
+ expected = json.loads(open(ref_file).read())
+
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears["r1"],
+ f"show bgp vrf vrf1 ipv{ipver} json",
+ expected,
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assertmsg = f"r1: BGP IPv{ipver} convergence failed"
+ assert res is None, assertmsg
- # withdraw prefixes
- configure_prefixes(tgen, "r2", 65502, "unicast", prefixes, update=False)
- logger.info("checking for withdrawed prefxies")
- # check
- test_func = partial(check_for_prefixes, prefixes, "withdraw", policy)
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
- assert success, "Checking the withdrawed prefixes has been failed !."
+ # check
+ test_func = partial(check_for_prefixes, prefixes, type, policy, step)
+ success, res = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert success, "Checking the updated prefixes has been failed ! %s" % res
def test_bmp_server_logging():
@@ -274,7 +366,7 @@ def test_bmp_server_logging():
return False
return True
- success, _ = topotest.run_and_expect(check_for_log_file, True, wait=0.5)
+ success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1)
assert success, "The BMP server is not logging"
@@ -288,7 +380,7 @@ def test_peer_up():
logger.info("checking for BMP peers up messages")
test_func = partial(check_for_peer_message, peers, "peer up")
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
+ success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1)
assert success, "Checking the updated prefixes has been failed !."
@@ -297,11 +389,11 @@ def test_bmp_bgp_unicast():
Add/withdraw bgp unicast prefixes and check the bmp logs.
"""
logger.info("*** Unicast prefixes pre-policy logging ***")
- unicast_prefixes(PRE_POLICY)
+ _test_prefixes(PRE_POLICY)
logger.info("*** Unicast prefixes post-policy logging ***")
- unicast_prefixes(POST_POLICY)
+ _test_prefixes(POST_POLICY)
logger.info("*** Unicast prefixes loc-rib logging ***")
- unicast_prefixes(LOC_RIB)
+ _test_prefixes(LOC_RIB)
def test_peer_down():
@@ -317,7 +409,7 @@ def test_peer_down():
logger.info("checking for BMP peers down messages")
test_func = partial(check_for_peer_message, peers, "peer down")
- success, _ = topotest.run_and_expect(test_func, True, wait=0.5)
+ success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1)
assert success, "Checking the updated prefixes has been failed !."