]> git.puffer.fish Git - mirror/frr.git/commitdiff
tests: improve test bgp_snmp_bgp4v2mib for snmp multi path support 14889/head
authorFrancois Dumontet <francois.dumontet@6wind.com>
Wed, 4 Oct 2023 16:01:02 +0000 (18:01 +0200)
committerFrancois Dumontet <francois.dumontet@6wind.com>
Tue, 5 Dec 2023 14:51:52 +0000 (15:51 +0100)
multi path support by snmp implies change in configuration and expected
tests results.

ipv6 trap test output is now ordered to avoid radom result due to
timeline.

Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
tests/topotests/bgp_snmp_bgp4v2mib/r1/bgpd.conf
tests/topotests/bgp_snmp_bgp4v2mib/r2/bgpd.conf
tests/topotests/bgp_snmp_bgp4v2mib/r3/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_snmp_bgp4v2mib/r3/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_snmp_bgp4v2mib/rr/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_snmp_bgp4v2mib/rr/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_snmp_bgp4v2mib/test_bgp_snmp_bgp4v2mib.py
tests/topotests/lib/snmptest.py

index d82a21e1f9fea4e03c2d45c9d16f6809b1fa5944..144466e418da86817a4cee3f120ac622051ea120 100644 (file)
@@ -1,24 +1,28 @@
 !
+!debug bgp updates
+!
 router bgp 65001
  no bgp ebgp-requires-policy
  no bgp network import-check
  no bgp default ipv4-unicast
- neighbor 192.168.12.2 remote-as external
- neighbor 192.168.12.2 timers 1 3
- neighbor 192.168.12.2 timers connect 1
- neighbor 2001:db8::12:2 remote-as external
- neighbor 2001:db8::12:2 timers 1 3
- neighbor 2001:db8::12:2 timers connect 1
+ neighbor 192.168.12.4 remote-as external
+ neighbor 192.168.12.4 timers 1 3
+ neighbor 192.168.12.4 timers connect 1
+ neighbor 2001:db8::12:4 remote-as external
+ neighbor 2001:db8::12:4 timers 1 3
+ neighbor 2001:db8::12:4 timers connect 1
  !
  address-family ipv4 unicast
   network 10.0.0.0/31 route-map p1
   network 10.0.0.2/32 route-map p2
-  neighbor 192.168.12.2 activate
+  neighbor 192.168.12.4 activate
+  neighbor 192.168.12.4 addpath-tx-all-paths
+  network 10.10.10.10/32
  exit-address-family
  address-family ipv6 unicast
   network 2001:db8::1/128 route-map p1
   network 2001:db8:1::/56 route-map p2
-  neighbor 2001:db8::12:2 activate
+  neighbor 2001:db8::12:4 activate
  exit-address-family
 !
 route-map p1 permit 10
@@ -28,4 +32,3 @@ route-map p2 permit 10
  set metric 2
  set origin incomplete
 exit
-!
index cf0013e1b7a1439549787348a3067de06192e524..55686f407a7fc2de0f52b28fe6e7e3b7d34db7b2 100644 (file)
@@ -5,18 +5,20 @@ router bgp 65002
  no bgp ebgp-requires-policy
  no bgp network import-check
  no bgp default ipv4-unicast
- neighbor 192.168.12.1 remote-as external
- neighbor 192.168.12.1 timers 1 3
- neighbor 192.168.12.1 timers connect 1
- neighbor 2001:db8::12:1 remote-as external
- neighbor 2001:db8::12:1 timers 1 3
- neighbor 2001:db8::12:1 timers connect 1
+ neighbor 192.168.12.4 remote-as external
+ neighbor 192.168.12.4 timers 1 3
+ neighbor 192.168.12.4 timers connect 1
+ neighbor 2001:db8::12:4 remote-as external
+ neighbor 2001:db8::12:4 timers 1 3
+ neighbor 2001:db8::12:4 timers connect 1
  !
  address-family ipv4 unicast
-  neighbor 192.168.12.1 activate
+  neighbor 192.168.12.4 activate
+  neighbor 192.168.12.4 addpath-tx-all-paths
+
  exit-address-family
  address-family ipv6 unicast
