blob: bca3382a80042e9fdbf42cd2c85c38a700e4411a [file] [log] [blame]
Zsolt Haraszti656ecc62016-12-28 15:08:23 -08001#
2# Copyright 2016 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16import structlog
17from scapy.layers.l2 import Ether
18from scapy.packet import Packet
19from twisted.internet.defer import inlineCallbacks, returnValue
20
21from common.frameio.frameio import FrameIOManager, hexify
22
23log = structlog.get_logger()
24
25
26class RealIo(object):
27
28 def __init__(self, iface_map):
29 self.port_to_iface_name = iface_map
30 self.iface_name_to_port = dict((n, p) for p, n in iface_map.items())
31 self.frame_io = FrameIOManager()
32 self.ponsim = None
33 self.io_ports = dict()
34
35 @inlineCallbacks
36 def start(self):
37 log.debug('starting')
38 yield self.frame_io.start()
39 for port, iface_name in self.port_to_iface_name.items():
40 io_port = self.frame_io.add_interface(iface_name, self.ingress)
41 self.io_ports[port] = io_port
42 log.info('started')
43 returnValue(self)
44
45 def stop(self):
46 log.debug('stopping')
47 for port in self.io_ports.values():
48 self.frame_io.del_interface(port.iface_name)
49 self.frame_io.stop()
50 log.info('stopped')
51
52 def register_ponsim(self, ponsim):
53 self.ponsim = ponsim
54
55 def ingress(self, io_port, frame):
56 port = self.iface_name_to_port.get(io_port.iface_name)
57 log.debug('ingress', port=port, iface_name=io_port.iface_name,
58 frame=hexify(frame))
59 decoded_frame = Ether(frame)
60 if self.ponsim is not None:
61 self.ponsim.ingress(port, decoded_frame)
62
63 def egress(self, port, frame):
64 if isinstance(frame, Packet):
65 frame = str(frame)
66 io_port = self.io_ports[port]
67 log.debug('sending', port=port, frame=hexify(frame))
68 io_port.send(frame)