VOL-253: Initial commit for pkt-in/pkt-out for Edgecore adapter
- Add protobuf msg for pkt_send
- Implement pkt-in/pkt-out in adapter (untested)
- Misc changes to conform with pep8
Change-Id: I991b8e03a39b82524e0d9a9437765b3fe0c18529
diff --git a/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py b/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py
index 7233ac7..2a26193 100644
--- a/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py
+++ b/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py
@@ -18,13 +18,16 @@
Asfvolt16 OLT adapter
"""
+
+from scapy.layers.l2 import Ether, Dot1Q
from uuid import uuid4
from common.frameio.frameio import BpfProgramFilter
from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, DeferredQueue
+from common.frameio.frameio import hexify
from scapy.packet import Packet
from voltha.protos.common_pb2 import OperStatus, ConnectStatus
-from voltha.protos.device_pb2 import DeviceType, DeviceTypes, Port, Device, \
- PmConfigs, PmConfig, PmGroupConfig
+from voltha.protos.device_pb2 import Port
from voltha.protos.common_pb2 import AdminState
from voltha.protos.logical_device_pb2 import LogicalPort, LogicalDevice
from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, \
@@ -33,9 +36,8 @@
from voltha.core.logical_device_agent import mac_str_to_tuple
from voltha.adapters.asfvolt16_olt.bal import Bal
from voltha.adapters.device_handler import OltDeviceHandler
-from voltha.protos.bbf_fiber_base_pb2 import \
- ChannelgroupConfig, ChannelpartitionConfig, ChannelpairConfig, \
- ChannelterminationConfig, OntaniConfig, VOntaniConfig, VEnetConfig
+from voltha.protos.bbf_fiber_base_pb2 import ChannelterminationConfig, \
+ VOntaniConfig
ASFVOLT_NNI_PORT = 50
# ASFVOLT_NNI_PORT needs to be other than pon port value.
@@ -80,7 +82,8 @@
device.serial_number = device.host_and_port
self.adapter_agent.update_device(device)
- self.add_port(port_no=ASFVOLT_NNI_PORT, port_type=Port.ETHERNET_NNI,
+ self.add_port(port_no=ASFVOLT_NNI_PORT,
+ port_type=Port.ETHERNET_NNI,
label='NNI facing Ethernet port')
self.logical_device_id = \
self.add_logical_device(device_id=device.id)
@@ -99,10 +102,6 @@
device.oper_status = OperStatus.ACTIVATING
self.adapter_agent.update_device(device)
- # Open the frameio port to receive in-band packet_in messages
-
- # self.activate_io_port()
-
def add_port(self, port_no, port_type, label):
self.log.info('adding-port', port_no=port_no, port_type=port_type)
if port_type is Port.ETHERNET_NNI:
@@ -140,10 +139,10 @@
n_buffers=256, # TODO fake for now
n_tables=2, # TODO ditto
capabilities=( # TODO and ditto
- OFPC_FLOW_STATS
- | OFPC_TABLE_STATS
- | OFPC_PORT_STATS
- | OFPC_GROUP_STATS
+ OFPC_FLOW_STATS |
+ OFPC_TABLE_STATS |
+ OFPC_PORT_STATS |
+ OFPC_GROUP_STATS
)
),
root_device_id=device_id
@@ -194,7 +193,7 @@
device.connect_status = ConnectStatus.REACHABLE
device.oper_status = OperStatus.ACTIVE
device.reason = 'OLT activated successfully'
- status = self.adapter_agent.update_device(device)
+ self.adapter_agent.update_device(device)
self.log.info('OLT activation complete')
else:
device.oper_status = OperStatus.FAILED
@@ -207,8 +206,8 @@
if ind_info['_sub_group_type'] == 'onu_discovery':
self.log.info('Onu discovered', olt_id=self.olt_id,
pon_ni=ind_info['_pon_id'], onu_data=ind_info)
- #To-Do: Need to handle the ONUs, where the admin state is
- #ENABLED and operation state is in Failed or Unkown
+ # To-Do: Need to handle the ONUs, where the admin state is
+ # ENABLED and operation state is in Failed or Unkown
self.log.info('Not Yet handled', olt_id=self.olt_id,
pon_ni=ind_info['_pon_id'], onu_data=ind_info)
else:
@@ -278,14 +277,16 @@
return
def handle_omci_ind(self, ind_info):
- child_device = self.adapter_agent.get_child_device(self.device_id,
- onu_id=ind_info['onu_id'])
+ child_device = self.adapter_agent.get_child_device(
+ self.device_id,
+ onu_id=ind_info['onu_id'])
if child_device is None:
- self.log.info('Onu is not configured',onu_id=ind_info['onu_id'])
+ self.log.info('Onu is not configured', onu_id=ind_info['onu_id'])
return
try:
- self.adapter_agent.receive_proxied_message(child_device.proxy_address,
- ind_info['packet'])
+ self.adapter_agent.receive_proxied_message(
+ child_device.proxy_address,
+ ind_info['packet'])
except Exception as e:
self.log.exception('', exc=str(e))
return
@@ -339,3 +340,41 @@
def delete(self):
super(Asfvolt16Handler, self).delete()
+
+ def handle_packet_in(self, ind_info):
+ self.log.info('Received Packet-In', ind_info=ind_info)
+
+ pkt = Ether(ind_info['packet'])
+ if pkt.haslayer(Dot1Q):
+ outer_shim = pkt.getlayer(Dot1Q)
+ if isinstance(outer_shim.payload, Dot1Q):
+ inner_shim = outer_shim.payload
+ cvid = inner_shim.vlan
+ logical_port = cvid
+ popped_frame = (
+ Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
+ inner_shim.payload
+ )
+ kw = dict(
+ logical_device_id=self.logical_device_id,
+ logical_port_no=logical_port,
+ )
+ self.log.info('sending-packet-in', **kw)
+ self.adapter_agent.send_packet_in(
+ packet=str(popped_frame), **kw)
+
+ reactor.callLater(1, self.process_packet_in)
+
+ def packet_out(self, egress_port, msg):
+ self.log.info('sending-packet-out', egress_port=egress_port,
+ msg=hexify(msg))
+ pkt = Ether(msg)
+ out_pkt = (
+ Ether(src=pkt.src, dst=pkt.dst) /
+ Dot1Q(vlan=PACKET_IN_VLAN) /
+ Dot1Q(vlan=egress_port, type=pkt.type) /
+ pkt.payload
+ )
+
+ # TODO: Need to retrieve the correct destination onu_id
+ self.bal.packet_out(onu_id=1, egress_port, str(out_pkt))
diff --git a/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py b/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py
index 81130fa..8017e2b 100644
--- a/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py
+++ b/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py
@@ -20,11 +20,9 @@
from twisted.internet import reactor
from common.utils.grpc_utils import twisted_async
from voltha.adapters.asfvolt16_olt.protos import bal_indications_pb2
-from voltha.adapters.asfvolt16_olt.protos import bal_msg_type_pb2, \
- bal_osmsg_pb2, bal_model_ids_pb2, bal_obj_pb2, bal_model_types_pb2, \
+from voltha.adapters.asfvolt16_olt.protos import bal_model_types_pb2, \
bal_errno_pb2, bal_pb2
from voltha.adapters.asfvolt16_olt.grpc_server import GrpcServer
-from voltha.protos.device_pb2 import Device
class Asfvolt16RxHandler(object):
@@ -72,8 +70,9 @@
else:
ind_info['activation_successful'] = False
+ device_handler = self.adapter.devices_handlers[device_id]
reactor.callLater(0,
- self.adapter.devices_handlers[device_id].handle_access_term_ind,
+ device_handler.handle_access_term_ind,
ind_info)
bal_err = bal_pb2.BalErr()
bal_err.err = bal_errno_pb2.BAL_ERR_OK
@@ -199,8 +198,9 @@
ind_info['_vendor_id'] = onu_data.data.serial_number.vendor_id
ind_info['_vendor_specific'] = \
onu_data.data.serial_number.vendor_specific
+ device_handler = self.adapter.devices_handlers[device_id]
reactor.callLater(0,
- self.adapter.devices_handlers[device_id].handle_sub_term_ind,
+ device_handler.handle_sub_term_ind,
ind_info)
bal_err = bal_pb2.BalErr()
bal_err.err = bal_errno_pb2.BAL_ERR_OK
@@ -266,8 +266,9 @@
elif (bal_model_types_pb2.BAL_STATE_UP == onu_data.data.admin_state):
ind_info['activation_successful'] = True
+ device_handler = self.adapter.devices_handlers[device_id]
reactor.callLater(0,
- self.adapter.devices_handlers[device_id].handle_sub_term_ind,
+ device_handler.handle_sub_term_ind,
ind_info)
bal_err = bal_pb2.BalErr()
bal_err.err = bal_errno_pb2.BAL_ERR_OK
@@ -300,11 +301,20 @@
@twisted_async
def BalPktBearerChannelRxInd(self, request, context):
device_id = request.device_id.decode('unicode-escape')
- self.log.info('Not implemented yet',
+ self.log.info('Received Packet-In',
device_id=device_id, obj_type=request.objType)
ind_info = dict()
- ind_info['_object_type'] = 'packet_in_indication'
- ind_info['_sub_group_type'] = 'bearer_message'
+ ind_info['flow_id'] = request.pktData.data.flow_id
+ ind_info['flow_type'] = request.pktData.data.flow_type
+ ind_info['intf_id'] = request.pktData.data.intf_id
+ ind_info['intf_type'] = request.pktData.data.intf_type
+ ind_info['svc_port'] = request.pktData.data.svc_port
+ ind_info['flow_cookie'] = request.pktData.data.flow_cookie
+ ind_info['pkt'] = request.pktData.data.pkt
+ device_handler = self.adapter.devices_handlers[device_id]
+ reactor.callLater(0,
+ device_handler.handle_packet_in,
+ ind_info)
bal_err = bal_pb2.BalErr()
bal_err.err = bal_errno_pb2.BAL_ERR_OK
return bal_err
@@ -322,11 +332,12 @@
ind_info['onu_id'] = packet_data.itu_omci_channel.sub_term_id
ind_info['packet'] = request.balOmciResp.data.pkt
self.log.info('ONU Id is',
- onu_id=packet_data.itu_omci_channel.sub_term_id)
+ onu_id=packet_data.itu_omci_channel.sub_term_id)
+ device_handler = self.adapter.devices_handlers[device_id]
reactor.callLater(0,
- self.adapter.devices_handlers[device_id].handle_omci_ind,
- ind_info)
+ device_handler.handle_omci_ind,
+ ind_info)
bal_err = bal_pb2.BalErr()
bal_err.err = bal_errno_pb2.BAL_ERR_OK
return bal_err
diff --git a/voltha/adapters/asfvolt16_olt/bal.py b/voltha/adapters/asfvolt16_olt/bal.py
index e078eb5..0ddc3e8 100644
--- a/voltha/adapters/asfvolt16_olt/bal.py
+++ b/voltha/adapters/asfvolt16_olt/bal.py
@@ -15,7 +15,7 @@
#
from twisted.internet.defer import inlineCallbacks
-from voltha.adapters.asfvolt16_olt.protos import bal_pb2, bal_obj_pb2, \
+from voltha.adapters.asfvolt16_olt.protos import bal_pb2, \
bal_model_types_pb2, bal_model_ids_pb2
from voltha.adapters.asfvolt16_olt.grpc_client import GrpcClient
@@ -122,3 +122,23 @@
self.log.info('activating-ONU-exception',
onu_info['onu_id'], exc=str(e))
return
+
+ @inlineCallbacks
+ def packet_out(self, onu_id, egress_port, pkt):
+ self.log.info('packet-out', onu_id=onu_id, egress_port=egress_port)
+
+ obj = bal_pb2.BalCfg()
+
+ # Set the destination ONU info
+ obj.packet.key.dest.packet_send_dest.sub_term.sub_term_id = onu_id
+ # TODO: Need to provide correct values for sub_term_uni and int_id
+ obj.packet.key.dest.packet_send_dest.sub_term.sub_term_uni = egress_port
+ obj.packet.key.dest.packet_send_dest.sub_term.int_id = egress_port
+
+ # Set the Packet-out info
+ obj.packet.data.flow_type = BAL_FLOW_TYPE_DOWNSTREAM
+ # TODO: Need to provide correct value for intf_id
+ obj.packet.data.intf_id = egress_port
+ obj.packet.data.pkt = pkt
+
+ yield self.stub.BalCfgSet(obj)
diff --git a/voltha/adapters/device_handler.py b/voltha/adapters/device_handler.py
index 15f11eb..a952aa2 100644
--- a/voltha/adapters/device_handler.py
+++ b/voltha/adapters/device_handler.py
@@ -18,6 +18,7 @@
from voltha.registry import registry
from voltha.protos.common_pb2 import OperStatus, ConnectStatus, AdminState
+
class DeviceHandler(object):
def __init__(self, adapter, device_id):
self.adapter = adapter
@@ -40,6 +41,7 @@
device.connect_status = ConnectStatus.UNREACHABLE
self.adapter_agent.update_device(device)
+
class OltDeviceHandler(DeviceHandler):
def __init__(self, adapter, device_id):
super(OltDeviceHandler, self).__init__(adapter, device_id)
@@ -130,5 +132,9 @@
self.alarms.send_alarm(self, raw_data)
'''
+ def packet_out(self, egress_port, msg):
+ raise NotImplementedError()
+
+
class OnuDeviceHandler(DeviceHandler):
pass