-  neighbor 2001:db8::12:1 activate
+  neighbor 2001:db8::12:4 activate
  exit-address-family
 !
 agentx
diff --git a/tests/topotests/bgp_snmp_bgp4v2mib/r3/bgpd.conf b/tests/topotests/bgp_snmp_bgp4v2mib/r3/bgpd.conf
new file mode 100644 (file)
index 0000000..71dbda0
--- /dev/null
@@ -0,0 +1,25 @@
+!
+!debug bgp updates
+!
+router bgp 65003
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ no bgp default ipv4-unicast
+ neighbor 192.168.12.4 remote-as external
+ neighbor 192.168.12.4 timers 1 3
+ neighbor 192.168.12.4 timers connect 1
+ neighbor 2001:db8::12:4 remote-as external
+ neighbor 2001:db8::12:4 timers 1 3
+ neighbor 2001:db8::12:4 timers connect 1
+ !
+ address-family ipv4 unicast
+  neighbor 192.168.12.4 activate
+  neighbor 192.168.12.4 addpath-tx-all-paths
+  network 10.10.10.10/32
+ exit-address-family
+ address-family ipv6 unicast
+  neighbor 2001:db8::12:4 activate
+ exit-address-family
+!
+agentx
+!
diff --git a/tests/topotests/bgp_snmp_bgp4v2mib/r3/zebra.conf b/tests/topotests/bgp_snmp_bgp4v2mib/r3/zebra.conf
new file mode 100644 (file)
index 0000000..398af65
--- /dev/null
@@ -0,0 +1,5 @@
+!
+interface r3-eth0
+ ip address 192.168.12.3/24
+ ipv6 address 2001:db8::12:3/64
+!
diff --git a/tests/topotests/bgp_snmp_bgp4v2mib/rr/bgpd.conf b/tests/topotests/bgp_snmp_bgp4v2mib/rr/bgpd.conf
new file mode 100644 (file)
index 0000000..5ebbde6
--- /dev/null
@@ -0,0 +1,67 @@
+!
+! debug bgp updates
+!
+router bgp 65004
+ no bgp ebgp-requires-policy
+ no bgp network import-check
+ no bgp default ipv4-unicast
+ neighbor 192.168.12.1 remote-as external
+ neighbor 192.168.12.1 timers 1 3
+ neighbor 192.168.12.1 timers connect 1
+ neighbor 192.168.12.2 remote-as external
+ neighbor 192.168.12.2 timers 1 3
+ neighbor 192.168.12.2 timers connect 1
+ neighbor 192.168.12.3 remote-as external
+ neighbor 192.168.12.3 timers 1 3
+ neighbor 192.168.12.3 timers connect 1
+ neighbor 2001:db8::12:1 remote-as external
+ neighbor 2001:db8::12:1 timers 1 3
+ neighbor 2001:db8::12:1 timers connect 1
+ neighbor 2001:db8::12:2 remote-as external
+ neighbor 2001:db8::12:2 timers 1 3
+ neighbor 2001:db8::12:2 timers connect 1
+ neighbor 2001:db8::12:3 remote-as external
+ neighbor 2001:db8::12:3 timers 1 3
+ neighbor 2001:db8::12:3 timers connect 1
+ !
+ address-family ipv4 unicast
+  network 10.0.0.0/31 route-map p1
+  network 10.0.0.2/32 route-map p2
+  neighbor 192.168.12.1 activate
+  neighbor 192.168.12.2 activate
+  neighbor 192.168.12.2 addpath-tx-all-paths
+  neighbor 192.168.12.2 route-map r2-import in
+  neighbor 192.168.12.2 route-map r2-export out
+!  neighbor 192.168.12.2 soft-reconfiguration inbound
+  neighbor 192.168.12.3 activate
+ exit-address-family
+ address-family ipv6 unicast
+  network 2001:db8::1/128 route-map p1
+  network 2001:db8:1::/56 route-map p2
+  neighbor 2001:db8::12:1 activate
+  neighbor 2001:db8::12:2 activate
+  neighbor 2001:db8::12:2  addpath-tx-all-paths
+  neighbor 2001:db8::12:3 activate
+ exit-address-family
+
+
+ip prefix-list r2-toto permit any
+
+route-map r2-import permit 10
+ match ip address prefix-list r2-toto
+
+route-map r2-export permit 10
+ match ip address prefix-list r2-toto
+!
+route-map p1 permit 10
+ set metric 1
+exit
+route-map p2 permit 10
+ set metric 2
+ set origin incomplete
+exit
+
+
+
+agentx
+!
diff --git a/tests/topotests/bgp_snmp_bgp4v2mib/rr/zebra.conf b/tests/topotests/bgp_snmp_bgp4v2mib/rr/zebra.conf
new file mode 100644 (file)
index 0000000..092673b
--- /dev/null
@@ -0,0 +1,5 @@
+!
+interface rr-eth0
+ ip address 192.168.12.4/24
+ ipv6 address 2001:db8::12:4/64
+!
index 14dadd45045b2662f51577b32a65adc95ef9fd7e..8cd49e35483f1ec382a3ba0becc6b14a68bfa202 100755 (executable)
@@ -32,10 +32,14 @@ pytestmark = [pytest.mark.bgpd, pytest.mark.snmp]
 def build_topo(tgen):
     tgen.add_router("r1")
     tgen.add_router("r2")
