From 57780492773463ca64285781ceb83da3aca871cc Mon Sep 17 00:00:00 2001 From: xirs Date: Wed, 6 Jul 2016 11:43:34 +0800 Subject: [PATCH 1/2] solaris support for send/recv msg at dataplane Solaris can use DLPI to send/recv L2 packet at dataplane. I write this file to help run OFTest at Solaris. --- platforms/solaris.py | 97 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 platforms/solaris.py diff --git a/platforms/solaris.py b/platforms/solaris.py new file mode 100644 index 000000000..955376d73 --- /dev/null +++ b/platforms/solaris.py @@ -0,0 +1,97 @@ +""" +Solaris platform uses dlpi + +This platform uses Solaris dlpi python interface. +""" +import sys +import time + +if "sunos" in sys.platform: + import dlpi + if not hasattr(dlpi, "DL_PROMISC_NOLOOP"): + dlpi.DL_PROMISC_NOLOOP = 0x10000000 +else: + raise Exception("system platform need be solaris") + +class DataPlanePortSolaris: + """ + Uses libdlpi to capture and send packets on a network interface. + """ + + RCV_SIZE_DEFAULT = 4096 + RCV_TIMEOUT = 10000 + + def __init__(self, interface_name, port_number): + """ + @param interface_name The name of the physical interface like net1 + """ + self.interface_name = interface_name + self.socket = dlpi.link(interface_name,dlpi.RAW) + self.socket.bind(dlpi.ANY_SAP) + self.socket.promiscon(dlpi.PROMISC_PHYS|dlpi.DL_PROMISC_NOLOOP) + # self.socket.promiscon(dlpi.PROMISC_SAP|dlpi.DL_PROMISC_NOLOOP) + # self.socket.promiscon(dlpi.PROMISC_MULTI|dlpi.DL_PROMISC_NOLOOP) + self.socket.set_timeout(self.RCV_TIMEOUT) + + def __del__(self): + if self.socket: + self.socket.unbind() + del self.socket + + def fileno(self): + """ + Return an integer file descriptor that can be passed to select(2). + """ + return self.socket.get_fd() + + def recv(self): + """ + Receive a packet from this port. + @retval (packet data, timestamp) + """ + src, pkt = self.socket.recv(self.RCV_SIZE_DEFAULT) + return (pkt, time.time()) + + def send(self, packet): + """ + Send a packet out this port. + @param packet The packet data to send to the port + @retval The number of bytes sent + """ + addr = self.socket.get_physaddr(dlpi.CURR_PHYS_ADDR) + self.socket.send(addr,packet) + return len(packet) + + + def down(self): + """ + Bring the physical link down. + """ + pass + + def up(self): + """ + Bring the physical link up. + """ + pass + + +# Update this dictionary to suit your environment. +solaris_port_map = { + 21 : "net2", + 22 : "net3", + 23 : "net4", + 24 : "net5" +} + +def platform_config_update(config): + """ + Update configuration for the Solaris platform + + @param config The configuration dictionary to use/update + """ + global solaris_port_map + config["port_map"] = solaris_port_map.copy() + config["caps_table_idx"] = 0 + config["dataplane"] = {"portclass": DataPlanePortSolaris} + config["allow_user"] = True From f354742822a6345f37c0e32bcc2df01d5957bcbf Mon Sep 17 00:00:00 2001 From: "Li.Zhao" Date: Wed, 20 Jul 2016 13:42:04 +0800 Subject: [PATCH 2/2] Update solaris.py --- platforms/solaris.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/platforms/solaris.py b/platforms/solaris.py index 955376d73..286e5fe80 100644 --- a/platforms/solaris.py +++ b/platforms/solaris.py @@ -5,6 +5,7 @@ """ import sys import time +import argparse if "sunos" in sys.platform: import dlpi @@ -76,13 +77,25 @@ def up(self): pass -# Update this dictionary to suit your environment. -solaris_port_map = { - 21 : "net2", - 22 : "net3", - 23 : "net4", - 24 : "net5" -} +if not "--platform-args" in " ".join(sys.argv): + # Update this dictionary to suit your environment. + solaris_port_map = { + 21 : "net1", + 22 : "net2", + 23 : "net3", + 24 : "net4" + } +else: + ap = argparse.ArgumentParser("solaris") + ap.add_argument("--platform-args") + (ops, rest) = ap.parse_known_args() + solaris_port_map = {} + ports = ops.platform_args.split(",") + for ps in ports: + (p, vpi) = ps.split("@") + solaris_port_map[int(p)] = vpi + + def platform_config_update(config): """ @@ -91,7 +104,13 @@ def platform_config_update(config): @param config The configuration dictionary to use/update """ global solaris_port_map - config["port_map"] = solaris_port_map.copy() + port_map = {} + for (ofport, interface) in config["interfaces"]: + port_map[ofport] = interface + if not port_map: + port_map= solaris_port_map + + config["port_map"] = port_map.copy() config["caps_table_idx"] = 0 config["dataplane"] = {"portclass": DataPlanePortSolaris} config["allow_user"] = True