VPI-based platform support.
diff --git a/platforms/bpp.py b/platforms/bpp.py
new file mode 100644
index 0000000..3f24949
--- /dev/null
+++ b/platforms/bpp.py
@@ -0,0 +1,73 @@
+"""
+Platform configuration file
+platform == bpp
+"""
+
+###############################################################################
+#
+# This platform assumes BPP VPI specifications on the command line.
+#
+###############################################################################
+
+import sys
+import os
+import argparse
+import subprocess
+import dppv
+
+# The port specification is passed via the "--platform-args" option to OFTest.
+# Note that we must guard against abbreviations supported by argparse
+if not "--platform-args" in " ".join(sys.argv):
+ raise Exception("--platform-args must be specified")
+
+ap = argparse.ArgumentParser("bpp")
+ap.add_argument("--platform-args")
+(ops, rest) = ap.parse_known_args()
+
+if not "@" in ops.platform_args:
+ # Assume it is just a device name. Get the ports from the track database.
+ if "," in ops.platform_args:
+ (type_, d) = ops.platform_args.split(",")
+ else:
+ (type_, d) = ("udp", ops.platform_args)
+
+ trackScript = "/usr/bin/track"
+ if not os.path.exists(trackScript):
+ raise Exception("Cannot find the track script (looked at %s" % trackScript)
+
+ ports = eval("[" + subprocess.check_output([trackScript, "getports", d]) + "]")
+ ops.platform_args = type_ + "," + ",".join( "%s@%s:%s" % (p, d, p) for p in ports)
+
+ print "new platform_args: ", ops.platform_args
+ exit;
+#
+###############################################################################
+
+vpi_port_map = {}
+ports = ops.platform_args.split(",")
+bpptype = "udp"
+if ports[0] == "udp" or ports[0] == "tcp":
+ bpptype = ports.pop(0)
+
+for ps in ports:
+ (p, vpi) = ps.split("@")
+ vpi_port_map[int(p)] = "bpp|%s|%s" % (bpptype, vpi)
+
+print vpi_port_map;
+
+def platform_config_update(config):
+ """
+ Update configuration for the remote platform
+
+ @param config The configuration dictionary to use/update
+ This routine defines the port map used for this configuration
+ """
+
+ global vpi_port_map
+ config["port_map"] = vpi_port_map.copy()
+ config["caps_table_idx"] = 0
+ #
+ # The class for DataPlanePorts must be specified here:
+ #
+ config['dataplane'] = { 'portclass': dppv.DataPlanePortVPI }
+ config['allow_user'] = True
diff --git a/platforms/dppv.py b/platforms/dppv.py
new file mode 100644
index 0000000..2d72997
--- /dev/null
+++ b/platforms/dppv.py
@@ -0,0 +1,79 @@
+###############################################################################
+#
+# DataPlanePort implementation for VPI platforms.
+#
+# The VPI-based platforms available here (bpp and vpi) depend upon
+# this module for the implementation of the OFTest DataPlanePort interface.
+#
+###############################################################################
+import sys
+import os
+import logging
+import time
+
+from oftest import config
+
+# Requires the libvpi and pyvpi packages
+from vpi import vpi
+
+class DataPlanePortVPI:
+ """
+ Class defining a port monitoring VPI object.
+
+ """
+
+ #
+ # OFTest creates and destroys DataPlanePorts for each test.
+ # We just cache them here.
+ cachedVPIs = {}
+
+ def vpiInit(self, interface_name, port_number, pcap_dir="."):
+ self.vpiSpec = interface_name;
+ if self.vpiSpec in self.cachedVPIs:
+ self.vpi = self.cachedVPIs[self.vpiSpec]
+ else:
+ self.vpi = vpi.Vpi(self.vpiSpec)
+ pcapspec = "pcapdump|%s/oft-port%.2d.pcap|mpls|PORT%d" % (pcap_dir, port_number, port_number)
+ self.vpi.AddSendRecvListener(pcapspec);
+ self.cachedVPIs[self.vpiSpec] = self.vpi
+
+ return self.vpi
+
+
+ def __init__(self, interface_name, port_number):
+ """
+ Set up a port monitor object
+ @param interface_name The name of the physical interface like eth1
+ @param port_number The port number associated with this port
+ """
+ self.interface_name = interface_name
+ self.port_number = port_number
+ logname = "VPI:" + interface_name
+ self.logger = logging.getLogger(logname)
+
+ path = "."
+ if config['log_file']:
+ path = config['log_file']
+
+ if self.vpiInit(interface_name, port_number,
+ os.path.dirname(os.path.abspath(path))) == None:
+ raise Exception("Could not create VPI interface %s" % interface_name)
+
+ self.logger.info("VPI: %s:%d\n" % (interface_name, port_number))
+
+ def fileno(self):
+ return self.vpi.DescriptorGet()
+
+ def recv(self):
+ pkt = self.vpi.Recv(False)
+ return (pkt, time.time())
+
+ def send(self, packet):
+ """
+ Send a packet to the dataplane port
+ @param packet The packet data to send to the port
+ @retval The number of bytes sent
+ """
+ _len = len(packet);
+ self.vpi.Send(packet)
+ return _len;
diff --git a/platforms/vpip.py b/platforms/vpip.py
new file mode 100644
index 0000000..518760e
--- /dev/null
+++ b/platforms/vpip.py
@@ -0,0 +1,49 @@
+"""
+Platform configuration file
+platform == vpi
+"""
+
+###############################################################################
+#
+# This platform module allows VPI port specifications on the command line.
+#
+###############################################################################
+
+import sys
+import os
+import argparse
+import dppv
+
+# The port specification is passed via the "--platform-args" option to OFTest.
+# Note that we must guard against abbreviations supported by argparse
+if not "--platform-args" in " ".join(sys.argv):
+ raise Exception("--platform-args must be specified")
+
+ap = argparse.ArgumentParser("vpi")
+ap.add_argument("--platform-args")
+(ops, rest) = ap.parse_known_args()
+
+vpi_port_map = {}
+ports = ops.platform_args.split(",")
+for ps in ports:
+ (p, vpi) = ps.split("@")
+ vpi_port_map[int(p)] = vpi
+
+print vpi_port_map;
+
+def platform_config_update(config):
+ """
+ Update configuration for the remote platform
+
+ @param config The configuration dictionary to use/update
+ This routine defines the port map used for this configuration
+ """
+
+ global vpi_port_map
+ config["port_map"] = vpi_port_map.copy()
+ config["caps_table_idx"] = 0
+ #
+ # The class for DataPlanePorts must be specified here:
+ #
+ config['dataplane'] = { 'portclass': dppv.DataPlanePortVPI }
+ config['allow_user'] = True