use PcapWriter to log dataplane traffic
When we write a logfile we'll also write a pcap file with the extension
replaced by ".pcap". If per-test logging is enabled we'll open a new pcap file
for each test.
diff --git a/oft b/oft
index b79d46c..a4aa5b4 100755
--- a/oft
+++ b/oft
@@ -232,6 +232,19 @@
oftest.open_logfile('main')
+def pcap_setup(config):
+ """
+ Set up dataplane packet capturing based on config
+ """
+
+ if config["log_dir"] == None:
+ filename = os.path.splitext(config["log_file"])[0] + '.pcap'
+ oftest.dataplane_instance.start_pcap(filename)
+ else:
+ # start_pcap is called per-test in base_tests
+ pass
+
+
def load_test_modules(config):
"""
Load tests from the test_dir directory.
@@ -498,6 +511,7 @@
if __name__ == "__main__":
# Set up the dataplane
oftest.dataplane_instance = oftest.dataplane.DataPlane(config)
+ pcap_setup(config)
for of_port, ifname in config["port_map"].items():
oftest.dataplane_instance.port_add(ifname, of_port)
diff --git a/src/python/oftest/base_tests.py b/src/python/oftest/base_tests.py
index 3b59bc1..a2b25ac 100644
--- a/src/python/oftest/base_tests.py
+++ b/src/python/oftest/base_tests.py
@@ -7,6 +7,7 @@
import logging
import unittest
+import os
import oftest
from oftest import config
@@ -103,6 +104,9 @@
SimpleProtocol.setUp(self)
self.dataplane = oftest.dataplane_instance
self.dataplane.flush()
+ if config["log_dir"] != None:
+ filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
+ self.dataplane.start_pcap(filename)
def inheritSetup(self, parent):
"""
@@ -114,6 +118,8 @@
self.dataplane = parent.dataplane
def tearDown(self):
+ if config["log_dir"] != None:
+ self.dataplane.stop_pcap()
SimpleProtocol.tearDown(self)
class DataPlaneOnly(BaseTest):
@@ -125,6 +131,11 @@
BaseTest.setUp(self)
self.dataplane = oftest.dataplane_instance
self.dataplane.flush()
+ if config["log_dir"] != None:
+ filename = os.path.join(config["log_dir"], str(self)) + ".pcap"
+ self.dataplane.start_pcap(filename)
def tearDown(self):
+ if config["log_dir"] != None:
+ self.dataplane.stop_pcap()
BaseTest.tearDown(self)
diff --git a/src/python/oftest/dataplane.py b/src/python/oftest/dataplane.py
index f70de6c..12dcfce 100644
--- a/src/python/oftest/dataplane.py
+++ b/src/python/oftest/dataplane.py
@@ -25,6 +25,7 @@
from threading import Condition
import ofutils
import netutils
+from pcap_writer import PcapWriter
have_pypcap = False
try:
@@ -165,6 +166,7 @@
self.killed = False
self.logger = logging.getLogger("dataplane")
+ self.pcap_writer = None
if config is None:
self.config = {}
@@ -215,6 +217,8 @@
port_number = port._port_number
self.logger.debug("Pkt len %d in on port %d",
len(pkt), port_number)
+ if self.pcap_writer:
+ self.pcap_writer.write(pkt, timestamp, port_number)
queue = self.packet_queues[port_number]
if len(queue) >= self.MAX_QUEUE_LEN:
# Queue full, throw away oldest
@@ -246,6 +250,8 @@
"""
self.logger.debug("Sending %d bytes to port %d" %
(len(packet), port_number))
+ if self.pcap_writer:
+ self.pcap_writer.write(packet, time.time(), port_number)
bytes = self.ports[port_number].send(packet)
if bytes != len(packet):
self.logger.error("Unhandled send error, length mismatch %d != %d" %
@@ -353,3 +359,12 @@
"""
for port_number in self.packet_queues.keys():
self.packet_queues[port_number] = []
+
+ def start_pcap(self, filename):
+ assert(self.pcap_writer == None)
+ self.pcap_writer = PcapWriter(filename)
+
+ def stop_pcap(self):
+ if self.pcap_writer:
+ self.pcap_writer.close()
+ self.pcap_writer = None