FrameIO to allow sharing same Linux interface
Change-Id: I30a8dd660477980069801952861d38e0dbe09739
diff --git a/tests/itests/run_as_root/test_frameio.py b/tests/itests/run_as_root/test_frameio.py
index 057fa28..bd8f770 100644
--- a/tests/itests/run_as_root/test_frameio.py
+++ b/tests/itests/run_as_root/test_frameio.py
@@ -31,11 +31,12 @@
from scapy.layers.inet import IP
from scapy.layers.l2 import Ether, Dot1Q
from twisted.internet import reactor
-from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.defer import Deferred, inlineCallbacks, DeferredQueue
from twisted.internet.error import AlreadyCalled
from twisted.trial.unittest import TestCase
-from common.frameio.frameio import FrameIOManager, BpfProgramFilter
+from common.frameio.frameio import FrameIOManager, BpfProgramFilter, \
+ FrameIOPortProxy
from common.utils.asleep import asleep
from common.utils.deferred_utils import DeferredWithTimeout, TimeOutError
@@ -75,8 +76,8 @@
@inlineCallbacks
def test_packet_send_receive(self):
rcvd = DeferredWithTimeout()
- p0 = self.mgr.add_interface('veth0', none).up()
- p1 = self.mgr.add_interface('veth1',
+ p0 = self.mgr.open_port('veth0', none).up()
+ p1 = self.mgr.open_port('veth1',
lambda p, f: rcvd.callback((p, f))).up()
# sending to veth0 should result in receiving on veth1 and vice versa
@@ -93,10 +94,10 @@
rcvd = DeferredWithTimeout()
filter = BpfProgramFilter('ip dst host 123.123.123.123')
- p0 = self.mgr.add_interface('veth0', none).up()
- p1 = self.mgr.add_interface('veth1',
- lambda p, f: rcvd.callback((p, f)),
- filter=filter).up()
+ p0 = self.mgr.open_port('veth0', none).up()
+ p1 = self.mgr.open_port('veth1',
+ lambda p, f: rcvd.callback((p, f)),
+ filter=filter).up()
# sending bogus packet would not be received
ip_packet = str(Ether()/IP(dst='123.123.123.123'))
@@ -112,9 +113,9 @@
rcvd = DeferredWithTimeout()
filter = BpfProgramFilter('ip dst host 123.123.123.123')
- p0 = self.mgr.add_interface('veth0', none).up()
- self.mgr.add_interface('veth1', lambda p, f: rcvd.callback((p, f)),
- filter=filter).up()
+ p0 = self.mgr.open_port('veth0', none).up()
+ self.mgr.open_port('veth1', lambda p, f: rcvd.callback((p, f)),
+ filter=filter).up()
# sending bogus packet would not be received
p0.send('bogus packet')
@@ -142,10 +143,10 @@
done.callback(None)
return _append
- p1in = self.mgr.add_interface('veth0', none).up()
- self.mgr.add_interface('veth1', append(queue1)).up()
- p2in = self.mgr.add_interface('veth2', none).up()
- self.mgr.add_interface('veth3', append(queue2)).up()
+ p1in = self.mgr.open_port('veth0', none).up()
+ self.mgr.open_port('veth1', append(queue1)).up()
+ p2in = self.mgr.open_port('veth2', none).up()
+ self.mgr.open_port('veth3', append(queue2)).up()
@inlineCallbacks
def send_packets(port, n):
@@ -177,10 +178,10 @@
return _append
filter = BpfProgramFilter('vlan 100')
- p1in = self.mgr.add_interface('veth0', none).up()
- self.mgr.add_interface('veth1', append(queue1), filter).up()
- p2in = self.mgr.add_interface('veth2', none).up()
- self.mgr.add_interface('veth3', append(queue2), filter).up()
+ p1in = self.mgr.open_port('veth0', none).up()
+ self.mgr.open_port('veth1', append(queue1), filter).up()
+ p2in = self.mgr.open_port('veth2', none).up()
+ self.mgr.open_port('veth3', append(queue2), filter).up()
@inlineCallbacks
def send_packets(port, n):
@@ -197,6 +198,70 @@
# verify that both queue got all packets
yield done
+ @inlineCallbacks
+ def test_shared_interface(self):
+
+ queue1 = DeferredQueue()
+ queue2 = DeferredQueue()
+
+ # two senders hooked up to the same interface (sharing it)
+ # here we test if they can both send
+ pin1 = self.mgr.open_port('veth0', none).up()
+ pin2 = self.mgr.open_port('veth0', none).up()
+
+ pout1 = self.mgr.open_port(
+ 'veth1', lambda p, f: queue1.put((p, f))).up()
+ filter = BpfProgramFilter('ip dst host 123.123.123.123')
+ pout2 = self.mgr.open_port(
+ 'veth1', lambda p, f: queue2.put((p, f)), filter=filter).up()
+
+ # sending from pin1, should be received by pout1
+ bogus_frame = 'bogus packet'
+ pin1.send(bogus_frame)
+ port, frame = yield queue1.get()
+ self.assertEqual(port, pout1)
+ self.assertEqual(frame, bogus_frame)
+ self.assertEqual(len(queue1.pending), 0)
+ self.assertEqual(len(queue2.pending), 0)
+
+ # sending from pin2, should be received by pout1
+ bogus_frame = 'bogus packet'
+ pin2.send(bogus_frame)
+ port, frame = yield queue1.get()
+ self.assertEqual(port, pout1)
+ self.assertEqual(frame, bogus_frame)
+ self.assertEqual(len(queue1.pending), 0)
+ self.assertEqual(len(queue2.pending), 0)
+
+ # sending from pin1, should be received by both pouts
+ ip_packet = str(Ether()/IP(dst='123.123.123.123'))
+ pin1.send(ip_packet)
+ port, frame = yield queue1.get()
+ self.assertEqual(port, pout1)
+ self.assertEqual(frame, ip_packet)
+ self.assertEqual(len(queue1.pending), 0)
+ port, frame = yield queue2.get()
+ self.assertEqual(port, pout2)
+ self.assertEqual(frame, ip_packet)
+ self.assertEqual(len(queue2.pending), 0)
+
+ # sending from pin2, should be received by pout1
+ ip_packet = str(Ether()/IP(dst='123.123.123.123'))
+ pin2.send(ip_packet)
+ port, frame = yield queue1.get()
+ self.assertEqual(port, pout1)
+ self.assertEqual(frame, ip_packet)
+ self.assertEqual(len(queue1.pending), 0)
+ port, frame = yield queue2.get()
+ self.assertEqual(port, pout2)
+ self.assertEqual(frame, ip_packet)
+ self.assertEqual(len(queue2.pending), 0)
+
+ self.mgr.close_port(pin1)
+ self.mgr.close_port(pin2)
+ self.mgr.close_port(pout1)
+ self.mgr.close_port(pout2)
+
if __name__ == '__main__':
import unittest