66from contextlib import suppress
77import concurrent .futures
88
9- from linuxswitch .util import PortType , add_vlan_tag , fix_checksums , apply_bpf_filter
10- from linuxswitch .manipulation import ManipulateArgs , ManipulateActions
9+ from linuxswitch .util import PortType , DeviceType , add_vlan_tag , fix_checksums , apply_bpf_filter
10+ from linuxswitch .manipulation import ManipulateArgs
1111
1212
1313DeviceEntry = namedtuple ('DeviceEntry' , [
@@ -43,52 +43,41 @@ async def _read_message_queue(self):
4343 await self ._process_packet (packet , dev_entry )
4444
4545 async def _process_packet (self , packet , src_device_entry ):
46- # Should we deal with tagging. We left an option for the manipulator
47- # to tag the packet.
48- should_inject_raw = False
49-
50- packets = [packet ]
51-
52- if self ._manipulate_cb is not None :
46+ """
47+ If `src_device_entry` is None, we're not performing manipulation.
48+ """
49+ if src_device_entry is not None and self ._manipulate_cb is not None :
5350 # We'll manipulate if there's no filter or if there's
5451 # filter and the packet matches the filter
5552 if self ._manipulate_filter == NO_FILTER or \
5653 apply_bpf_filter (packet , self ._manipulate_filter ):
5754
58- # In case the packet matches the filter, and `duplicate` is not
59- # set, we remove the packet from the list, since the manipulator
60- # might drop the packet.
61- if not self ._manipulate_dup :
62- packets .remove (packet )
63-
64- packet , action = await self ._event_loop .run_in_executor (
55+ await self ._event_loop .run_in_executor (
6556 self ._executers ,
6657 self ._manipulate_cb ,
6758 ManipulateArgs (packet , src_device_entry .port_type , src_device_entry .vlan ))
6859
69- if action == ManipulateActions .INJECT_RAW :
70- should_inject_raw = True
71- packets .append (packet )
72- elif action == ManipulateActions .HANDLE_ENCAP :
73- should_inject_raw = False
74- packets .append (packet )
75- # else - action is DROP, so we don't add the packet to the list.
76-
77- for packet in packets :
60+ # In case the packet matches the filter, and `duplicate` is not
61+ # set, then only the manipulator should process the packet.
62+ # Therefore, we abort here.
63+ if not self ._manipulate_dup :
64+ return None
7865
79- src_vlan = self ._get_vlan_by_mac (Ether (packet ).src )
80- if src_vlan is None :
81- return None
66+ src_vlan = self ._get_vlan_by_mac (Ether (packet ).src )
67+ if src_vlan is None :
68+ return None
8269
83- # Looking for the destination device
84- for dst_device in self ._devices :
85- if dst_device .dev .get_mac == Ether (packet ).dst and dst_device .vlan == src_vlan :
70+ # Looking for the destination device
71+ for dst_device in self ._devices :
72+ if dst_device .dev .get_mac == Ether (packet ).dst and dst_device .vlan == src_vlan :
8673
87- if dst_device .port_type == PortType .TRUNK and not should_inject_raw :
88- packet = add_vlan_tag (packet , dst_device .vlan )
74+ # TODO: currently we're taggint packets. Maybe the Device
75+ # should state whether we should tag or inject raw.
76+ if dst_device .port_type == PortType .TRUNK :
77+ packet = add_vlan_tag (packet , dst_device .vlan )
8978
90- packet = fix_checksums (packet )
91- await self ._event_loop .sock_sendall (dst_device .sock , packet )
79+ packet = fix_checksums (packet )
80+ await self ._event_loop .sock_sendall (dst_device .sock , packet )
9281
9382 def _read_raw_packet (self , device_entry ):
9483 try :
@@ -137,12 +126,12 @@ def _get_vlan_by_mac(self, mac):
137126
138127 return None
139128
140- def append_device (self , dev , vlan , port_type ):
129+ def append_device (self , dev , vlan , port_type , iface_name ):
141130 def _append_device_entry (self , new_dev_entry ):
142131 self ._devices .append (new_dev_entry )
143132
144133 sock = socket .socket (socket .AF_PACKET , socket .SOCK_RAW , socket .htons (0x0003 ))
145- sock .bind (('br-{}' . format ( dev . get_name ) , 0 ))
134+ sock .bind ((iface_name , 0 ))
146135
147136 new_dev_entry = DeviceEntry (dev , sock , vlan , port_type )
148137
@@ -168,15 +157,18 @@ def _remove_device_entry(self, dev_to_remove):
168157
169158 def set_manipulation (self , cb , bpf_filter , duplicate ):
170159 ''' Assumes cb is in valid form '''
171- def __set_manipulation (cb , bpf_filter ):
160+ def __set_manipulation (cb , bpf_filter , duplicate ):
172161 self ._manipulate_cb = cb
173162 self ._manipulate_filter = bpf_filter
174163 self ._manipulate_dup = duplicate
175164
176165 # set_manipulation is called from the main thread.
177166 # Since we're affecting the event loop thread, we should call_soon_threadsafe,
178167 # so the call will be synchronized.
179- self ._event_loop .call_soon_threadsafe (__set_manipulation , cb , bpf_filter )
168+ self ._event_loop .call_soon_threadsafe (__set_manipulation , cb , bpf_filter , duplicate )
169+
170+ def manipulator_queue_packet (self , packet ):
171+ self ._message_queue .put_nowait ((packet , None ))
180172
181173 def start_connections_thread (self ):
182174 self ._connections_thread .start ()
0 commit comments