From fe3c85de1a3e167ecd5308efa448d127e78a9f7e Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Tue, 4 May 2021 04:04:37 +0200 Subject: [PATCH] tests: Add PIM ACL-based RP selection test Signed-off-by: Martin Winter --- tests/topotests/pim_acl/h1/zebra.conf | 10 + tests/topotests/pim_acl/h2/zebra.conf | 8 + .../topotests/pim_acl/r1/acl_1_pim_join.json | 21 + .../topotests/pim_acl/r1/acl_2_pim_join.json | 21 + .../topotests/pim_acl/r1/acl_3_pim_join.json | 21 + .../topotests/pim_acl/r1/acl_4_pim_join.json | 21 + .../topotests/pim_acl/r1/acl_5_pim_join.json | 21 + .../topotests/pim_acl/r1/acl_6_pim_join.json | 21 + tests/topotests/pim_acl/r1/ospf_neighbor.json | 59 +++ tests/topotests/pim_acl/r1/ospfd.conf | 16 + tests/topotests/pim_acl/r1/pim_neighbor.json | 31 ++ tests/topotests/pim_acl/r1/pimd.conf | 30 ++ tests/topotests/pim_acl/r1/zebra.conf | 18 + .../topotests/pim_acl/r11/acl_1_pim_join.json | 19 + tests/topotests/pim_acl/r11/ospfd.conf | 14 + tests/topotests/pim_acl/r11/pimd.conf | 16 + tests/topotests/pim_acl/r11/zebra.conf | 13 + .../topotests/pim_acl/r12/acl_2_pim_join.json | 19 + tests/topotests/pim_acl/r12/ospfd.conf | 14 + tests/topotests/pim_acl/r12/pimd.conf | 16 + tests/topotests/pim_acl/r12/zebra.conf | 13 + .../topotests/pim_acl/r13/acl_3_pim_join.json | 19 + tests/topotests/pim_acl/r13/ospfd.conf | 14 + tests/topotests/pim_acl/r13/pimd.conf | 16 + tests/topotests/pim_acl/r13/zebra.conf | 13 + .../topotests/pim_acl/r14/acl_4_pim_join.json | 19 + .../topotests/pim_acl/r14/acl_5_pim_join.json | 19 + tests/topotests/pim_acl/r14/ospfd.conf | 14 + tests/topotests/pim_acl/r14/pimd.conf | 17 + tests/topotests/pim_acl/r14/zebra.conf | 13 + .../topotests/pim_acl/r15/acl_6_pim_join.json | 19 + tests/topotests/pim_acl/r15/ospfd.conf | 14 + tests/topotests/pim_acl/r15/pimd.conf | 16 + tests/topotests/pim_acl/r15/zebra.conf | 13 + tests/topotests/pim_acl/test_pim_acl.py | 418 ++++++++++++++++++ 35 files changed, 1046 insertions(+) create mode 100644 tests/topotests/pim_acl/h1/zebra.conf create mode 100644 tests/topotests/pim_acl/h2/zebra.conf create mode 100644 tests/topotests/pim_acl/r1/acl_1_pim_join.json create mode 100644 tests/topotests/pim_acl/r1/acl_2_pim_join.json create mode 100644 tests/topotests/pim_acl/r1/acl_3_pim_join.json create mode 100644 tests/topotests/pim_acl/r1/acl_4_pim_join.json create mode 100644 tests/topotests/pim_acl/r1/acl_5_pim_join.json create mode 100644 tests/topotests/pim_acl/r1/acl_6_pim_join.json create mode 100644 tests/topotests/pim_acl/r1/ospf_neighbor.json create mode 100644 tests/topotests/pim_acl/r1/ospfd.conf create mode 100644 tests/topotests/pim_acl/r1/pim_neighbor.json create mode 100644 tests/topotests/pim_acl/r1/pimd.conf create mode 100644 tests/topotests/pim_acl/r1/zebra.conf create mode 100644 tests/topotests/pim_acl/r11/acl_1_pim_join.json create mode 100644 tests/topotests/pim_acl/r11/ospfd.conf create mode 100644 tests/topotests/pim_acl/r11/pimd.conf create mode 100644 tests/topotests/pim_acl/r11/zebra.conf create mode 100644 tests/topotests/pim_acl/r12/acl_2_pim_join.json create mode 100644 tests/topotests/pim_acl/r12/ospfd.conf create mode 100644 tests/topotests/pim_acl/r12/pimd.conf create mode 100644 tests/topotests/pim_acl/r12/zebra.conf create mode 100644 tests/topotests/pim_acl/r13/acl_3_pim_join.json create mode 100644 tests/topotests/pim_acl/r13/ospfd.conf create mode 100644 tests/topotests/pim_acl/r13/pimd.conf create mode 100644 tests/topotests/pim_acl/r13/zebra.conf create mode 100644 tests/topotests/pim_acl/r14/acl_4_pim_join.json create mode 100644 tests/topotests/pim_acl/r14/acl_5_pim_join.json create mode 100644 tests/topotests/pim_acl/r14/ospfd.conf create mode 100644 tests/topotests/pim_acl/r14/pimd.conf create mode 100644 tests/topotests/pim_acl/r14/zebra.conf create mode 100644 tests/topotests/pim_acl/r15/acl_6_pim_join.json create mode 100644 tests/topotests/pim_acl/r15/ospfd.conf create mode 100644 tests/topotests/pim_acl/r15/pimd.conf create mode 100644 tests/topotests/pim_acl/r15/zebra.conf create mode 100755 tests/topotests/pim_acl/test_pim_acl.py diff --git a/tests/topotests/pim_acl/h1/zebra.conf b/tests/topotests/pim_acl/h1/zebra.conf new file mode 100644 index 0000000000..3d6540d40c --- /dev/null +++ b/tests/topotests/pim_acl/h1/zebra.conf @@ -0,0 +1,10 @@ +! +hostname h1 +log file zebra.log +! +interface h1-eth0 + description connection to r1 via sw1 + ip address 192.168.100.10/24 +! +ip route 0.0.0.0/0 192.168.100.1 +! diff --git a/tests/topotests/pim_acl/h2/zebra.conf b/tests/topotests/pim_acl/h2/zebra.conf new file mode 100644 index 0000000000..95342f9e8a --- /dev/null +++ b/tests/topotests/pim_acl/h2/zebra.conf @@ -0,0 +1,8 @@ +hostname h2 +! +interface h2-eth0 + description connection to r1 via sw2 + ip address 192.168.101.2/24 +! +ip route 0.0.0.0/0 192.168.101.1 +! diff --git a/tests/topotests/pim_acl/r1/acl_1_pim_join.json b/tests/topotests/pim_acl/r1/acl_1_pim_join.json new file mode 100644 index 0000000000..1b44b2b5cf --- /dev/null +++ b/tests/topotests/pim_acl/r1/acl_1_pim_join.json @@ -0,0 +1,21 @@ +{ + "r1-eth0":{ + "name":"r1-eth0", + "state":"up", + "address":"192.168.100.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.1":{ + "*":{ + "source":"*", + "group":"239.100.0.1", + "upTime":"--:--:--", + "expire":"--:--", + "prune":"--:--", + "channelJoinName":"NOINFO", + "protocolIgmp":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r1/acl_2_pim_join.json b/tests/topotests/pim_acl/r1/acl_2_pim_join.json new file mode 100644 index 0000000000..c020a489a9 --- /dev/null +++ b/tests/topotests/pim_acl/r1/acl_2_pim_join.json @@ -0,0 +1,21 @@ +{ + "r1-eth0":{ + "name":"r1-eth0", + "state":"up", + "address":"192.168.100.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.17":{ + "*":{ + "source":"*", + "group":"239.100.0.17", + "upTime":"--:--:--", + "expire":"--:--", + "prune":"--:--", + "channelJoinName":"NOINFO", + "protocolIgmp":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r1/acl_3_pim_join.json b/tests/topotests/pim_acl/r1/acl_3_pim_join.json new file mode 100644 index 0000000000..6122f73992 --- /dev/null +++ b/tests/topotests/pim_acl/r1/acl_3_pim_join.json @@ -0,0 +1,21 @@ +{ + "r1-eth0":{ + "name":"r1-eth0", + "state":"up", + "address":"192.168.100.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.32":{ + "*":{ + "source":"*", + "group":"239.100.0.32", + "upTime":"--:--:--", + "expire":"--:--", + "prune":"--:--", + "channelJoinName":"NOINFO", + "protocolIgmp":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r1/acl_4_pim_join.json b/tests/topotests/pim_acl/r1/acl_4_pim_join.json new file mode 100644 index 0000000000..5f72256ba7 --- /dev/null +++ b/tests/topotests/pim_acl/r1/acl_4_pim_join.json @@ -0,0 +1,21 @@ +{ + "r1-eth0":{ + "name":"r1-eth0", + "state":"up", + "address":"192.168.100.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.255":{ + "*":{ + "source":"*", + "group":"239.100.0.255", + "upTime":"--:--:--", + "expire":"--:--", + "prune":"--:--", + "channelJoinName":"NOINFO", + "protocolIgmp":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r1/acl_5_pim_join.json b/tests/topotests/pim_acl/r1/acl_5_pim_join.json new file mode 100644 index 0000000000..70021bdbec --- /dev/null +++ b/tests/topotests/pim_acl/r1/acl_5_pim_join.json @@ -0,0 +1,21 @@ +{ + "r1-eth0":{ + "name":"r1-eth0", + "state":"up", + "address":"192.168.100.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.97":{ + "*":{ + "source":"*", + "group":"239.100.0.97", + "upTime":"--:--:--", + "expire":"--:--", + "prune":"--:--", + "channelJoinName":"NOINFO", + "protocolIgmp":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r1/acl_6_pim_join.json b/tests/topotests/pim_acl/r1/acl_6_pim_join.json new file mode 100644 index 0000000000..2baac6cb22 --- /dev/null +++ b/tests/topotests/pim_acl/r1/acl_6_pim_join.json @@ -0,0 +1,21 @@ +{ + "r1-eth0":{ + "name":"r1-eth0", + "state":"up", + "address":"192.168.100.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.70":{ + "*":{ + "source":"*", + "group":"239.100.0.70", + "upTime":"--:--:--", + "expire":"--:--", + "prune":"--:--", + "channelJoinName":"NOINFO", + "protocolIgmp":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r1/ospf_neighbor.json b/tests/topotests/pim_acl/r1/ospf_neighbor.json new file mode 100644 index 0000000000..a8fc093e90 --- /dev/null +++ b/tests/topotests/pim_acl/r1/ospf_neighbor.json @@ -0,0 +1,59 @@ +{ + "neighbors":{ + "192.168.0.11":[ + { + "priority":10, + "state":"Full\/Backup", + "address":"192.168.101.11", + "ifaceName":"r1-eth1:192.168.101.1", + "retransmitCounter":0, + "requestCounter":0, + "dbSummaryCounter":0 + } + ], + "192.168.0.12":[ + { + "priority":0, + "state":"Full\/DROther", + "address":"192.168.101.12", + "ifaceName":"r1-eth1:192.168.101.1", + "retransmitCounter":0, + "requestCounter":0, + "dbSummaryCounter":0 + } + ], + "192.168.0.13":[ + { + "priority":0, + "state":"Full\/DROther", + "address":"192.168.101.13", + "ifaceName":"r1-eth1:192.168.101.1", + "retransmitCounter":0, + "requestCounter":0, + "dbSummaryCounter":0 + } + ], + "192.168.0.14":[ + { + "priority":0, + "state":"Full\/DROther", + "address":"192.168.101.14", + "ifaceName":"r1-eth1:192.168.101.1", + "retransmitCounter":0, + "requestCounter":0, + "dbSummaryCounter":0 + } + ], + "192.168.0.15":[ + { + "priority":0, + "state":"Full\/DROther", + "address":"192.168.101.15", + "ifaceName":"r1-eth1:192.168.101.1", + "retransmitCounter":0, + "requestCounter":0, + "dbSummaryCounter":0 + } + ] + } +} diff --git a/tests/topotests/pim_acl/r1/ospfd.conf b/tests/topotests/pim_acl/r1/ospfd.conf new file mode 100644 index 0000000000..e1f47fb3b1 --- /dev/null +++ b/tests/topotests/pim_acl/r1/ospfd.conf @@ -0,0 +1,16 @@ +hostname r1 +! +debug ospf event +! +interface r1-eth1 + ip ospf hello-interval 2 + ip ospf dead-interval 10 + ip ospf priority 20 +! +router ospf + ospf router-id 192.168.0.1 + passive-interface r1-eth0 + network 192.168.0.1/32 area 0 + network 192.168.100.0/24 area 0 + network 192.168.101.0/24 area 0 + diff --git a/tests/topotests/pim_acl/r1/pim_neighbor.json b/tests/topotests/pim_acl/r1/pim_neighbor.json new file mode 100644 index 0000000000..ae95e8db14 --- /dev/null +++ b/tests/topotests/pim_acl/r1/pim_neighbor.json @@ -0,0 +1,31 @@ +{ + "r1-eth0":{ + }, + "r1-eth1":{ + "192.168.101.12":{ + "interface":"r1-eth1", + "neighbor":"192.168.101.12", + "drPriority":1 + }, + "192.168.101.15":{ + "interface":"r1-eth1", + "neighbor":"192.168.101.15", + "drPriority":1 + }, + "192.168.101.14":{ + "interface":"r1-eth1", + "neighbor":"192.168.101.14", + "drPriority":1 + }, + "192.168.101.11":{ + "interface":"r1-eth1", + "neighbor":"192.168.101.11", + "drPriority":1 + }, + "192.168.101.13":{ + "interface":"r1-eth1", + "neighbor":"192.168.101.13", + "drPriority":1 + } + } +} diff --git a/tests/topotests/pim_acl/r1/pimd.conf b/tests/topotests/pim_acl/r1/pimd.conf new file mode 100644 index 0000000000..72d28c9b02 --- /dev/null +++ b/tests/topotests/pim_acl/r1/pimd.conf @@ -0,0 +1,30 @@ +hostname r1 +! +debug igmp events +debug igmp packets +debug pim events +debug pim packets +debug pim trace +debug pim zebra +debug pim bsm +! +ip pim rp 192.168.0.11 prefix-list rp-pl-1 +ip pim rp 192.168.0.12 prefix-list rp-pl-2 +ip pim rp 192.168.0.13 prefix-list rp-pl-3 +ip pim rp 192.168.0.14 prefix-list rp-pl-4 +ip pim rp 192.168.0.15 prefix-list rp-pl-5 +! +interface r1-eth0 + ip igmp + ip igmp version 2 + ip pim +! +interface r1-eth1 + ip pim +! +ip prefix-list rp-pl-1 seq 10 permit 239.100.0.0/28 +ip prefix-list rp-pl-2 seq 10 permit 239.100.0.17/32 +ip prefix-list rp-pl-3 seq 10 permit 239.100.0.32/27 +ip prefix-list rp-pl-4 seq 10 permit 239.100.0.128/25 +ip prefix-list rp-pl-4 seq 20 permit 239.100.0.96/28 +ip prefix-list rp-pl-5 seq 10 permit 239.100.0.64/28 diff --git a/tests/topotests/pim_acl/r1/zebra.conf b/tests/topotests/pim_acl/r1/zebra.conf new file mode 100644 index 0000000000..74feb8f6a7 --- /dev/null +++ b/tests/topotests/pim_acl/r1/zebra.conf @@ -0,0 +1,18 @@ +! +hostname r1 +log file zebra.log +! +ip forwarding +ipv6 forwarding +! +interface lo + ip address 192.168.0.1/32 +! +interface r1-eth0 + description connection to h1 via sw1 + ip address 192.168.100.1/24 +! +interface r1-eth1 + description connection to r11/12/13/14/15 via sw2 + ip address 192.168.101.1/24 +! diff --git a/tests/topotests/pim_acl/r11/acl_1_pim_join.json b/tests/topotests/pim_acl/r11/acl_1_pim_join.json new file mode 100644 index 0000000000..289bf51e76 --- /dev/null +++ b/tests/topotests/pim_acl/r11/acl_1_pim_join.json @@ -0,0 +1,19 @@ +{ + "r11-eth0":{ + "name":"r11-eth0", + "state":"up", + "address":"192.168.101.11", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.1":{ + "*":{ + "source":"*", + "group":"239.100.0.1", + "prune":"--:--", + "channelJoinName":"JOIN", + "protocolPim":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r11/ospfd.conf b/tests/topotests/pim_acl/r11/ospfd.conf new file mode 100644 index 0000000000..e107220a4e --- /dev/null +++ b/tests/topotests/pim_acl/r11/ospfd.conf @@ -0,0 +1,14 @@ +hostname r11 +! +debug ospf event +! +interface r11-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 + ip ospf priority 10 +! +router ospf + ospf router-id 192.168.0.11 + network 192.168.0.11/32 area 0 + network 192.168.101.0/24 area 0 +! diff --git a/tests/topotests/pim_acl/r11/pimd.conf b/tests/topotests/pim_acl/r11/pimd.conf new file mode 100644 index 0000000000..05cd5ac911 --- /dev/null +++ b/tests/topotests/pim_acl/r11/pimd.conf @@ -0,0 +1,16 @@ +hostname r11 +! +debug pim events +debug pim packets +debug pim trace +debug pim zebra +debug pim bsm +! +ip pim rp 192.168.0.11 239.100.0.0/28 +! +interface lo + ip pim +! +interface r11-eth0 + ip pim +! diff --git a/tests/topotests/pim_acl/r11/zebra.conf b/tests/topotests/pim_acl/r11/zebra.conf new file mode 100644 index 0000000000..137706d245 --- /dev/null +++ b/tests/topotests/pim_acl/r11/zebra.conf @@ -0,0 +1,13 @@ +! +hostname r11 +log file zebra.log +! +interface lo + ip address 192.168.0.11/32 +! +interface r11-eth0 + description connection to r1 via sw1 + ip address 192.168.101.11/24 +! +ip route 0.0.0.0/0 192.168.101.1 +! diff --git a/tests/topotests/pim_acl/r12/acl_2_pim_join.json b/tests/topotests/pim_acl/r12/acl_2_pim_join.json new file mode 100644 index 0000000000..76ab7ee701 --- /dev/null +++ b/tests/topotests/pim_acl/r12/acl_2_pim_join.json @@ -0,0 +1,19 @@ +{ + "r12-eth0":{ + "name":"r12-eth0", + "state":"up", + "address":"192.168.101.12", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.17":{ + "*":{ + "source":"*", + "group":"239.100.0.17", + "prune":"--:--", + "channelJoinName":"JOIN", + "protocolPim":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r12/ospfd.conf b/tests/topotests/pim_acl/r12/ospfd.conf new file mode 100644 index 0000000000..f9203c78e4 --- /dev/null +++ b/tests/topotests/pim_acl/r12/ospfd.conf @@ -0,0 +1,14 @@ +hostname r12 +! +debug ospf event +! +interface r12-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 + ip ospf priority 0 +! +router ospf + ospf router-id 192.168.0.12 + network 192.168.0.12/32 area 0 + network 192.168.101.0/24 area 0 +! diff --git a/tests/topotests/pim_acl/r12/pimd.conf b/tests/topotests/pim_acl/r12/pimd.conf new file mode 100644 index 0000000000..cedde73c59 --- /dev/null +++ b/tests/topotests/pim_acl/r12/pimd.conf @@ -0,0 +1,16 @@ +hostname r12 +! +debug pim events +debug pim packets +debug pim trace +debug pim zebra +debug pim bsm +! +ip pim rp 192.168.0.12 239.100.0.17/32 +! +interface lo + ip pim +! +interface r12-eth0 + ip pim +! diff --git a/tests/topotests/pim_acl/r12/zebra.conf b/tests/topotests/pim_acl/r12/zebra.conf new file mode 100644 index 0000000000..bede104906 --- /dev/null +++ b/tests/topotests/pim_acl/r12/zebra.conf @@ -0,0 +1,13 @@ +! +hostname r12 +log file zebra.log +! +interface lo + ip address 192.168.0.12/32 +! +interface r12-eth0 + description connection to r1 via sw1 + ip address 192.168.101.12/24 +! +ip route 0.0.0.0/0 192.168.101.1 +! diff --git a/tests/topotests/pim_acl/r13/acl_3_pim_join.json b/tests/topotests/pim_acl/r13/acl_3_pim_join.json new file mode 100644 index 0000000000..48ad72cbe1 --- /dev/null +++ b/tests/topotests/pim_acl/r13/acl_3_pim_join.json @@ -0,0 +1,19 @@ +{ + "r13-eth0":{ + "name":"r13-eth0", + "state":"up", + "address":"192.168.101.13", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.32":{ + "*":{ + "source":"*", + "group":"239.100.0.32", + "prune":"--:--", + "channelJoinName":"JOIN", + "protocolPim":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r13/ospfd.conf b/tests/topotests/pim_acl/r13/ospfd.conf new file mode 100644 index 0000000000..830c5a14b6 --- /dev/null +++ b/tests/topotests/pim_acl/r13/ospfd.conf @@ -0,0 +1,14 @@ +hostname r13 +! +debug ospf event +! +interface r13-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 + ip ospf priority 0 +! +router ospf + ospf router-id 192.168.0.13 + network 192.168.0.13/32 area 0 + network 192.168.101.0/24 area 0 +! diff --git a/tests/topotests/pim_acl/r13/pimd.conf b/tests/topotests/pim_acl/r13/pimd.conf new file mode 100644 index 0000000000..2dab0cabec --- /dev/null +++ b/tests/topotests/pim_acl/r13/pimd.conf @@ -0,0 +1,16 @@ +hostname r13 +! +debug pim events +debug pim packets +debug pim trace +debug pim zebra +debug pim bsm +! +ip pim rp 192.168.0.13 239.100.0.32/27 +! +interface lo + ip pim +! +interface r13-eth0 + ip pim +! diff --git a/tests/topotests/pim_acl/r13/zebra.conf b/tests/topotests/pim_acl/r13/zebra.conf new file mode 100644 index 0000000000..f9ff27abac --- /dev/null +++ b/tests/topotests/pim_acl/r13/zebra.conf @@ -0,0 +1,13 @@ +! +hostname r13 +log file zebra.log +! +interface lo + ip address 192.168.0.13/32 +! +interface r13-eth0 + description connection to r1 via sw1 + ip address 192.168.101.13/24 +! +ip route 0.0.0.0/0 192.168.101.1 +! diff --git a/tests/topotests/pim_acl/r14/acl_4_pim_join.json b/tests/topotests/pim_acl/r14/acl_4_pim_join.json new file mode 100644 index 0000000000..46d86dd40d --- /dev/null +++ b/tests/topotests/pim_acl/r14/acl_4_pim_join.json @@ -0,0 +1,19 @@ +{ + "r14-eth0":{ + "name":"r14-eth0", + "state":"up", + "address":"192.168.101.14", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.255":{ + "*":{ + "source":"*", + "group":"239.100.0.255", + "prune":"--:--", + "channelJoinName":"JOIN", + "protocolPim":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r14/acl_5_pim_join.json b/tests/topotests/pim_acl/r14/acl_5_pim_join.json new file mode 100644 index 0000000000..2b291a8a0c --- /dev/null +++ b/tests/topotests/pim_acl/r14/acl_5_pim_join.json @@ -0,0 +1,19 @@ +{ + "r14-eth0":{ + "name":"r14-eth0", + "state":"up", + "address":"192.168.101.14", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.97":{ + "*":{ + "source":"*", + "group":"239.100.0.97", + "prune":"--:--", + "channelJoinName":"JOIN", + "protocolPim":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r14/ospfd.conf b/tests/topotests/pim_acl/r14/ospfd.conf new file mode 100644 index 0000000000..422e4c08b0 --- /dev/null +++ b/tests/topotests/pim_acl/r14/ospfd.conf @@ -0,0 +1,14 @@ +hostname r14 +! +debug ospf event +! +interface r14-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 + ip ospf priority 0 +! +router ospf + ospf router-id 192.168.0.14 + network 192.168.0.14/32 area 0 + network 192.168.101.0/24 area 0 +! diff --git a/tests/topotests/pim_acl/r14/pimd.conf b/tests/topotests/pim_acl/r14/pimd.conf new file mode 100644 index 0000000000..c6b949af16 --- /dev/null +++ b/tests/topotests/pim_acl/r14/pimd.conf @@ -0,0 +1,17 @@ +hostname r14 +! +debug pim events +debug pim packets +debug pim trace +debug pim zebra +debug pim bsm +! +ip pim rp 192.168.0.14 239.100.0.96/28 +ip pim rp 192.168.0.14 239.100.0.128/25 +! +interface lo + ip pim +! +interface r14-eth0 + ip pim +! diff --git a/tests/topotests/pim_acl/r14/zebra.conf b/tests/topotests/pim_acl/r14/zebra.conf new file mode 100644 index 0000000000..8761b46206 --- /dev/null +++ b/tests/topotests/pim_acl/r14/zebra.conf @@ -0,0 +1,13 @@ +! +hostname r14 +log file zebra.log +! +interface lo + ip address 192.168.0.14/32 +! +interface r14-eth0 + description connection to r1 via sw1 + ip address 192.168.101.14/24 +! +ip route 0.0.0.0/0 192.168.101.1 +! diff --git a/tests/topotests/pim_acl/r15/acl_6_pim_join.json b/tests/topotests/pim_acl/r15/acl_6_pim_join.json new file mode 100644 index 0000000000..05fed4ecc5 --- /dev/null +++ b/tests/topotests/pim_acl/r15/acl_6_pim_join.json @@ -0,0 +1,19 @@ +{ + "r15-eth0":{ + "name":"r15-eth0", + "state":"up", + "address":"192.168.101.15", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.100.0.70":{ + "*":{ + "source":"*", + "group":"239.100.0.70", + "prune":"--:--", + "channelJoinName":"JOIN", + "protocolPim":1 + } + } + } +} diff --git a/tests/topotests/pim_acl/r15/ospfd.conf b/tests/topotests/pim_acl/r15/ospfd.conf new file mode 100644 index 0000000000..cd4d7b3875 --- /dev/null +++ b/tests/topotests/pim_acl/r15/ospfd.conf @@ -0,0 +1,14 @@ +hostname r15 +! +debug ospf event +! +interface r15-eth0 + ip ospf hello-interval 2 + ip ospf dead-interval 10 + ip ospf priority 0 +! +router ospf + ospf router-id 192.168.0.15 + network 192.168.0.15/32 area 0 + network 192.168.101.0/24 area 0 +! diff --git a/tests/topotests/pim_acl/r15/pimd.conf b/tests/topotests/pim_acl/r15/pimd.conf new file mode 100644 index 0000000000..85c9c51e1e --- /dev/null +++ b/tests/topotests/pim_acl/r15/pimd.conf @@ -0,0 +1,16 @@ +hostname r15 +! +debug pim events +debug pim packets +debug pim trace +debug pim zebra +debug pim bsm +! +ip pim rp 192.168.0.15 239.100.0.64/28 +! +interface lo + ip pim +! +interface r15-eth0 + ip pim +! diff --git a/tests/topotests/pim_acl/r15/zebra.conf b/tests/topotests/pim_acl/r15/zebra.conf new file mode 100644 index 0000000000..f6909dd020 --- /dev/null +++ b/tests/topotests/pim_acl/r15/zebra.conf @@ -0,0 +1,13 @@ +! +hostname r15 +log file zebra.log +! +interface lo + ip address 192.168.0.15/32 +! +interface r15-eth0 + description connection to r1 via sw1 + ip address 192.168.101.15/24 +! +ip route 0.0.0.0/0 192.168.101.1 +! diff --git a/tests/topotests/pim_acl/test_pim_acl.py b/tests/topotests/pim_acl/test_pim_acl.py new file mode 100755 index 0000000000..848f7fa8ed --- /dev/null +++ b/tests/topotests/pim_acl/test_pim_acl.py @@ -0,0 +1,418 @@ +#!/usr/bin/env python + +# +# test_pim_acl.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2020 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_pim_acl.py: Test PIM with RP selection using ACLs +""" + +# Test PIM RP selection with ACLs +# +# Testing RP selection with ACLs. R1 uses multiple ACLs +# to select desired RPs (R11 to R15) +# +# Test steps: +# - setup_module() +# Create topology. Hosts are only using zebra/staticd, +# no PIM, no OSPF (using IGMPv2 for multicast) +# - test_ospf_convergence() +# Wait for OSPF convergence in each VRF. OSPF is run on +# R1 and R11 - R15. +# - test_pim_convergence() +# Wait for PIM convergence on all routers. PIM is run on +# R1 and R11 - R15. +# - test_mcast_acl_1(): +# Test 1st ACL entry 239.100.0.0/28 with 239.100.0.1 which +# should use R11 as RP +# Stop multicast after verification +# - test_mcast_acl_2(): +# Test 2nd ACL entry 239.100.0.17/32 with 239.100.0.17 which +# should use R12 as RP +# Stop multicast after verification +# - test_mcast_acl_3(): +# Test 3rd ACL entry 239.100.0.32/27 with 239.100.0.32 which +# should use R13 as RP +# Stop multicast after verification +# - test_mcast_acl_4(): +# Test 4th ACL entry 239.100.0.128/25 with 239.100.0.255 which +# should use R14 as RP +# Stop multicast after verification +# - test_mcast_acl_5(): +# Test 5th ACL entry 239.100.0.96/28 with 239.100.0.97 which +# should use R14 as RP +# Stop multicast after verification +# - test_mcast_acl_6(): +# Test 6th ACL entry 239.100.0.64/28 with 239.100.0.70 which +# should use R15 as RP +# Stop multicast after verification +# - teardown_module() +# shutdown topology +# + + +TOPOLOGY = """ + +----------+ + | Host H2 | + | Source | + +----------+ + .2 | + +-----------+ | +----------+ + | | .1 | .11 | Host R11 | ++---------+ | R1 |---------+--------| PIM RP | +| Host H1 | 192.168.100.0/24 | | 192.168.101.0/24 +----------+ +| receive |------------------| uses ACLs | | +----------+ +|IGMP JOIN| .10 .1 | to pick | | .12 | Host R12 | ++---------+ | RP | +--------| PIM RP | + | | | +----------+ + +-----------+ | +----------+ + | .13 | Host R13 | + +--------| PIM RP | + | +----------+ + | +----------+ + | .14 | Host R14 | + +--------| PIM RP | + | +----------+ + | +----------+ + | .15 | Host R15 | + +--------| PIM RP | + +----------+ +""" + +import json +import functools +import os +import sys +import pytest +import re +import time +from time import sleep +import socket + +# 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. +from mininet.topo import Topo + +pytestmark = [pytest.mark.pimd] + + +# +# Test global variables: +# They are used to handle communicating with external application. +# +APP_SOCK_PATH = '/tmp/topotests/apps.sock' +HELPER_APP_PATH = os.path.join(CWD, "../lib/mcast-tester.py") +app_listener = None +app_clients = {} + +def listen_to_applications(): + "Start listening socket to connect with applications." + # Remove old socket. + try: + os.unlink(APP_SOCK_PATH) + except OSError: + pass + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) + sock.bind(APP_SOCK_PATH) + sock.listen(10) + global app_listener + app_listener = sock + +def accept_host(host): + "Accept connection from application running in hosts." + global app_listener, app_clients + conn = app_listener.accept() + app_clients[host] = { + 'fd': conn[0], + 'address': conn[1] + } + +def close_applications(): + "Signal applications to stop and close all sockets." + global app_listener, app_clients + + if app_listener: + # Close listening socket. + app_listener.close() + + # Remove old socket. + try: + os.unlink(APP_SOCK_PATH) + except OSError: + pass + + # Close all host connections. + for host in ["h1", "h2"]: + if app_clients.get(host) is None: + continue + app_clients[host]["fd"].close() + + # Reset listener and clients data struct + app_listener = None + app_clients = {} + + +class PIMACLTopo(Topo): + "PIM ACL Test Topology" + + def build(self): + tgen = get_topogen(self) + + # Create the hosts + for hostNum in range(1,3): + tgen.add_router("h{}".format(hostNum)) + + # Create the main router + tgen.add_router("r1") + + # Create the PIM RP routers + for rtrNum in range(11, 16): + tgen.add_router("r{}".format(rtrNum)) + + # Setup Switches and connections + for swNum in range(1, 3): + tgen.add_switch("sw{}".format(swNum)) + + # Add connections H1 to R1 switch sw1 + tgen.gears["h1"].add_link(tgen.gears["sw1"]) + tgen.gears["r1"].add_link(tgen.gears["sw1"]) + + # Add connections R1 to R1x switch sw2 + tgen.gears["r1"].add_link(tgen.gears["sw2"]) + tgen.gears["h2"].add_link(tgen.gears["sw2"]) + tgen.gears["r11"].add_link(tgen.gears["sw2"]) + tgen.gears["r12"].add_link(tgen.gears["sw2"]) + tgen.gears["r13"].add_link(tgen.gears["sw2"]) + tgen.gears["r14"].add_link(tgen.gears["sw2"]) + tgen.gears["r15"].add_link(tgen.gears["sw2"]) + + +##################################################### +# +# Tests starting +# +##################################################### + +def setup_module(module): + logger.info("PIM RP ACL Topology: \n {}".format(TOPOLOGY)) + + tgen = Topogen(PIMACLTopo, module.__name__) + tgen.start_topology() + + # Starting Routers + router_list = tgen.routers() + + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + if rname[0] != 'h': + # Only load ospf on routers, not on end hosts + router.load_config( + TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_PIM, os.path.join(CWD, "{}/pimd.conf".format(rname)) + ) + tgen.start_router() + + +def teardown_module(module): + tgen = get_topogen() + tgen.stop_topology() + close_applications() + + +def test_ospf_convergence(): + "Test for OSPFv2 convergence" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking OSPFv2 convergence on router r1") + + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/ospf_neighbor.json") + expected = json.loads(open(reffile).read()) + + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip ospf neighbor json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) + assertmsg = "OSPF router R1 did not converge" + assert res is None, assertmsg + + +def test_pim_convergence(): + "Test for PIM convergence" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking PIM convergence on router r1") + + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/pim_neighbor.json") + expected = json.loads(open(reffile).read()) + + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip pim neighbor json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) + assertmsg = "PIM router R1 did not converge" + assert res is None, assertmsg + + + +def check_mcast_entry(entry, mcastaddr, pimrp): + "Helper function to check RP" + tgen = get_topogen() + + logger.info("Testing PIM RP selection for ACL {} entry using {}".format(entry, mcastaddr)); + + # Start applications socket. + listen_to_applications() + + tgen.gears["h2"].run("{} --send='0.7' '{}' '{}' '{}' &".format( + HELPER_APP_PATH, APP_SOCK_PATH, mcastaddr, 'h2-eth0')) + accept_host("h2") + + tgen.gears["h1"].run("{} '{}' '{}' '{}' &".format( + HELPER_APP_PATH, APP_SOCK_PATH, mcastaddr, 'h1-eth0')) + accept_host("h1") + + logger.info("mcast join and source for {} started".format(mcastaddr)) + + # tgen.mininet_cli() + + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/acl_{}_pim_join.json".format(entry)) + expected = json.loads(open(reffile).read()) + + logger.info("verifying pim join on r1 for {}".format(mcastaddr)) + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip pim join json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) + assertmsg = "PIM router r1 did not show join status" + assert res is None, assertmsg + + logger.info("verifying pim join on PIM RP {} for {}".format(pimrp, mcastaddr)) + router = tgen.gears[pimrp] + reffile = os.path.join(CWD, "{}/acl_{}_pim_join.json".format(pimrp, entry)) + expected = json.loads(open(reffile).read()) + + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip pim join json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) + assertmsg = "PIM router {} did not get selected as the PIM RP".format(pimrp) + assert res is None, assertmsg + + close_applications() + return + + +def test_mcast_acl_1(): + "Test 1st ACL entry 239.100.0.0/28 with 239.100.0.1" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_mcast_entry(1, '239.100.0.1', 'r11') + + +def test_mcast_acl_2(): + "Test 2nd ACL entry 239.100.0.17/32 with 239.100.0.17" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_mcast_entry(2, '239.100.0.17', 'r12') + + +def test_mcast_acl_3(): + "Test 3rd ACL entry 239.100.0.32/27 with 239.100.0.32" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_mcast_entry(3, '239.100.0.32', 'r13') + + +def test_mcast_acl_4(): + "Test 4th ACL entry 239.100.0.128/25 with 239.100.0.255" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_mcast_entry(4, '239.100.0.255', 'r14') + + +def test_mcast_acl_5(): + "Test 5th ACL entry 239.100.0.96/28 with 239.100.0.97" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_mcast_entry(5, '239.100.0.97', 'r14') + + +def test_mcast_acl_6(): + "Test 6th ACL entry 239.100.0.64/28 with 239.100.0.70" + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_mcast_entry(6, '239.100.0.70', 'r15') + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args))