]> git.puffer.fish Git - matthieu/frr.git/commitdiff
tests: lib add support of snmptrapd daemon
authorFrancois Dumontet <francois.dumontet@6wind.com>
Tue, 26 Sep 2023 12:07:00 +0000 (14:07 +0200)
committerFrancois Dumontet <francois.dumontet@6wind.com>
Tue, 24 Oct 2023 15:16:47 +0000 (17:16 +0200)
Signed-off-by: Francois Dumontet <francois.dumontet@6wind.com>
tests/topotests/lib/snmptest.py
tests/topotests/lib/topogen.py
tests/topotests/lib/topotest.py

index e7cd657b20274e629b108994de5a71d88538a4dd..598ad05f589773db42d6a3e1e8f284879787b4ea 100644 (file)
@@ -18,6 +18,7 @@ Basic usage instructions:
 """
 
 from lib.topolog import logger
+import re
 
 
 class SnmpTester(object):
@@ -72,15 +73,38 @@ class SnmpTester(object):
         # third token onwards is the value of the object
         return tokens[0].split(".", 1)[1]
 
-    @staticmethod
-    def _get_snmp_oid(snmp_output):
-        tokens = snmp_output.strip().split()
-
-        #        if len(tokens) > 5:
-        #            return None
-
-        # third token 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")
@@ -93,6 +117,15 @@ 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)
 
@@ -116,6 +149,11 @@ class SnmpTester(object):
         result = self.router.cmd(cmd)
         return self._parse_multiline(result)
 
+    def trap(self, outputfile):
+        whitecleanfile = re.sub("\t", " ", outputfile)
+        results = whitecleanfile.strip().split("\n")
+        return self._parse_multiline_trap(results)
+
     def test_oid(self, oid, value):
         print("oid: {}".format(self.get_next(oid)))
         return self.get_next(oid) == value
index 4d935b9538c523656f5f69531f2726f61e0412ab..48caf6f03a546c310cfd2bd6b6692bb7fa57a0d8 100644 (file)
@@ -744,6 +744,7 @@ class TopoRouter(TopoGear):
     RD_SNMP = 18
     RD_PIM6 = 19
     RD_MGMTD = 20
+    RD_TRAP = 21
     RD = {
         RD_FRR: "frr",
         RD_ZEBRA: "zebra",
@@ -766,6 +767,7 @@ class TopoRouter(TopoGear):
         RD_PATH: "pathd",
         RD_SNMP: "snmpd",
         RD_MGMTD: "mgmtd",
+        RD_TRAP: "snmptrapd",
     }
 
     def __init__(self, tgen, cls, name, **params):
@@ -842,7 +844,7 @@ class TopoRouter(TopoGear):
         TopoRouter.RD_RIPNG, TopoRouter.RD_OSPF, TopoRouter.RD_OSPF6,
         TopoRouter.RD_ISIS, TopoRouter.RD_BGP, TopoRouter.RD_LDP,
         TopoRouter.RD_PIM, TopoRouter.RD_PIM6, TopoRouter.RD_PBR,
-        TopoRouter.RD_SNMP, TopoRouter.RD_MGMTD.
+        TopoRouter.RD_SNMP, TopoRouter.RD_MGMTD, TopoRouter.RD_TRAP.
 
         Possible `source` values are `None` for an empty config file, a path name which is
         used directly, or a file name with no path components which is first looked for
@@ -880,7 +882,7 @@ class TopoRouter(TopoGear):
         # Enable all daemon command logging, logging files
         # and set them to the start dir.
         for daemon, enabled in nrouter.daemons.items():
-            if enabled and daemon != "snmpd":
+            if enabled and daemon != "snmpd" and daemon != "snmptrapd":
                 self.vtysh_cmd(
                     "\n".join(
                         [
index c220bcfed1b8b4d214d318f9b0339c5debd11c7d..7db4963154ae10b165ecbdd729aefa8a66c7afe1 100644 (file)
@@ -1261,8 +1261,8 @@ def rlimit_atleast(rname, min_value, raises=False):
 
 def fix_netns_limits(ns):
     # Maximum read and write socket buffer sizes
-    sysctl_atleast(ns, "net.ipv4.tcp_rmem", [10 * 1024, 87380, 16 * 2 ** 20])
-    sysctl_atleast(ns, "net.ipv4.tcp_wmem", [10 * 1024, 87380, 16 * 2 ** 20])
+    sysctl_atleast(ns, "net.ipv4.tcp_rmem", [10 * 1024, 87380, 16 * 2**20])
+    sysctl_atleast(ns, "net.ipv4.tcp_wmem", [10 * 1024, 87380, 16 * 2**20])
 
     sysctl_assure(ns, "net.ipv4.conf.all.rp_filter", 0)
     sysctl_assure(ns, "net.ipv4.conf.default.rp_filter", 0)
@@ -1321,8 +1321,8 @@ def fix_host_limits():
     sysctl_atleast(None, "net.core.netdev_max_backlog", 4 * 1024)
 
     # Maximum read and write socket buffer sizes
-    sysctl_atleast(None, "net.core.rmem_max", 16 * 2 ** 20)
-    sysctl_atleast(None, "net.core.wmem_max", 16 * 2 ** 20)
+    sysctl_atleast(None, "net.core.rmem_max", 16 * 2**20)
+    sysctl_atleast(None, "net.core.wmem_max", 16 * 2**20)
 
     # Garbage Collection Settings for ARP and Neighbors
     sysctl_atleast(None, "net.ipv4.neigh.default.gc_thresh2", 4 * 1024)
@@ -1420,6 +1420,7 @@ class Router(Node):
             "pathd": 0,
             "snmpd": 0,
             "mgmtd": 0,
+            "snmptrapd": 0,
         }
         self.daemons_options = {"zebra": ""}
         self.reportCores = True
@@ -1883,6 +1884,15 @@ class Router(Node):
                     daemon_opts
                 ) + "{}.pid -x /etc/frr/agentx".format(runbase)
                 # check_daemon_files.append(runbase + ".pid")
+            elif daemon == "snmptrapd":
+                binary = "/usr/sbin/snmptrapd"
+                cmdenv = ""
+                cmdopt = (
+                    "{} ".format(daemon_opts)
+                    + "-C -c /etc/{}/snmptrapd.conf".format(self.routertype)
+                    + " -p {}.pid".format(runbase)
+                    + " -LF 6-7 {}/{}/snmptrapd.log".format(self.logdir, self.name)
+                )
             else:
                 binary = os.path.join(self.daemondir, daemon)
                 check_daemon_files.extend([runbase + ".pid", runbase + ".vty"])
@@ -1922,6 +1932,7 @@ class Router(Node):
                         tail_log_files.append(
                             "{}/{}/{}.log".format(self.logdir, self.name, daemon)
                         )
+
             if extra_opts:
                 cmdopt += " " + extra_opts
 
@@ -1970,7 +1981,7 @@ class Router(Node):
                         "%s: %s %s started with perf", self, self.routertype, daemon
                     )
             else:
-                if daemon != "snmpd":
+                if daemon != "snmpd" and daemon != "snmptrapd":
                     cmdopt += " -d "
                 cmdopt += rediropt
 
@@ -2213,6 +2224,8 @@ class Router(Node):
         for daemon in self.daemons:
             if daemon == "snmpd":
                 continue
+            if daemon == "snmptrapd":
+                continue
             if (self.daemons[daemon] == 1) and not (daemon in daemonsRunning):
                 sys.stderr.write("%s: Daemon %s not running\n" % (self.name, daemon))
                 if daemon == "staticd":