Moved dataplaneport to dataplane so as only one file
diff --git a/src/python/oftest/dataplane/dataplane.py b/src/python/oftest/dataplane/dataplane.py
index 7a2e8cd..90a5207 100644
--- a/src/python/oftest/dataplane/dataplane.py
+++ b/src/python/oftest/dataplane/dataplane.py
@@ -1,7 +1,7 @@
"""
OpenFlow Test Framework
-Dataplane class
+DataPlane and DataPlanePort classes
Provide the interface to the control the set of ports being used
to stimulate the switch under test.
@@ -10,9 +10,148 @@
a set of those objects allowing general calls and parsing
configuration.
+@todo Add "filters" for matching packets. Actions supported
+for filters should include a callback or a counter
"""
-from dataplaneport import *
+import sys
+import os
+import socket
+import time
+import promisc
+from threading import Thread
+from threading import Lock
+
+#@todo Move these identifiers into config
+ETH_P_ALL = 0x03
+RCV_TIMEOUT = 10000
+RCV_SIZE = 4096
+
+class DataPlanePort(Thread):
+ """
+ Class defining a port monitoring object.
+
+ Control a dataplane port connected to the switch under test.
+ Creates a promiscuous socket on a physical interface.
+ Queues the packets received on that interface with time stamps.
+ Inherits from Thread class as meant to run in background. Also
+ supports polling.
+ Use accessors to dequeue packets for proper synchronization.
+ """
+
+ def __init__(self, interface_name, max_pkts=1024):
+ """
+ Set up a port monitor object
+ @param interface_name The name of the physical interface like eth1
+ @param max_pkts Maximum number of pkts to keep in queue
+ """
+ Thread.__init__(self)
+ self.interface_name = interface_name
+ self.max_pkts = max_pkts
+ self.packets_pending = 0
+ self.packets_total = 0
+ self.packets = []
+ self.packet_times = []
+ self.sync = Lock()
+ self.socket = self.interface_open(interface_name)
+ print "Openned port monitor socket " + interface_name
+
+ def interface_open(self, interface_name):
+ """
+ Open a socket in a promiscuous mode for a data connection.
+ @param interface_name port name as a string such as 'eth1'
+ @retval s socket
+ """
+ s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
+ socket.htons(ETH_P_ALL))
+ s.bind((interface_name, 0))
+ promisc.set_promisc(s, interface_name)
+ s.settimeout(RCV_TIMEOUT)
+ return s
+
+ def kill(self):
+ """
+ Terminate the running thread
+ """
+ self.running = False
+ self.socket.close()
+ print "Port monitor for " + self.interface_name + " exiting"
+
+ def run(self):
+ """
+ Activity function for class
+ """
+ self.running = True
+ while self.running:
+ try:
+ rcvmsg = self.socket.recv(RCV_SIZE)
+ rcvtime = time.clock()
+
+ self.sync.acquire()
+ self.packets.append(rcvmsg)
+ self.packet_times.append(rcvtime)
+ self.packets_pending += 1
+ self.packets_total += 1
+ self.sync.release()
+
+ except socket.timeout:
+ print "Socket timeout for " + self.interface_name
+ except socket.error:
+ print "Socket closed for " + self.interface_name
+ if self.running:
+ self.kill()
+ break
+
+ def dequeue(self):
+ """
+ Get the oldest packet in the queue
+ """
+ self.sync.acquire()
+ pkt = self.packets.pop(0)
+ pkt_time = self.packet_times.pop(0)
+ self.packets_pending -= 1
+ self.sync.release()
+ return pkt, pkt_time
+
+ def timestamp_head(self):
+ """
+ Return the timestamp of the head of queue or None if empty
+ """
+ if self.packets_pending:
+ return self.packet_times[0]
+ return None
+
+ def flush(self):
+ """
+ Clear the packet queue
+ """
+ self.sync.acquire()
+ self.packets = []
+ self.packet_times = []
+ self.packets_pending = 0
+ self.sync.release()
+
+
+ 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
+ """
+ return self.socket.send(packet)
+
+
+ def register(self, handler):
+ """
+ Register a callback function to receive packets from this
+ port. The callback will be passed the packet, the
+ interface name and the port number (if set) on which the
+ packet was received.
+
+ To be implemented
+ """
+ pass
+
class DataPlane:
"""
diff --git a/src/python/oftest/dataplane/dataplaneport.py b/src/python/oftest/dataplane/dataplaneport.py
deleted file mode 100644
index f461dfa..0000000
--- a/src/python/oftest/dataplane/dataplaneport.py
+++ /dev/null
@@ -1,152 +0,0 @@
-"""
-OpenFlow Test Framework
-
-Dataplane Port class
-
-Control a dataplane port connected to the switch under test.
-
-Class inherits from thread so as to run in background allowing
-asynchronous callbacks (if needed, not required). Also supports
-polling.
-
-The port object thread maintains a queue. Incoming packets that
-are not handled by a callback function are placed in this queue for
-poll calls.
-
-"""
-
-import sys
-sys.path.append("../packet") # Needed?
-import os
-import socket
-import time
-import promisc
-from threading import Thread
-from threading import Lock
-
-ETH_P_ALL = 0x03
-RCV_TIMEOUT = 10000
-RCV_SIZE = 4096
-
-class DataPlanePort(Thread):
- """
- Class defining a port monitoring object.
- Creates a promiscuous socket on a physical interface
- Queues the packets received on that interface with time stamps
- Inherits from Thread class as meant to run in background
- Use accessors to dequeue packets for proper synchronization
- """
-
- def __init__(self, interface_name, max_pkts=1024):
- """
- Set up a port monitor object
- @param interface_name The name of the physical interface like eth1
- @param max_pkts Maximum number of pkts to keep in queue
- """
- Thread.__init__(self)
- self.interface_name = interface_name
- self.max_pkts = max_pkts
- self.packets_pending = 0
- self.packets_total = 0
- self.packets = []
- self.packet_times = []
- self.sync = Lock()
- self.socket = self.interface_open(interface_name)
- print "Openned port monitor socket " + interface_name
-
- def interface_open(self, interface_name):
- """
- Open a socket in a promiscuous mode for a data connection.
- @param interface_name port name as a string such as 'eth1'
- @retval s socket
- """
- s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
- socket.htons(ETH_P_ALL))
- s.bind((interface_name, 0))
- promisc.set_promisc(s, interface_name)
- s.settimeout(RCV_TIMEOUT)
- return s
-
- def kill(self):
- """
- Terminate the running thread
- """
- self.running = False
- self.socket.close()
- print "Port monitor for " + self.interface_name + " exiting"
-
- def run(self):
- """
- Activity function for class
- """
- self.running = True
- while self.running:
- try:
- rcvmsg = self.socket.recv(RCV_SIZE)
- rcvtime = time.clock()
-
- self.sync.acquire()
- self.packets.append(rcvmsg)
- self.packet_times.append(rcvtime)
- self.packets_pending += 1
- self.packets_total += 1
- self.sync.release()
-
- except socket.timeout:
- print "Socket timeout for " + self.interface_name
- except socket.error:
- print "Socket closed for " + self.interface_name
- if self.running:
- self.kill()
- break
-
- def dequeue(self):
- """
- Get the oldest packet in the queue
- """
- self.sync.acquire()
- pkt = self.packets.pop(0)
- pkt_time = self.packet_times.pop(0)
- self.packets_pending -= 1
- self.sync.release()
- return pkt, pkt_time
-
- def timestamp_head(self):
- """
- Return the timestamp of the head of queue or None if empty
- """
- if self.packets_pending:
- return self.packet_times[0]
- return None
-
- def flush(self):
- """
- Clear the packet queue
- """
- self.sync.acquire()
- self.packets = []
- self.packet_times = []
- self.packets_pending = 0
- self.sync.release()
-
-
- 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
- """
- return self.socket.send(packet)
-
-
- def register(self, handler):
- """
- Register a callback function to receive packets from this
- port. The callback will be passed the packet, the
- interface name and the port number (if set) on which the
- packet was received.
-
- To be implemented
- """
- pass
-