+    tgen.add_router("r3")
+    tgen.add_router("rr")
 
     switch = tgen.add_switch("s1")
     switch.add_link(tgen.gears["r1"])
     switch.add_link(tgen.gears["r2"])
+    switch.add_link(tgen.gears["r3"])
+    switch.add_link(tgen.gears["rr"])
 
 
 def setup_module(mod):
@@ -57,14 +61,15 @@ def setup_module(mod):
             "-M snmp",
         )
 
-    tgen.gears["r2"].load_config(
+    r2 = tgen.gears["r2"]
+    r2.load_config(
         TopoRouter.RD_SNMP,
-        os.path.join(CWD, "{}/snmpd.conf".format(rname)),
+        os.path.join(CWD, "{}/snmpd.conf".format(r2.name)),
         "-Le -Ivacm_conf,usmConf,iquery -V -DAgentX",
     )
-    tgen.gears["r2"].load_config(
+    r2.load_config(
         TopoRouter.RD_TRAP,
-        os.path.join(CWD, "{}/snmptrapd.conf".format(rname)),
+        os.path.join(CWD, "{}/snmptrapd.conf".format(r2.name)),
         " -On -OQ ",
     )
 
@@ -81,27 +86,29 @@ def test_bgp_snmp_bgp4v2():
 
     r1 = tgen.gears["r1"]
     r2 = tgen.gears["r2"]
+    rr = tgen.gears["rr"]
 
     def _bgp_converge_summary():
         output = json.loads(r2.vtysh_cmd("show bgp summary json"))
         expected = {
             "ipv4Unicast": {
                 "peers": {
-                    "192.168.12.1": {
+                    "192.168.12.4": {
                         "state": "Established",
-                        "pfxRcd": 2,
+                        "pfxRcd": 6,
                     }
                 }
             },
             "ipv6Unicast": {
                 "peers": {
-                    "2001:db8::12:1": {
+                    "2001:db8::12:4": {
                         "state": "Established",
-                        "pfxRcd": 2,
+                        "pfxRcd": 4,
                     }
                 }
             },
         }
+        # tgen.mininet_cli()
         return topotest.json_cmp(output, expected)
 
     test_func = functools.partial(_bgp_converge_summary)
@@ -144,6 +151,7 @@ def test_bgp_snmp_bgp4v2():
                 }
             },
         }
+        # tgen.mininet_cli()
         return topotest.json_cmp(output, expected)
 
     test_func = functools.partial(_bgp_converge_prefixes)
@@ -154,11 +162,12 @@ def test_bgp_snmp_bgp4v2():
 
     def _snmpwalk_remote_addr():
         expected = {
-            "1.3.6.1.3.5.1.1.2.1.5.1.1.192.168.12.1": "C0 A8 0C 01",
-            "1.3.6.1.3.5.1.1.2.1.5.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1": "20 01 0D B8 00 00 00 00 00 00 00 00 00 12 00 01",
+            "1.3.6.1.3.5.1.1.2.1.5.1.1.192.168.12.4": "C0 A8 0C 04",
+            "1.3.6.1.3.5.1.1.2.1.5.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4": "20 01 0D B8 00 00 00 00 00 00 00 00 00 12 00 04",
         }
 
         # bgp4V2PeerRemoteAddr
+        # tgen.mininet_cli()
         output, _ = snmp.walk(".1.3.6.1.3.5.1.1.2.1.5")
         return output == expected
 
@@ -168,8 +177,8 @@ def test_bgp_snmp_bgp4v2():
 
     def _snmpwalk_peer_state():
         expected = {
-            "1.3.6.1.3.5.1.1.2.1.13.1.1.192.168.12.1": "6",
-            "1.3.6.1.3.5.1.1.2.1.13.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1": "6",
+            "1.3.6.1.3.5.1.1.2.1.13.1.1.192.168.12.4": "6",
+            "1.3.6.1.3.5.1.1.2.1.13.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4": "6",
         }
 
         # bgp4V2PeerState
@@ -182,8 +191,8 @@ def test_bgp_snmp_bgp4v2():
 
     def _snmpwalk_peer_last_error_code_received():
         expected = {
-            "1.3.6.1.3.5.1.1.3.1.1.1.1.192.168.12.1": "0",
-            "1.3.6.1.3.5.1.1.3.1.1.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1": "0",
+            "1.3.6.1.3.5.1.1.3.1.1.1.1.192.168.12.4": "0",
+            "1.3.6.1.3.5.1.1.3.1.1.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4": "0",
         }
 
         # bgp4V2PeerLastErrorCodeReceived
@@ -198,14 +207,19 @@ def test_bgp_snmp_bgp4v2():
 
     def _snmpwalk_origin():
         expected = {
-            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.0.0.0.31.1.192.168.12.1.1": "1",
-            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.0.0.2.32.1.192.168.12.1.1": "3",
-            "1.3.6.1.3.5.1.1.9.1.9.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.0.0.1.128.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1.1": "1",
-            "1.3.6.1.3.5.1.1.9.1.9.1.2.1.2.32.1.13.184.0.1.0.0.0.0.0.0.0.0.0.0.56.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1.1": "3",
+            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.10.10.10.32.1.192.168.12.4.1": "1",
+            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.10.10.10.32.1.192.168.12.4.2": "1",
+            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.0.0.0.31.1.192.168.12.4.1": "1",
+            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.0.0.0.31.1.192.168.12.4.2": "1",
+            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.0.0.2.32.1.192.168.12.4.1": "3",
+            "1.3.6.1.3.5.1.1.9.1.9.1.1.1.1.10.0.0.2.32.1.192.168.12.4.2": "3",
+            "1.3.6.1.3.5.1.1.9.1.9.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.0.0.1.128.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.1": "1",
+            "1.3.6.1.3.5.1.1.9.1.9.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.0.0.1.128.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.2": "1",
+            "1.3.6.1.3.5.1.1.9.1.9.1.2.1.2.32.1.13.184.0.1.0.0.0.0.0.0.0.0.0.0.56.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.1": "3",
+            "1.3.6.1.3.5.1.1.9.1.9.1.2.1.2.32.1.13.184.0.1.0.0.0.0.0.0.0.0.0.0.56.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.2": "3",
         }
 
         # bgp4V2NlriOrigin
-        # tgen.mininet_cli()
         output, _ = snmp.walk(".1.3.6.1.3.5.1.1.9.1.9")
         return output == expected
 
@@ -215,10 +229,16 @@ def test_bgp_snmp_bgp4v2():
 
     def _snmpwalk_med():
         expected = {
-            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.0.0.0.31.1.192.168.12.1.1": "1",
-            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.0.0.2.32.1.192.168.12.1.1": "2",
-            "1.3.6.1.3.5.1.1.9.1.17.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.0.0.1.128.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1.1": "1",
-            "1.3.6.1.3.5.1.1.9.1.17.1.2.1.2.32.1.13.184.0.1.0.0.0.0.0.0.0.0.0.0.56.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1.1": "2",
+            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.10.10.10.32.1.192.168.12.4.1": "0",
+            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.10.10.10.32.1.192.168.12.4.2": "0",
+            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.0.0.0.31.1.192.168.12.4.1": "1",
+            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.0.0.0.31.1.192.168.12.4.2": "0",
+            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.0.0.2.32.1.192.168.12.4.1": "2",
+            "1.3.6.1.3.5.1.1.9.1.17.1.1.1.1.10.0.0.2.32.1.192.168.12.4.2": "0",
+            "1.3.6.1.3.5.1.1.9.1.17.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.0.0.1.128.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.1": "1",
+            "1.3.6.1.3.5.1.1.9.1.17.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.0.0.1.128.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.2": "0",
+            "1.3.6.1.3.5.1.1.9.1.17.1.2.1.2.32.1.13.184.0.1.0.0.0.0.0.0.0.0.0.0.56.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.1": "2",
+            "1.3.6.1.3.5.1.1.9.1.17.1.2.1.2.32.1.13.184.0.1.0.0.0.0.0.0.0.0.0.0.56.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4.2": "0",
         }
 
         # bgp4V2NlriMed
@@ -230,96 +250,65 @@ def test_bgp_snmp_bgp4v2():
     assertmsg = "Can't fetch SNMP for bgp4V2NlriMed"
     assert result, assertmsg
 
+    #
+    # traps
+    #
+
+    #
+    # bgp4 traps
+    #
     def _snmptrap_ipv4():
-        expected = [
-            ("1.3.6.1.2.1.15.3.1.7.192.168.12.1", "192.168.12.1"),
-            ("1.3.6.1.2.1.15.3.1.14.192.168.12.1", '"06 04 "'),
-            ("1.3.6.1.2.1.15.3.1.2.192.168.12.1", "7"),
-            ("1.3.6.1.2.1.15.3.1.7.192.168.12.1", "192.168.12.1"),
-            ("1.3.6.1.2.1.15.3.1.14.192.168.12.1", '"06 04 "'),
-            ("1.3.6.1.2.1.15.3.1.2.192.168.12.1", "6"),
-        ]
-
-        # load trapd resulting file
-        # tgen.mininet_cli()
+        def __get_notif_bgp4_in_trap_file(router):
+            snmptrapfile = "{}/{}/snmptrapd.log".format(router.logdir, router.name)
+            outputfile = open(snmptrapfile).read()
+            output = snmp.get_notif_bgp4(outputfile)
 
-        snmptrapfile = "{}/{}/snmptrapd.log".format(r2.logdir, r2.name)
-        outputfile = open(snmptrapfile).read()
-        output = snmp.trap(outputfile)
-        return output == expected
+            return output
+
+        output = __get_notif_bgp4_in_trap_file(r2)
+        logger.info("output bgp4")
+        logger.info(output)
+        return snmp.is_notif_bgp4_valid(output, "192.168.12.4")
 
     # skip tests is SNMP not installed
     if not os.path.isfile("/usr/sbin/snmptrapd"):
         error_msg = "SNMP not installed - skipping"
         pytest.skip(error_msg)
 
-    snmptrapfile = "{}/{}/snmptrapd.log".format(r2.logdir, r2.name)
-    trap_file = open(snmptrapfile, "w")
-    trap_file.truncate(0)
-    trap_file.close()
-    r1.vtysh_cmd("clear bgp *")
+    rr.vtysh_cmd("clear bgp *")
     _, result = topotest.run_and_expect(_snmptrap_ipv4, True, count=2, wait=10)
     assertmsg = "Can't fetch SNMP trap for ipv4"
     assert result, assertmsg
 
+    #
+    # bgp4v2 traps
+    #
     def _snmptrap_ipv6():
-        expected = [
-            ("1.3.6.1.3.5.1.1.2.1.13.1.1.192.168.12.1", "7"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.1.192.168.12.1", "179"),
-            ("1.3.6.1.3.5.1.1.3.1.1.1.1.192.168.12.1", "6"),
-            ("1.3.6.1.3.5.1.1.3.1.2.1.1.192.168.12.1", "4"),
-            ("1.3.6.1.3.5.1.1.3.1.4.1.1.192.168.12.1", '"00 "'),
-            ("1.3.6.1.3.5.1.1.2.1.13.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "7"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "179"),
-            ("1.3.6.1.3.5.1.1.3.1.1.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "6"),
-            ("1.3.6.1.3.5.1.1.3.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "4"),
-            (
-                "1.3.6.1.3.5.1.1.3.1.4.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1",
-                '"00 "',
-            ),
-            ("1.3.6.1.3.5.1.1.2.1.13.1.1.192.168.12.1", "6"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.1.192.168.12.1", "179"),
-            ("1.3.6.1.3.5.1.1.2.1.13.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "6"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "179"),
-        ]
-
-        expected2 = [
-            ("1.3.6.1.3.5.1.1.2.1.13.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "7"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "179"),
-            ("1.3.6.1.3.5.1.1.3.1.1.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "6"),
-            ("1.3.6.1.3.5.1.1.3.1.2.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "4"),
-            (
-                "1.3.6.1.3.5.1.1.3.1.4.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1",
-                '"00 "',
-            ),
-            ("1.3.6.1.3.5.1.1.2.1.13.1.1.192.168.12.1", "7"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.1.192.168.12.1", "179"),
-            ("1.3.6.1.3.5.1.1.3.1.1.1.1.192.168.12.1", "6"),
-            ("1.3.6.1.3.5.1.1.3.1.2.1.1.192.168.12.1", "4"),
-            ("1.3.6.1.3.5.1.1.3.1.4.1.1.192.168.12.1", '"00 "'),
-            ("1.3.6.1.3.5.1.1.2.1.13.1.1.192.168.12.1", "6"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.1.192.168.12.1", "179"),
-            ("1.3.6.1.3.5.1.1.2.1.13.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "6"),
-            ("1.3.6.1.3.5.1.1.2.1.6.1.2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.1", "179"),
-        ]
-
-        # load trapd resulting file
-        # tgen.mininet_cli()
+        def __get_notif_bgp4v2_in_trap_file(router):
+            snmptrapfile = "{}/{}/snmptrapd.log".format(router.logdir, router.name)
+            outputfile = open(snmptrapfile).read()
+            output = snmp.get_notif_bgp4v2(outputfile)
 
-        snmptrapfile = "{}/{}/snmptrapd.log".format(r2.logdir, r2.name)
-        outputfile = open(snmptrapfile).read()
-        output = snmp.trap(outputfile)
+            return output
+
+        # tgen.mininet_cli()
+        output = __get_notif_bgp4v2_in_trap_file(r2)
+        logger.info("output bgp4v2")
         logger.info(output)
-        output_cut = output[:14]
-        return output_cut == expected or output_cut == expected2
+        p_ipv4_addr = "1.192.168.12.4"
+        p_ipv6_addr = "2.32.1.13.184.0.0.0.0.0.0.0.0.0.18.0.4"
+        return (
+            snmp.is_notif_bgp4v2_valid(output, p_ipv4_addr, "Estab")
+            and snmp.is_notif_bgp4v2_valid(output, p_ipv6_addr, "Estab")
+            and snmp.is_notif_bgp4v2_valid(output, p_ipv4_addr, "Backward")
+            and snmp.is_notif_bgp4v2_valid(output, p_ipv6_addr, "Backward")
+        )
 
-    snmptrapfile = "{}/{}/snmptrapd.log".format(r2.logdir, r2.name)
-    trap_file = open(snmptrapfile, "w")
-    trap_file.truncate(0)
-    trap_file.close()
+    sleep(10)
     r2.vtysh_cmd("conf\nbgp snmp traps bgp4-mibv2")
     r2.vtysh_cmd("conf\nno bgp snmp traps rfc4273")
-    r1.vtysh_cmd("clear bgp *")
+    rr.vtysh_cmd("clear bgp *")
+    sleep(30)
     _, result = topotest.run_and_expect(_snmptrap_ipv6, True, count=2, wait=10)
     assertmsg = "Can't fetch SNMP trap for ipv6"
     assert result, assertmsg
index 598ad05f589773db42d6a3e1e8f284879787b4ea..5c4e97a5d245e950c09767ef7ea794a45006c12b 100644 (file)
@@ -73,39 +73,6 @@ class SnmpTester(object):
         # third token onwards is the value of the object
         return tokens[0].split(".", 1)[1]
 
-    def _parse_notification_trap(self, snmp_out):
-        # we use the "=" as separator thus we will have
-        # element of list formated "value   oid"
-        # value for index i is corresponding to index i-1
-        results = snmp_out.strip().split("=")
-
-        # remove the notification part date, notification OID
-        del results[0:2]
-
-        index = 0
-        oid_list = []
-        next_oid = ""
-        oid = ""
-        while index < len(results):
-            result = results[index].strip().split()
-            if index < len(results) - 1:
-                raw_oid = result[-1]
-                # remove initial "." of oid
-                next_oid = raw_oid.split(".", 1)[1]
-                # remove oid from result to have only value
-                del result[-1]
-            if index > 0:
-                value = " ".join(result)
-                # ignore remote port oid 1.3.6.1.3.5.1.1.2.1.9 since
-                # it's value is variable
-                local_port = re.search("1.3.6.1.3.5.1.1.2.1.9", oid)
-                if not local_port:
-                    oid_list.append((oid, value))
-
-            oid = next_oid
-            index += 1
-        return oid_list
-
     def _parse_multiline(self, snmp_output):
         results = snmp_output.strip().split("\n")
 
@@ -117,15 +84,6 @@ class SnmpTester(object):
 
         return out_dict, out_list
 
-    def _parse_multiline_trap(self, results):
-        out_list = []
-        results = [elem for index, elem in enumerate(results) if index % 2 != 0]
-
-        for response in results:
-            oid_list = self._parse_notification_trap(response)
-            out_list += oid_list
-        return out_list
-
     def get(self, oid):
         cmd = "snmpget {0} {1}".format(self._snmp_config(), oid)
 
@@ -149,10 +107,148 @@ class SnmpTester(object):
         result = self.router.cmd(cmd)
         return self._parse_multiline(result)
 
-    def trap(self, outputfile):
-        whitecleanfile = re.sub("\t", " ", outputfile)
+    def parse_notif_ipv4(self, notif):
+        # normalise values
+        notif = re.sub(":", "", notif)
+        notif = re.sub('"([0-9]{2}) ([0-9]{2}) "', r"\1\2", notif)
+        notif = re.sub('"([0-9]{2}) "', r"\1", notif)
+        elems = re.findall("([0-9,\.]+) = ([0-9,\.]+)", notif)
+
+        # remove common part
+        elems = elems[1:]
+        return elems
+
+    def is_notif_bgp4_valid(self, output_list, address):
+        oid_notif_type = ".1.3.6.1.6.3.1.1.4.1.0"
+        peer_notif_established = ".1.3.6.1.2.1.15.0.1"
+        peer_notif_backward = ".1.3.6.1.2.1.15.0.2"
+        oid_peer_last_error = ".1.3.6.1.2.1.15.3.1.14"
+        oid_peer_remote_addr = ".1.3.6.1.2.1.15.3.1.7"
+        oid_peer_state = ".1.3.6.1.2.1.15.3.1.2"
+
+        nb_notif = len(output_list)
+        for nb in range(0, nb_notif - 1):
+            # identify type of notification
+            # established or BackwardTransition
+
+            if output_list[nb][0][0] != "{}".format(oid_notif_type):
+                return False
+
+            if output_list[nb][0][1] == "{}".format(peer_notif_established):
+                logger.info("Established notification")
+            elif output_list[nb][0][1] == "{}".format(peer_notif_backward):
+                logger.info("Backward transition notification")
+            else:
+                return False
+
+            # same behavior for 2 notification type in bgp4
+            if output_list[nb][1][0] != "{}.{}".format(oid_peer_remote_addr, address):
+                return False
+
+            if output_list[nb][2][0] != "{}.{}".format(oid_peer_last_error, address):
+                return False
+            if output_list[nb][3][0] != "{}.{}".format(oid_peer_state, address):
+                return False
+
+        return True
+
+    def is_notif_bgp4v2_valid(self, output_list, address, type_requested):
+        oid_notif_type = ".1.3.6.1.6.3.1.1.4.1.0"
+        peer_notif_established = ".1.3.6.1.3.5.1.0.1"
+        peer_notif_backward = ".1.3.6.1.3.5.1.0.2"
+        oid_peer_state = ".1.3.6.1.3.5.1.1.2.1.13"
+        oid_peer_local_port = ".1.3.6.1.3.5.1.1.2.1.6"
+        oid_peer_remote_port = ".1.3.6.1.3.5.1.1.2.1.9"
+        oid_peer_err_code_recv = ".1.3.6.1.3.5.1.1.3.1.1"
+        oid_peer_err_sub_code_recv = ".1.3.6.1.3.5.1.1.3.1.2"
+        oid_peer_err_recv_text = ".1.3.6.1.3.5.1.1.3.1.4"
+
+        nb_notif = len(output_list)
+        for nb in range(nb_notif):
+            if output_list[nb][0][0] != "{}".format(oid_notif_type):
+                return False
+
+            if output_list[nb][0][1] == "{}".format(peer_notif_established):
+                logger.info("Established notification")
+                notif_type = "Estab"
+
+            elif output_list[nb][0][1] == "{}".format(peer_notif_backward):
+                logger.info("Backward transition notification")
+                notif_type = "Backward"
+            else:
+                return False
+
+            if notif_type != type_requested:
+                continue
+
+            if output_list[nb][1][0] != "{}.1.{}".format(oid_peer_state, address):
+                continue
+
+            if output_list[nb][2][0] != "{}.1.{}".format(oid_peer_local_port, address):
+                return False
+
+            if output_list[nb][3][0] != "{}.1.{}".format(oid_peer_remote_port, address):
+                return False
+
+            if notif_type == "Estab":
+                return True
+
+            if output_list[nb][4][0] != "{}.1.{}".format(
+                oid_peer_err_code_recv, address
+            ):
+                return False
+
+            if output_list[nb][5][0] != "{}.1.{}".format(
+                oid_peer_err_sub_code_recv, address
+            ):
+                return False
+
+            if output_list[nb][6][0] != "{}.1.{}".format(
+                oid_peer_err_recv_text, address
+            ):
+                return False
+
+            return True
+
+        return False
+
+    def get_notif_bgp4(self, output_file):
+        notif_list = []
+        whitecleanfile = re.sub("\t", " ", output_file)
         results = whitecleanfile.strip().split("\n")
-        return self._parse_multiline_trap(results)
+
+        # don't consider SNMP additional messages
+        notifs_first = [elem for elem in results if not ("SNMP" in elem)]
+        # don't consider additional application messages
+        notifs = [elem for index, elem in enumerate(notifs_first) if index % 2 != 0]
+
+        oid_v4 = "1\.3\.6\.1\.2\.1\.15"
+        for one_notif in notifs:
+            is_ipv4_notif = re.search(oid_v4, one_notif)
+            if is_ipv4_notif != None:
+                formated_notif = self.parse_notif_ipv4(one_notif)
+                notif_list.append(formated_notif)
+
+        return notif_list
+
+    def get_notif_bgp4v2(self, output_file):
+        notif_list = []
+        whitecleanfile = re.sub("\t", " ", output_file)
+        results = whitecleanfile.strip().split("\n")
+
+        # don't consider SNMP additional messages
+        notifs_first = [elem for elem in results if not ("SNMP" in elem)]
+        # don't consider additional application messages
+        notifs = [elem for index, elem in enumerate(results) if index % 2 != 0]
+
+        oid_v6 = "1\.3\.6\.1\.3\.5\.1"
+        for one_notif in notifs:
+            is_ipv6_notif = re.search(oid_v6, one_notif)
+            if is_ipv6_notif != None:
+                formated_notif = self.parse_notif_ipv4(one_notif)
+                notif_list.append(formated_notif)
+
+        return notif_list
 
     def test_oid(self, oid, value):
         print("oid: {}".format(self.get_next(oid)))