VOL-252: Process flow rules and provision BAL for HSIA, DHCP, EAPOL flows
Change-Id: I3dc2629e442b44377d69f7025f70446634a4eac5
diff --git a/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py b/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py
index 47946e0..6f02b80 100644
--- a/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py
+++ b/voltha/adapters/asfvolt16_olt/asfvolt16_device_handler.py
@@ -23,21 +23,32 @@
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
+import voltha.core.flow_decomposer as fd
from voltha.protos.common_pb2 import OperStatus, ConnectStatus
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, \
OFPPF_1GB_FD, OFPC_GROUP_STATS, OFPC_PORT_STATS, OFPC_TABLE_STATS, \
- OFPC_FLOW_STATS, ofp_switch_features, ofp_desc, ofp_port
+ OFPC_FLOW_STATS, ofp_switch_features, ofp_desc, ofp_port, \
+ OFPXMC_OPENFLOW_BASIC
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 ChannelterminationConfig, \
- VOntaniConfig
+from voltha.protos.bbf_fiber_base_pb2 import \
+ ChannelgroupConfig, ChannelpartitionConfig, ChannelpairConfig, \
+ ChannelterminationConfig, OntaniConfig, VOntaniConfig, VEnetConfig
+from voltha.protos.bbf_fiber_traffic_descriptor_profile_body_pb2 import \
+ TrafficDescriptorProfileData
+from voltha.protos.bbf_fiber_tcont_body_pb2 import TcontsConfigData
+from voltha.protos.bbf_fiber_gemport_body_pb2 import GemportsConfigData
+from voltha.protos.bbf_fiber_multicast_gemport_body_pb2 import \
+ MulticastGemportsConfigData
+from voltha.protos.bbf_fiber_multicast_distribution_set_body_pb2 import \
+ MulticastDistributionSetData
+import time
ASFVOLT_NNI_PORT = 50
# ASFVOLT_NNI_PORT needs to be other than pon port value.
@@ -48,14 +59,58 @@
is_inband_frame = BpfProgramFilter('(ether[14:2] & 0xfff) = 0x{:03x}'.format(
PACKET_IN_VLAN))
+ASFVOLT_EAPOL_ID = 1
+ASFVOLT_DHCP_UNTAGGED_ID = 2
+ASFVOLT_DHCP_TAGGED_ID = 3
+ASFVOLT_IGMP_UNTAGGED_ID = 4
+ASFVOLT_IGMP_TAGGED_ID = 5
+ASFVOLT_FIRMWARE_ID = 6
+ASFVOLT_ARP_ID = 7
+ASFVOLT_HSIA_ID = 8
+ASFVOLT_DNS_ID = 9
+
+ASFVOLT_DOWNLINK_EAPOL_ID = 10
+ASFVOLT_DOWNLINK_DHCP_UNTAGGED_ID = 11
+ASFVOLT_DOWNLINK_DHCP_TAGGED_ID = 12
+ASFVOLT_DOWNLINK_IGMP_UNTAGGED_ID = 13
+ASFVOLT_DOWNLINK_IGMP_TAGGED_ID = 14
+ASFVOLT_DOWNLINK_FIRMWARE_ID = 15
+ASFVOLT_DOWNLINK_ARP_ID = 16
+ASFVOLT_DOWNLINK_HSIA_ID = 17
+ASFVOLT_DOWNLINK_DNS_ID = 18
+
+
+class VEnetHandler(object):
+
+ def __init__(self):
+ self.v_enet = VEnetConfig()
+ self.gem_ports = dict()
+
+
+class VOntAniHandler(object):
+
+ def __init__(self):
+ self.v_ont_ani = VOntaniConfig()
+ self.tconts = dict()
+
class Asfvolt16Handler(OltDeviceHandler):
+
def __init__(self, adapter, device_id):
super(Asfvolt16Handler, self).__init__(adapter, device_id)
self.filter = is_inband_frame
self.bal = Bal(self, self.log)
self.host_and_port = None
self.olt_id = 0
+ self.channel_groups = dict()
+ self.channel_partitions = dict()
+ self.channel_pairs = dict()
+ self.channel_terminations = dict()
+ self.v_ont_anis = dict()
+ self.ont_anis = dict()
+ self.v_enets = dict()
+ self.traffic_descriptors = dict()
+ self.uni_port_num = 20
def __del__(self):
super(Asfvolt16Handler, self).__del__()
@@ -63,6 +118,60 @@
def __str__(self):
return "Asfvolt16Handler: {}".format(self.host_and_port)
+ def _get_next_uni_port(self):
+ self.uni_port_num += 1
+ return self.uni_port_num
+
+ def get_venet(self, name):
+ for key, v_enet in self.v_enets.items():
+ if key == name:
+ return v_enet
+ return None
+
+ def get_v_ont_ani(self, name):
+ for key, v_ont_ani in self.v_ont_anis.items():
+ if key == name:
+ return v_ont_ani
+ return None
+
+ def get_gem_port_info(self, v_enet, **kwargs):
+ traffic_class = kwargs.pop('traffic_class', None)
+ name = kwargs.pop('name', None)
+ for key, gem_port in v_enet.gem_ports.items():
+ if traffic_class is not None:
+ if traffic_class == gem_port.traffic_class:
+ return gem_port
+ if name is not None:
+ if name == gem_port.name:
+ return gem_port
+ return None
+
+ def get_tcont_info(self, v_ont_ani, **kwargs):
+ alloc_id = kwargs.pop('alloc_id', None)
+ name = kwargs.pop('name', None)
+ for key, tcont in v_ont_ani.tconts.items():
+ if alloc_id is not None:
+ if alloc_id == tcont.alloc_id:
+ return tcont
+ if name is not None:
+ if name == tcont.name:
+ return tcont
+ return None
+
+ def get_traffic_profile(self, name):
+ for key, traffic_profile in self.traffic_descriptors():
+ if name is not None:
+ if name == traffic_profile.name:
+ return traffic_profile
+ return None
+
+ def get_flow_id(self, onu_id, intf_id, id):
+ # Tp-Do Need to generate unique flow ID using
+ # OnuID, IntfId, id
+ # BAL accepts flow_id till 16384. So we are
+ # using only onu_id and id to generate flow ID.
+ return ((onu_id << 13) | id)
+
def activate(self, device):
self.log.info('activating-asfvolt16-olt', device=device)
@@ -87,7 +196,7 @@
label='NNI facing Ethernet port')
self.logical_device_id = \
self.add_logical_device(device_id=device.id)
- self.add_logical_port(port_no=1,
+ self.add_logical_port(port_no=ASFVOLT_NNI_PORT,
port_type=Port.ETHERNET_NNI,
device_id=device.id,
logical_device_id=self.logical_device_id)
@@ -111,7 +220,7 @@
# For now make the status as Active.
oper_status = OperStatus.ACTIVE
else:
- self.log.erro('invalid-port-type', port_type=port_type)
+ self.log.error('invalid-port-type', port_type=port_type)
return
port = Port(
@@ -160,7 +269,7 @@
curr_speed = OFPPF_1GB_FD
max_speed = OFPPF_1GB_FD
else:
- self.log.erro('invalid-port-type', port_type=port_type)
+ self.log.error('invalid-port-type', port_type=port_type)
return
ofp = ofp_port(
@@ -188,7 +297,7 @@
def handle_access_term_ind(self, ind_info):
device = self.adapter_agent.get_device(self.device_id)
if ind_info['activation_successful'] is True:
- self.log.info('successful access terminal Indication',
+ self.log.info('successful-access-terminal-Indication',
olt_id=self.olt_id)
device.connect_status = ConnectStatus.REACHABLE
device.oper_status = OperStatus.ACTIVE
@@ -204,35 +313,35 @@
def handle_not_started_onu(self, child_device, ind_info):
if ind_info['_sub_group_type'] == 'onu_discovery':
- self.log.info('Onu discovered', olt_id=self.olt_id,
+ 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
- self.log.info('Not Yet handled', olt_id=self.olt_id,
+ self.log.info('Not-Yet-handled', olt_id=self.olt_id,
pon_ni=ind_info['_pon_id'], onu_data=ind_info)
else:
- self.log.info('Invalid ONU event', olt_id=self.olt_id,
+ self.log.info('Invalid-ONU-event', olt_id=self.olt_id,
pon_ni=ind_info['_pon_id'], onu_data=ind_info)
def handle_activating_onu(self, child_device, ind_info):
pon_id = ind_info['_pon_id']
- self.log.info('Not handled Yet', olt_id=self.olt_id,
+ self.log.info('Not-handled-Yet', olt_id=self.olt_id,
pon_ni=pon_id, onu_data=ind_info)
def handle_activated_onu(self, child_device, ind_info):
pon_id = ind_info['_pon_id']
- self.log.info('Not handled Yet', olt_id=self.olt_id,
+ self.log.info('Not-handled-Yet', olt_id=self.olt_id,
pon_ni=pon_id, onu_data=ind_info)
def handle_discovered_onu(self, child_device, ind_info):
pon_id = ind_info['_pon_id']
if ind_info['_sub_group_type'] == 'onu_discovery':
- self.log.info('Activation is in progress', olt_id=self.olt_id,
+ self.log.info('Activation-is-in-progress', olt_id=self.olt_id,
pon_ni=pon_id, onu_data=ind_info,
onu_id=child_device.proxy_address.onu_id)
elif ind_info['_sub_group_type'] == 'sub_term_indication':
- self.log.info('ONU activation is completed', olt_id=self.olt_id,
+ self.log.info('ONU-activation-is-completed', olt_id=self.olt_id,
pon_ni=pon_id, onu_data=ind_info)
msg = {'proxy_address': child_device.proxy_address,
@@ -241,8 +350,25 @@
# Send the event message to the ONU adapter
self.adapter_agent.publish_inter_adapter_message(child_device.id,
msg)
+ if ind_info['activation_successful'] is True:
+ for key, v_ont_ani in self.v_ont_anis.items():
+ if v_ont_ani.v_ont_ani.data.onu_id == \
+ child_device.proxy_address.onu_id:
+ for tcont_key, tcont in v_ont_ani.tconts.items():
+ owner_info = dict()
+ # To-Do: Right Now use alloc_id as schduler ID. Need to
+ # find way to generate uninqe number.
+ id = tcont.alloc_id
+ owner_info['type'] = 'agg_port'
+ owner_info['intf_id'] = \
+ child_device.proxy_address.channel_id
+ owner_info['onu_id'] = \
+ child_device.proxy_address.onu_id
+ owner_info['alloc_id'] = tcont.alloc_id
+ self.bal.create_scheduler(id, 'upstream',
+ owner_info, 8)
else:
- self.log.info('Invalid ONU event', olt_id=self.olt_id,
+ self.log.info('Invalid-ONU-event', olt_id=self.olt_id,
pon_ni=ind_info['_pon_id'], onu_data=ind_info)
onu_handlers = {
@@ -259,7 +385,7 @@
serial_number=(ind_info['_vendor_id'] +
ind_info['_vendor_specific']))
if child_device is None:
- self.log.info('Onu is not configured', olt_id=self.olt_id,
+ self.log.info('Onu-is-not-configured', olt_id=self.olt_id,
pon_ni=ind_info['_pon_id'], onu_data=ind_info)
return
@@ -288,53 +414,182 @@
child_device.proxy_address,
ind_info['packet'])
except Exception as e:
- self.log.exception('', exc=str(e))
+ self.log.exception('', exc=str(e))
return
+ def handle_v_ont_ani_config(self, data):
+ serial_number = data.data.expected_serial_number
+ child_device = self.adapter_agent.get_child_device(
+ self.device_id,
+ serial_number=serial_number)
+ if child_device is None:
+ self.log.info('Failed-to-find-ONU-Info',
+ serial_number=serial_number)
+ elif child_device.admin_state == AdminState.ENABLED:
+ self.log.info('Activating ONU',
+ serial_number=serial_number,
+ onu_id=child_device.proxy_address.onu_id,
+ pon_id=child_device.parent_port_no)
+ onu_info = dict()
+ onu_info['pon_id'] = child_device.parent_port_no
+ onu_info['onu_id'] = child_device.proxy_address.onu_id
+ onu_info['vendor'] = child_device.vendor_id
+ onu_info['vendor_specific'] = serial_number[4:]
+ self.bal.activate_onu(onu_info)
+ else:
+ self.log.info('Invalid-ONU-state-to-activate',
+ onu_id=child_device.proxy_address.onu_id,
+ serial_number=serial_number)
+
def create_interface(self, data):
try:
+ if isinstance(data, ChannelgroupConfig):
+ if data.name in self.channel_groups:
+ self.log('Channel-Group-already-present',
+ channel_group=data)
+ else:
+ channel_group_config = ChannelgroupConfig()
+ channel_group_config.CopyFrom(data)
+ self.channel_groups[data.name] = channel_group_config
+ if isinstance(data, ChannelpartitionConfig):
+ if data.name in self.channel_partitions:
+ self.log('Channel-partition-already-present',
+ channel_partition=data)
+ else:
+ channel_partition_config = ChannelpartitionConfig()
+ channel_partition_config.CopyFrom(data)
+ self.channel_partitions[data.name] = \
+ channel_partition_config
+ if isinstance(data, ChannelpairConfig):
+ if data.name in self.channel_pairs:
+ self.log('Channel-pair-already-present',
+ channel_pair=data)
+ else:
+ channel_pair_config = ChannelpairConfig()
+ channel_pair_config.CopyFrom(data)
+ self.channel_pairs[data.name] = channel_pair_config
if isinstance(data, ChannelterminationConfig):
- self.log.info('Activating PON port at OLT',
+ self.log.info('Activating-PON-port-at-OLT',
pon_id=data.data.xgs_ponid)
self.add_port(port_no=data.data.xgs_ponid,
port_type=Port.PON_OLT,
label=data.name)
self.bal.activate_pon_port(self.olt_id, data.data.xgs_ponid)
- if isinstance(data, VOntaniConfig):
- serial_number = data.data.expected_serial_number
- child_device = self.adapter_agent.get_child_device(
- self.device_id,
- serial_number=serial_number)
- if child_device is None:
- self.log.info('Failed to find ONU Info',
- serial_number=serial_number)
- elif child_device.admin_state == AdminState.ENABLED:
- self.log.info('Activating ONU',
- serial_number=serial_number,
- onu_id=child_device.proxy_address.onu_id,
- pon_id=child_device.parent_port_no)
- onu_info = dict()
- onu_info['pon_id'] = child_device.parent_port_no
- onu_info['onu_id'] = child_device.proxy_address.onu_id
- onu_info['vendor'] = child_device.vendor_id
- onu_info['vendor_specific'] = serial_number[4:]
- self.bal.activate_onu(onu_info)
+ if data.name in self.channel_terminations:
+ self.log.info('Channel-termination-already-present',
+ channel_termination=data)
else:
- self.log.info('Invalid ONU state to activate',
- onu_id=child_device.proxy_address.onu_id,
- serial_number=serial_number)
+ channel_termination_config = ChannelterminationConfig()
+ channel_termination_config.CopyFrom(data)
+ self.channel_terminations[data.name] = \
+ channel_termination_config
+ if isinstance(data, VOntaniConfig):
+ if data.name in self.v_ont_anis:
+ self.log.info('v_ont_ani-already-present',
+ v_ont_ani=data)
+ else:
+ self.handle_v_ont_ani_config(data)
+ v_ont_ani_config = VOntAniHandler()
+ v_ont_ani_config.v_ont_ani.CopyFrom(data)
+ self.v_ont_anis[data.name] = v_ont_ani_config
+ if isinstance(data, VEnetConfig):
+ if data.name in self.v_enets:
+ self.log.info('v_enet-already-present',
+ v_enet=data)
+ else:
+ v_enet_config = VEnetHandler()
+ v_enet_config.v_enet.CopyFrom(data)
+ self.log.info("creating-port-at-olt")
+ self.adapter_agent.add_port(self.device_id, Port(
+ port_no=self._get_next_uni_port(),
+ label=data.interface.name,
+ type=Port.ETHERNET_UNI,
+ admin_state=AdminState.ENABLED,
+ oper_status=OperStatus.ACTIVE
+ ))
+ self.v_enets[data.name] = v_enet_config
+ if isinstance(data, OntaniConfig):
+ if data.name in self.ont_anis:
+ self.log.info('ont_ani-already-present',
+ v_enet=data)
+ else:
+ ont_ani_config = OntaniConfig()
+ ont_ani_config.CopyFrom(data)
+ self.ont_anis[data.name] = ont_ani_config
except Exception as e:
self.log.exception('', exc=str(e))
return
def update_interface(self, data):
- self.log.info('Not Implemented yet')
+ self.log.info('Not-Implemented-yet')
return
def remove_interface(self, data):
- self.log.info('Not Implemented yet')
+ self.log.info('Not-Implemented-yet')
return
+ def create_tcont(self, tcont_data, traffic_descriptor_data):
+ if traffic_descriptor_data.name in self.traffic_descriptors:
+ traffic_descriptor = TrafficDescriptorProfileData()
+ traffic_descriptor.CopyFrom(traffic_descriptor_data)
+ self.traffic_descriptors[traffic_descriptor_data.name] = \
+ traffic_descriptor
+ if tcont_data.interface_reference in self.v_ont_anis:
+ v_ont_ani = self.v_ont_anis[tcont_data.interface_reference]
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id,
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if (onu_device is not None and
+ onu_device.oper_status == OperStatus.ACTIVE):
+ owner_info = dict()
+ # To-Do: Right Now use alloc_id as schduler ID. Need to
+ # find way to generate uninqe number.
+ id = tcont_data.alloc_id
+ owner_info['type'] = 'agg_port'
+ owner_info['intf_id'] = onu_device.proxy_address.channel_id
+ owner_info['onu_id'] = onu_device.proxy_address.onu_id
+ owner_info['alloc_id'] = tcont_data.alloc_id
+ self.bal.create_scheduler(id, 'upstream', owner_info, 8)
+ else:
+ self.log.info('Onu-is-not-configured', olt_id=self.olt_id,
+ intf_id=onu_device.proxy_address.channel_id,
+ onu_data=onu_device.proxy_address.onu_id)
+ if tcont_data.name in v_ont_ani.tconts:
+ self.log.info('tcont-info-already-present',
+ tcont_info=tcont_data)
+ else:
+ tcont = TcontsConfigData()
+ tcont.CopyFrom(tcont_data)
+ v_ont_ani.tconts[tcont_data.name] = tcont
+
+ def update_tcont(self, tcont_data, traffic_descriptor_data):
+ raise NotImplementedError()
+
+ def remove_tcont(self, tcont_data, traffic_descriptor_data):
+ raise NotImplementedError()
+
+ def create_gemport(self, data):
+ if data.itf_ref in self.v_enets:
+ v_enet = self.v_enets[data.itf_ref]
+ if data.name in v_enet.gem_ports:
+ self.log.info('Gem-port-info-is-already-present',
+ VEnet=v_enet, gem_info=data)
+ if data.gemport_id > 9212:
+ raise Exception('supported range for '
+ 'gem-port is from 1024 to 4099')
+ gem_port = GemportsConfigData()
+ gem_port.CopyFrom(data)
+ v_enet.gem_ports[data.name] = gem_port
+ else:
+ self.log.info('VEnet-is-not-configured-yet.',
+ gem_port_info=data)
+
+ def update_gemport(self, data):
+ raise NotImplementedError()
+
+ def remove_gemport(self, data):
+ raise NotImplementedError()
+
def disable(self):
super(Asfvolt16Handler, self).disable()
@@ -375,6 +630,746 @@
Dot1Q(vlan=egress_port, type=pkt.type) /
pkt.payload
)
-
+ onu_id = 1
# TODO: Need to retrieve the correct destination onu_id
- self.bal.packet_out(1, egress_port, str(out_pkt))
+ self.bal.packet_out(onu_id, egress_port, str(out_pkt))
+
+ def update_flow_table(self, flows):
+ device = self.adapter_agent.get_device(self.device_id)
+ self.log.info('bulk-flow-update', device_id=self.device_id)
+
+ for flow in flows:
+ self.log.info('flow-details', device_id=self.device_id, flow=flow)
+ classifier_info = dict()
+ action_info = dict()
+ is_down_stream = None
+ _in_port = None
+ try:
+ _in_port = fd.get_in_port(flow)
+ assert _in_port is not None
+ # Right now there is only one NNI port. Get the NNI PORT and compare
+ # with IN_PUT port number. Need to find better way.
+ ports = self.adapter_agent.get_ports(device.id, Port.ETHERNET_NNI)
+
+ for port in ports:
+ if (port.port_no == _in_port):
+ self.log.info('downstream-flow')
+ is_down_stream = True
+ break
+ if is_down_stream is None:
+ is_down_stream = False
+ self.log.info('upstream-flow')
+
+ _out_port = fd.get_out_port(flow) # may be None
+ self.log.info('out-port', out_port=_out_port)
+
+ for field in fd.get_ofb_fields(flow):
+
+ if field.type == fd.ETH_TYPE:
+ classifier_info['eth_type'] = field.eth_type
+ self.log.info('field-type-eth-type',
+ eth_type=classifier_info['eth_type'])
+
+ elif field.type == fd.IP_PROTO:
+ classifier_info['ip_proto'] = field.ip_proto
+ self.log.info('field-type-ip-proto',
+ ip_proto=classifier_info['ip_proto'])
+
+ elif field.type == fd.IN_PORT:
+ classifier_info['in_port'] = field.port
+ self.log.info('field-type-in-port',
+ in_port=classifier_info['in_port'])
+
+ elif field.type == fd.VLAN_VID:
+ classifier_info['vlan_vid'] = field.vlan_vid & 0xfff
+ self.log.info('field-type-vlan-vid',
+ vlan=classifier_info['vlan_vid'])
+
+ elif field.type == fd.VLAN_PCP:
+ classifier_info['vlan_pcp'] = field.vlan_pcp
+ self.log.info('field-type-vlan-pcp',
+ pcp=classifier_info['vlan_pcp'])
+
+ elif field.type == fd.UDP_DST:
+ classifier_info['udp_dst'] = field.udp_dst
+ self.log.info('field-type-udp-dst',
+ udp_dst=classifier_info['udp_dst'])
+
+ elif field.type == fd.UDP_SRC:
+ classifier_info['udp_src'] = field.udp_src
+ self.log.info('field-type-udp-src',
+ udp_src=classifier_info['udp_src'])
+
+ elif field.type == fd.IPV4_DST:
+ classifier_info['ipv4_dst'] = field.ipv4_dst
+ self.log.info('field-type-ipv4-dst',
+ ipv4_dst=classifier_info['ipv4_dst'])
+
+ elif field.type == fd.IPV4_SRC:
+ classifier_info['ipv4_src'] = field.ipv4_src
+ self.log.info('field-type-ipv4-src',
+ ipv4_dst=classifier_info['ipv4_src'])
+
+ elif field.type == fd.METADATA:
+ classifier_info['metadata'] = field.table_metadata
+ self.log.info('field-type-metadata',
+ metadata=classifier_info['metadata'])
+
+ else:
+ raise NotImplementedError('field.type={}'.format(
+ field.type))
+
+ for action in fd.get_actions(flow):
+
+ if action.type == fd.OUTPUT:
+ action_info['output'] = action.output.port
+ self.log.info('action-type-output',
+ output=action_info['output'],
+ in_port=classifier_info['in_port'])
+
+ elif action.type == fd.POP_VLAN:
+ action_info['pop_vlan'] = True
+ self.log.info('action-type-pop-vlan',
+ in_port=_in_port)
+
+ elif action.type == fd.PUSH_VLAN:
+ action_info['push_vlan'] = True
+ action_info['tpid'] = action.push.ethertype
+ self.log.info('action-type-push-vlan',
+ push_tpid=action_info['tpid'],
+ in_port=_in_port)
+ if action.push.ethertype != 0x8100:
+ self.log.error('unhandled-tpid',
+ ethertype=action.push.ethertype)
+
+ elif action.type == fd.SET_FIELD:
+ # action_info['action_type'] = 'set_field'
+ _field = action.set_field.field.ofb_field
+ assert (action.set_field.field.oxm_class ==
+ OFPXMC_OPENFLOW_BASIC)
+ self.log.info('action-type-set-field',
+ field=_field, in_port=_in_port)
+ if _field.type == fd.VLAN_VID:
+ self.log.info('set-field-type-vlan-vid',
+ vlan_vid=_field.vlan_vid & 0xfff)
+ action_info['vlan_vid'] = (_field.vlan_vid & 0xfff)
+ else:
+ self.log.error('unsupported-action-set-field-type',
+ field_type=_field.type)
+ else:
+ self.log.error('unsupported-action-type',
+ action_type=action.type, in_port=_in_port)
+
+ if is_down_stream is False:
+ self.divide_and_add_flow(classifier_info, action_info)
+ except Exception as e:
+ self.log.exception('failed-to-install-flow', e=e, flow=flow)
+
+ # This function will divide the upstream flow into both
+ # upstreand and downstream flow, as broadcom devices
+ # expects down stream flows to be added to handle
+ # packet_out messge from controller.
+ def divide_and_add_flow(self, classifier, action):
+ found = False
+ ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_UNI)
+ for port in ports:
+ if port.port_no == classifier['in_port']:
+ found = True
+ break
+ if found is True:
+ v_enet = self.get_venet(port.label)
+ else:
+ self.log.error('Failed to get v_enet info',
+ in_port=classifier['in_port'])
+ return
+ if 'ip_proto' in classifier:
+ if classifier['ip_proto'] == 17:
+ self.log.error('Addtion of DHCP flows are defferd')
+ '''
+ # DHCP flow from the ONOS doesn't have Ctag and Stags
+ # information. For now DHCP flow will be added as a
+ # part of data flows.
+ # self.add_dhcp_flow(classifier, action, v_enet,
+ # ASFVOLT_DHCP_UNTAGGED_ID)
+ '''
+ elif classifier['ip_proto'] == 2:
+ self.log.info('Addtion of IGMP flow are not handled yet')
+ '''
+ #self.add_igmp_flow(classifier, action, v_enet,
+ # ASFVOLT_IGMP_UNTAGGED_ID)
+ '''
+ else:
+ self.log.info("Invalid-Classifier-to-handle",
+ classifier=classifier,
+ action=action)
+ elif 'eth_type' in classifier:
+ if classifier['eth_type'] == 0x888e:
+ # self.log.error('Addtion of EAPOL flows are defferd')
+ self.add_eapol_flow(classifier, action,
+ v_enet, ASFVOLT_EAPOL_ID,
+ ASFVOLT_DOWNLINK_EAPOL_ID)
+ elif 'push_vlan' in action:
+ self.prepare_and_add_dhcp_flow(classifier, action, v_enet,
+ ASFVOLT_DHCP_TAGGED_ID,
+ ASFVOLT_DOWNLINK_DHCP_TAGGED_ID)
+ self.add_data_flow(classifier, action, v_enet)
+ else:
+ self.log.info('Invalid-flow-type-to-handle',
+ classifier=classifier,
+ action=action)
+
+ def add_eapol_flow(self, uplink_classifier, uplink_action,
+ v_enet, uplink_eapol_id, downlink_eapol_id):
+ downlink_classifier = dict(uplink_classifier)
+ downlink_action = dict(uplink_action)
+ # To-Do For a time being hard code the traffic class value.
+ # Need to know how to get the traffic class info from flows.
+ gem_port = self.get_gem_port_info(v_enet, traffic_class=2)
+ if gem_port is None:
+ self.log.info('Failed-to-get-gemport',)
+ return
+ v_ont_ani = self.get_v_ont_ani(v_enet.v_enet.data.v_ontani_ref)
+ if v_ont_ani is None:
+ self.log.info('Failed-to-get-v_ont_ani',
+ v_ont_ani=v_enet.v_enet.data.v_ontani_ref)
+ return
+ tcont = self.get_tcont_info(v_ont_ani, name=gem_port.tcont_ref)
+ if tcont is None:
+ self.log.info('Failed-to-get-tcont-info',
+ tcont=gem_port.tcont_ref)
+ return
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id, onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if onu_device is None:
+ self.log.info('Failed-to-get-onu-device',
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ return
+
+ flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ uplink_eapol_id)
+ # Add Upstream EAPOL Flow.
+ uplink_classifier['pkt_tag_type'] = 'untagged'
+ uplink_action.clear()
+ uplink_action['trap_to_host'] = True
+ try:
+ is_down_stream = False
+ self.log.info('Adding-Upstream-EAPOL-flow',
+ classifier=uplink_classifier,
+ action=uplink_action, gem_port=gem_port,
+ flow_id=flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ flow_id, gem_port.gemport_id,
+ uplink_classifier, is_down_stream,
+ action_info=uplink_action,
+ sched_id=tcont.alloc_id)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-Upstream-EAPOL-flow', e=e,
+ classifier=uplink_classifier,
+ action=uplink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ # Add Downstream EAPOL Flow.
+ downlink_flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_eapol_id)
+ is_down_stream = True
+ downlink_classifier['pkt_tag_type'] = 'untagged'
+ try:
+ self.log.info('Adding-Downstream-EAPOL-flow',
+ classifier=downlink_classifier,
+ action=downlink_action,
+ gem_port=gem_port,
+ flow_id=downlink_flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_flow_id, gem_port.gemport_id,
+ downlink_classifier, is_down_stream)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-downstream-EAPOL-flow', e=e,
+ classifier=downlink_classifier,
+ action=downlink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ def prepare_and_add_dhcp_flow(self, data_classifier, data_action,
+ v_enet, dhcp_id, downlink_dhcp_id):
+ dhcp_classifier = dict()
+ dhcp_action = dict()
+ dhcp_classifier['ip_proto'] = 17
+ dhcp_classifier['udp_src'] = 68
+ dhcp_classifier['udp_dsct'] = 67
+ dhcp_classifier['pkt_tag_type'] = 'single_tag'
+ dhcp_classifier['vlan_vid'] = data_classifier['vlan_vid']
+ dhcp_action['vlan_push'] = True
+ dhcp_action['vlan_vid'] = data_action['vlan_vid']
+ self.add_dhcp_flow(dhcp_classifier, dhcp_action, v_enet,
+ dhcp_id, downlink_dhcp_id)
+
+ def add_dhcp_flow(self, uplink_classifier, uplink_action,
+ v_enet, dhcp_id, downlink_dhcp_id):
+ downlink_classifier = dict(uplink_classifier)
+ downlink_action = dict(uplink_action)
+ # Add Upstream DHCP Flow.
+ # To-Do For a time being hard code the traffic class value.
+ # Need to know how to get the traffic class info from flows.
+ gem_port = self.get_gem_port_info(v_enet, traffic_class=2)
+ if gem_port is None:
+ self.log.error('Failed-to-get-gemport')
+ return
+ v_ont_ani = self.get_v_ont_ani(v_enet.v_enet.data.v_ontani_ref)
+ if v_ont_ani is None:
+ self.log.error('Failed-to-get-v_ont_ani',
+ v_ont_ani=v_enet.v_enet.data.v_ontani_ref)
+ return
+ tcont = self.get_tcont_info(v_ont_ani, name=gem_port.tcont_ref)
+ if tcont is None:
+ self.log.error('Failed-to-get-tcont-info',
+ tcont=gem_port.tcont_ref)
+ return
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id, onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if onu_device is None:
+ self.log.error('Failed-to-get-onu-device',
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ return
+
+ flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ dhcp_id)
+ uplink_action.clear()
+ uplink_action['trap_to_host'] = True
+ try:
+ is_down_stream = False
+ self.log.info('Adding-Upstream-DHCP-flow',
+ classifier=uplink_classifier,
+ action=uplink_action,
+ gem_port=gem_port,
+ flow_id=flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ flow_id, gem_port.gemport_id,
+ uplink_classifier, is_down_stream,
+ action_info=uplink_action,
+ sched_id=tcont.alloc_id)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+
+ except Exception as e:
+ self.log.exception('failed-to-install-dhcp-upstream-flow', e=e,
+ classifier=uplink_classifier,
+ action=uplink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ is_down_stream = True
+ downlink_classifier['udp_src'] = 67
+ downlink_classifier['udp_dst'] = 68
+
+ if dhcp_id == ASFVOLT_DHCP_TAGGED_ID:
+ downlink_classifier['pkt_tag_type'] = 'double_tag'
+ downlink_classifier['vlan_vid'] = downlink_action['vlan_vid']
+ if 'push_vlan' in downlink_classifier:
+ downlink_action.pop('push_vlan')
+ downlink_action['pop_vlan'] = True
+
+ downlink_flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_dhcp_id)
+
+ try:
+ self.log.info('Adding-Downstream-DHCP-flow',
+ classifier=downlink_classifier,
+ action=downlink_action, gem_port=gem_port,
+ flow_id=downlink_flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_flow_id, gem_port.gemport_id,
+ downlink_classifier, is_down_stream,
+ action_info=downlink_action)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-dhcp-downstream-flow', e=e,
+ classifier=downlink_classifier,
+ action=downlink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ def add_igmp_flow(self, classifier, action, v_enet, igmp_id):
+ self.log.info('Not-Implemented-Yet')
+ return
+
+ def add_data_flow(self, uplink_classifier, uplink_action, v_enet):
+
+ downlink_classifier = dict(uplink_classifier)
+ downlink_action = dict(uplink_action)
+
+ uplink_classifier['pkt_tag_type'] = 'single_tag'
+
+ downlink_classifier['pkt_tag_type'] = 'double_tag'
+ downlink_classifier['vlan_vid'] = uplink_action['vlan_vid']
+ downlink_classifier['vlan_pcp'] = 0
+ del downlink_action['push_vlan']
+ downlink_action['pop_vlan'] = True
+
+ self.add_firmware_flow(uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, ASFVOLT_FIRMWARE_ID,
+ ASFVOLT_DOWNLINK_FIRMWARE_ID)
+ self.add_arp_flow(uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, ASFVOLT_ARP_ID, ASFVOLT_DOWNLINK_ARP_ID)
+ self.add_dns_flow(uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, ASFVOLT_DNS_ID, ASFVOLT_DOWNLINK_DNS_ID)
+ self.add_hsia_flow(uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, ASFVOLT_HSIA_ID, ASFVOLT_DOWNLINK_HSIA_ID)
+
+ def add_firmware_flow(self, uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, firmware_id, downlink_firmware_id):
+ # Add Upstream Firmware Flow.
+ # To-Do For a time being hard code the traffic class value.
+ # Need to know how to get the traffic class info from flows.
+ gem_port = self.get_gem_port_info(v_enet, traffic_class=2)
+ if gem_port is None:
+ self.log.info('Failed-to-get-gemport')
+ return
+ v_ont_ani = self.get_v_ont_ani(v_enet.v_enet.data.v_ontani_ref)
+ if v_ont_ani is None:
+ self.log.info('Failed-to-get-v_ont_ani',
+ v_ont_ani=v_enet.v_enet.data.v_ontani_ref)
+ return
+ tcont = self.get_tcont_info(v_ont_ani, name=gem_port.tcont_ref)
+ if tcont is None:
+ self.log.info('Failed-to-get-tcont-info',
+ tcont=gem_port.tcont_ref)
+ return
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id, onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if onu_device is None:
+ self.log.info('Failed-to-get-onu-device',
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ return
+
+ flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ firmware_id)
+ self.log.info('Adding-FirmWare-data-upstream-flow')
+ try:
+ is_down_stream = False
+ self.log.info('Adding-Firmware-data-upstream-flow',
+ classifier=uplink_classifier,
+ action=uplink_action,
+ gem_port=gem_port,
+ flow_id=flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ flow_id, gem_port.gemport_id,
+ uplink_classifier, is_down_stream,
+ action_info=uplink_action,
+ sched_id=tcont.alloc_id)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-firmware-upstream-flow', e=e,
+ classifier=uplink_classifier,
+ action=uplink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+ is_down_stream = True
+ # To-Do: For Now hard code the p-bit values.
+ downlink_classifier['vlan_pcp'] = 1
+ downlink_flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_firmware_id)
+ try:
+ self.log.info('Adding-Firmware-data-downstream-flow',
+ classifier=downlink_classifier,
+ action=downlink_action,
+ gem_port=gem_port,
+ flow_id=downlink_flow_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_flow_id, gem_port.gemport_id,
+ downlink_classifier, is_down_stream,
+ action_info=downlink_action)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-firmware-downstream-flow', e=e,
+ classifier=downlink_classifier,
+ action=downlink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ def add_dns_flow(self, uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, dns_id, downlink_dns_id):
+ # Add Upstream Firmware Flow.
+ # To-Do For a time being hard code the traffic class value.
+ # Need to know how to get the traffic class info from flows.
+ gem_port = self.get_gem_port_info(v_enet, traffic_class=2)
+ if gem_port is None:
+ self.log.info('Failed-to-get-gemport')
+ return
+ v_ont_ani = self.get_v_ont_ani(v_enet.v_enet.data.v_ontani_ref)
+ if v_ont_ani is None:
+ self.log.info('Failed-to-get-v_ont_ani',
+ v_ont_ani=v_enet.v_enet.data.v_ontani_ref)
+ return
+ tcont = self.get_tcont_info(v_ont_ani, name=gem_port.tcont_ref)
+ if tcont is None:
+ self.log.info('Failed-to-get-tcont-info',
+ tcont=gem_port.tcont_ref)
+ return
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id, onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if onu_device is None:
+ self.log.info('Failed-to-get-onu-device',
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ return
+
+ flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ dns_id)
+ try:
+ is_down_stream = False
+ self.log.info('Adding-DNS-upstream-flow',
+ classifier=uplink_classifier,
+ action=uplink_action,
+ gem_port=gem_port,
+ flow_id=flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ flow_id, gem_port.gemport_id,
+ uplink_classifier, is_down_stream,
+ action_info=uplink_action,
+ sched_id=tcont.alloc_id)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-DNS-upstream-flow', e=e,
+ classifier=uplink_classifier,
+ action=uplink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+ is_down_stream = True
+ # To-Do: For Now hard code the p-bit values.
+ downlink_classifier['vlan_pcp'] = 3
+ downlink_flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_dns_id)
+ try:
+ self.log.info('Adding-DNS-downstream-flow',
+ classifier=downlink_classifier,
+ action=downlink_action,
+ gem_port=gem_port,
+ flow_id=downlink_flow_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_flow_id, gem_port.gemport_id,
+ downlink_classifier, is_down_stream,
+ action_info=downlink_action)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-DNS-downstream-flow', e=e,
+ classifier=downlink_classifier,
+ action=downlink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ def add_arp_flow(self, uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, arp_id, downlink_arp_id):
+ # Add Upstream Firmware Flow.
+ # To-Do For a time being hard code the traffic class value.
+ # Need to know how to get the traffic class info from flows.
+ gem_port = self.get_gem_port_info(v_enet, traffic_class=2)
+ if gem_port is None:
+ self.log.info('Failed-to-get-gemport')
+ return
+ v_ont_ani = self.get_v_ont_ani(v_enet.v_enet.data.v_ontani_ref)
+ if v_ont_ani is None:
+ self.log.info('Failed-to-get-v_ont_ani',
+ v_ont_ani=v_enet.v_enet.data.v_ontani_ref)
+ return
+ tcont = self.get_tcont_info(v_ont_ani, name=gem_port.tcont_ref)
+ if tcont is None:
+ self.log.info('Failed-to-get-tcont-info',
+ tcont=gem_port.tcont_ref)
+ return
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id, onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if onu_device is None:
+ self.log.info('Failed-to-get-onu-device',
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ return
+
+ flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ arp_id)
+ try:
+ is_down_stream = False
+ self.log.info('Adding-ARP-upstream-flow',
+ classifier=uplink_classifier,
+ action=uplink_action,
+ gem_port=gem_port,
+ flow_id=flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ flow_id, gem_port.gemport_id,
+ uplink_classifier, is_down_stream,
+ action_info=uplink_action,
+ sched_id=tcont.alloc_id)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-ARP-upstream-flow', e=e,
+ classifier=uplink_classifier,
+ action=uplink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+ is_down_stream = True
+ # To-Do: For Now hard code the p-bit values.
+ downlink_classifier['vlan_pcp'] = 7
+ downlink_flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_arp_id)
+ try:
+ self.log.info('Adding-ARP-downstream-flow',
+ classifier=downlink_classifier,
+ action=downlink_action,
+ gem_port=gem_port,
+ flow_id=downlink_flow_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_flow_id, gem_port.gemport_id,
+ downlink_classifier, is_down_stream,
+ action_info=downlink_action)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-ARP-downstream-flow', e=e,
+ classifier=downlink_classifier,
+ action=downlink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+
+ def add_hsia_flow(self, uplink_classifier, uplink_action,
+ downlink_classifier, downlink_action,
+ v_enet, hsia_id, downlink_hsia_id):
+ # Add Upstream Firmware Flow.
+ # To-Do For a time being hard code the traffic class value.
+ # Need to know how to get the traffic class info from flows.
+ gem_port = self.get_gem_port_info(v_enet, traffic_class=2)
+ if gem_port is None:
+ self.log.info('Failed-to-get-gemport')
+ return
+ v_ont_ani = self.get_v_ont_ani(v_enet.v_enet.data.v_ontani_ref)
+ if v_ont_ani is None:
+ self.log.info('Failed-to-get-v_ont_ani',
+ v_ont_ani=v_enet.v_enet.data.v_ontani_ref)
+ return
+ tcont = self.get_tcont_info(v_ont_ani, name=gem_port.tcont_ref)
+ if tcont is None:
+ self.log.info('Failed-to-get-tcont-info',
+ tcont=gem_port.tcont_ref)
+ return
+ onu_device = self.adapter_agent.get_child_device(
+ self.device_id, onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ if onu_device is None:
+ self.log.info('Failed-to-get-onu-device',
+ onu_id=v_ont_ani.v_ont_ani.data.onu_id)
+ return
+
+ flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ hsia_id)
+ try:
+ is_down_stream = False
+ self.log.info('Adding-HSIA-upstream-flow',
+ classifier=uplink_classifier,
+ action=uplink_action,
+ gem_port=gem_port,
+ flow_id=flow_id,
+ sched_info=tcont.alloc_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ flow_id, gem_port.gemport_id,
+ uplink_classifier, is_down_stream,
+ action_info=uplink_action,
+ sched_id=tcont.alloc_id)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-HSIA-upstream-flow', e=e,
+ classifier=uplink_classifier,
+ action=uplink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
+ is_down_stream = True
+ # To-Do: For Now hard code the p-bit values.
+ downlink_classifier['vlan_pcp'] = 0
+ downlink_flow_id = self.get_flow_id(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_hsia_id)
+ try:
+ self.log.info('Adding-HSIA-downstream-flow',
+ classifier=downlink_classifier,
+ action=downlink_action,
+ gem_port=gem_port,
+ flow_id=downlink_flow_id)
+ self.bal.add_flow(onu_device.proxy_address.onu_id,
+ onu_device.proxy_address.channel_id,
+ downlink_flow_id, gem_port.gemport_id,
+ downlink_classifier, is_down_stream,
+ action_info=downlink_action)
+ # To-Do. While addition of one flow is in progress,
+ # we cannot add an another flow. Right now use sleep
+ # of 5 sec, assuming that addtion of flow is successful.
+ time.sleep(10)
+ except Exception as e:
+ self.log.exception('failed-to-install-HSIA-downstream-flow', e=e,
+ classifier=downlink_classifier,
+ action=downlink_action,
+ onu_id=onu_device.proxy_address.onu_id,
+ intf_id=onu_device.proxy_address.channel_id)
diff --git a/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py b/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py
index 1aeaf7f..437a587 100644
--- a/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py
+++ b/voltha/adapters/asfvolt16_olt/asfvolt16_olt.py
@@ -43,3 +43,45 @@
def stop(self):
self.rx_handler.stop()
+
+ def create_tcont(self, device, tcont_data, traffic_descriptor_data):
+ log.info('create-tcont', device_id=device.id)
+ if device.id in self.devices_handlers:
+ handler = self.devices_handlers[device.id]
+ if handler is not None:
+ handler.create_tcont(tcont_data, traffic_descriptor_data)
+
+ def update_tcont(self, device, tcont_data, traffic_descriptor_data):
+ log.info('update-tcont', device_id=device.id)
+ if device.id in self.devices_handlers:
+ handler = self.devices_handlers[device.id]
+ if handler is not None:
+ handler.update_tcont(tcont_data, traffic_descriptor_data)
+
+ def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
+ log.info('remove-tcont', device_id=device.id)
+ if device.id in self.devices_handlers:
+ handler = self.devices_handlers[device.id]
+ if handler is not None:
+ handler.remove_tcont(tcont_data, traffic_descriptor_data)
+
+ def create_gemport(self, device, data):
+ log.info('create-gemport', device_id=device.id)
+ if device.id in self.devices_handlers:
+ handler = self.devices_handlers[device.id]
+ if handler is not None:
+ handler.create_gemport(data)
+
+ def update_gemport(self, device, data):
+ log.info('update-gemport', device_id=device.id)
+ if device.id in self.devices_handlers:
+ handler = self.devices_handlers[device.id]
+ if handler is not None:
+ handler.update_gemport(data)
+
+ def remove_gemport(self, device, data):
+ log.info('remove-gemport', device_id=device.id)
+ if device.id in self.devices_handlers:
+ handler = self.devices_handlers[device.id]
+ if handler is not None:
+ handler.remove_gemport(data)
diff --git a/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py b/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py
index 8017e2b..5f60e9b 100644
--- a/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py
+++ b/voltha/adapters/asfvolt16_olt/asfvolt16_rx_handler.py
@@ -26,6 +26,7 @@
class Asfvolt16RxHandler(object):
+
def __init__(self, adapter, port, log):
self.adapter = adapter
self.adapter_agent = adapter.adapter_agent
diff --git a/voltha/adapters/asfvolt16_olt/bal.py b/voltha/adapters/asfvolt16_olt/bal.py
index 878202f..b246db1 100644
--- a/voltha/adapters/asfvolt16_olt/bal.py
+++ b/voltha/adapters/asfvolt16_olt/bal.py
@@ -18,8 +18,7 @@
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
-from common.utils.nethelpers import get_my_primary_interface, \
- get_my_primary_local_ipv4
+from common.utils.nethelpers import get_my_primary_local_ipv4
import os
"""
@@ -27,6 +26,7 @@
"""
ADAPTER_PORT = 60001
+
class Bal(object):
def __init__(self, olt, log):
self.log = log
@@ -37,7 +37,6 @@
@inlineCallbacks
def connect_olt(self, host_and_port, device_id):
- self.log.info('connecting-olt', host_and_port=host_and_port)
self.device_id = device_id
self.grpc_client.connect(host_and_port)
self.stub = bal_pb2.BalStub(self.grpc_client.channel)
@@ -60,6 +59,8 @@
TODO: Need to determine out what information
needs to be sent to the OLT at this stage.
'''
+ self.log.info('connecting-olt', host_and_port=host_and_port,
+ init_details=init)
yield self.stub.BalApiInit(init)
def activate_olt(self):
@@ -68,19 +69,18 @@
@inlineCallbacks
def set_access_terminal_admin_state(self, admin_state):
- self.log.info('setting-admin-state',
- admin_state=admin_state, device_id=self.device_id)
obj = bal_pb2.BalCfg()
obj.device_id = self.device_id.encode('ascii', 'ignore')
obj.hdr.obj_type = bal_model_ids_pb2.BAL_OBJ_ID_ACCESS_TERMINAL
obj.cfg.key.access_term_id = 0
obj.cfg.data.admin_state = admin_state
+ self.log.info('Activating-Access-Terminal-Device',
+ admin_state=admin_state, device_id=self.device_id,
+ access_terminal_details=obj)
yield self.stub.BalCfgSet(obj)
@inlineCallbacks
def activate_pon_port(self, olt_no, pon_port):
- self.log.info('activating-pon-port in olt',
- olt=olt_no, pon_port=pon_port)
try:
obj = bal_pb2.BalCfg()
# Fill Header details
@@ -92,6 +92,9 @@
obj.interface.data.admin_state = bal_model_types_pb2.BAL_STATE_UP
obj.interface.data.transceiver_type = \
bal_model_types_pb2.BAL_TRX_TYPE_XGPON_LTH_7226_PC
+ self.log.info('activating-pon-port-in-olt',
+ olt=olt_no, pon_port=pon_port,
+ pon_port_details=obj)
yield self.stub.BalCfgSet(obj)
except Exception as e:
self.log.info('activating-pon-port in olt-exception', exc=str(e))
@@ -99,9 +102,6 @@
@inlineCallbacks
def send_omci_request_message(self, proxy_address, msg):
- self.log.info('send_omci_request_message',
- proxy_address=proxy_address.channel_id,
- msg=msg)
try:
obj = bal_pb2.BalCfg()
# Fill Header details
@@ -115,6 +115,9 @@
obj.packet.key.packet_send_dest.itu_omci_channel.intf_id = \
proxy_address.channel_id
obj.packet.data.pkt = msg
+ self.log.info('send_omci_request_message',
+ proxy_address=proxy_address.channel_id,
+ omci_msg_details=obj)
yield self.stub.BalCfgSet(obj)
except Exception as e:
self.log.info('send-proxied_message-exception', exc=str(e))
@@ -122,8 +125,6 @@
@inlineCallbacks
def activate_onu(self, onu_info):
- self.log.info('activating-ONU in olt',
- olt=self.olt.olt_id, onu_id=onu_info['onu_id'])
try:
obj = bal_pb2.BalCfg()
# Fill Header details
@@ -138,6 +139,8 @@
onu_info['vendor_specific']
obj.terminal.data.registration_id = \
'202020202020202020202020202020202020202020202020202020202020202020202020'
+ self.log.info('activating-ONU-in-olt',
+ onu_details=obj)
yield self.stub.BalCfgSet(obj)
except Exception as e:
self.log.info('activating-ONU-exception',
@@ -146,10 +149,8 @@
@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
@@ -157,9 +158,183 @@
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
+ obj.packet.data.flow_type = bal_model_types_pb2.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
-
+ self.log.info('packet-out',
+ packet_out_details=obj)
yield self.stub.BalCfgSet(obj)
+
+ @inlineCallbacks
+ def add_flow(self, onu_id, intf_id, flow_id, gem_port,
+ classifier_info, is_downstream,
+ action_info=None, sched_id=None):
+ try:
+ obj = bal_pb2.BalCfg()
+ # Fill Header details
+ obj.device_id = self.device_id.encode('ascii', 'ignore')
+ obj.hdr.obj_type = bal_model_ids_pb2.BAL_OBJ_ID_FLOW
+ # Fill Access Terminal Details
+ # To-DO flow ID need to be retrieved from flow details
+ obj.flow.key.flow_id = flow_id
+ if is_downstream is False:
+ obj.flow.key.flow_type = \
+ bal_model_types_pb2.BAL_FLOW_TYPE_UPSTREAM
+ obj.flow.data.dba_tm_sched_id = sched_id
+ else:
+ obj.flow.key.flow_type = \
+ bal_model_types_pb2.BAL_FLOW_TYPE_DOWNSTREAM
+
+ obj.flow.data.admin_state = bal_model_types_pb2.BAL_STATE_UP
+ obj.flow.data.access_int_id = intf_id
+ #obj.flow.data.network_int_id = intf_id
+ obj.flow.data.sub_term_id = onu_id
+ obj.flow.data.svc_port_id = gem_port
+ obj.flow.data.classifier.presence_mask = 0
+ if 'eth_type' in classifier_info:
+ obj.flow.data.classifier.ether_type = \
+ classifier_info['eth_type']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_ETHER_TYPE
+ if 'ip_proto' in classifier_info:
+ obj.flow.data.classifier.ip_proto = \
+ classifier_info['ip_proto']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_IP_PROTO
+ if 'vlan_vid' in classifier_info:
+ obj.flow.data.classifier.o_vid = \
+ classifier_info['vlan_vid']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_O_VID
+ if 'vlan_pcp' in classifier_info:
+ obj.flow.data.classifier.o_pbits = \
+ classifier_info['vlan_pcp']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_O_PBITS
+ if 'udp_src' in classifier_info:
+ obj.flow.data.classifier.src_port = \
+ classifier_info['udp_src']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_SRC_PORT
+ if 'udp_dst' in classifier_info:
+ obj.flow.data.classifier.dst_port = \
+ classifier_info['udp_dst']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_DST_PORT
+ if 'ipv4_dst' in classifier_info:
+ obj.flow.data.classifier.dst_ip = \
+ classifier_info['ipv4_dst']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_DST_IP
+ if 'ipv4_src' in classifier_info:
+ obj.flow.data.classifier.src_ip = \
+ classifier_info['ipv4_src']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_SRC_IP
+ if 'metadata' in classifier_info:
+ obj.flow.data.classifier.i_vid = \
+ classifier_info['metadata']
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_I_VID
+ if 'pkt_tag_type' in classifier_info:
+ if classifier_info['pkt_tag_type'] == 'single_tag':
+ obj.flow.data.classifier.pkt_tag_type = \
+ bal_model_types_pb2.BAL_PKT_TAG_TYPE_SINGLE_TAG
+ elif classifier_info['pkt_tag_type'] == 'double_tag':
+ obj.flow.data.classifier.pkt_tag_type = \
+ bal_model_types_pb2.BAL_PKT_TAG_TYPE_DOUBLE_TAG
+ elif classifier_info['pkt_tag_type'] == 'untagged':
+ obj.flow.data.classifier.pkt_tag_type = \
+ bal_model_types_pb2.BAL_PKT_TAG_TYPE_UNTAGGED
+ else:
+ obj.flow.data.classifier.pkt_tag_type = \
+ bal_model_types_pb2.BAL_PKT_TAG_TYPE_NONE
+ obj.flow.data.classifier.presence_mask |= \
+ bal_model_types_pb2.BAL_CLASSIFIER_ID_PKT_TAG_TYPE
+
+ if action_info is not None:
+ obj.flow.data.action.presence_mask = 0
+ obj.flow.data.action.cmds_bitmask = 0
+ if 'pop_vlan' in action_info:
+ obj.flow.data.action.o_vid = action_info['vlan_vid']
+ obj.flow.data.action.cmds_bitmask |= \
+ bal_model_types_pb2.BAL_ACTION_CMD_ID_REMOVE_OUTER_TAG
+ obj.flow.data.action.presence_mask |= \
+ bal_model_types_pb2.BAL_ACTION_ID_CMDS_BITMASK
+ obj.flow.data.action.presence_mask |= \
+ bal_model_types_pb2.BAL_ACTION_ID_O_VID
+ elif 'push_vlan' in action_info:
+ obj.flow.data.action.o_vid = action_info['vlan_vid']
+ obj.flow.data.action.cmds_bitmask |= \
+ bal_model_types_pb2.BAL_ACTION_CMD_ID_ADD_OUTER_TAG
+ obj.flow.data.action.presence_mask |= \
+ bal_model_types_pb2.BAL_ACTION_ID_CMDS_BITMASK
+ obj.flow.data.action.presence_mask |= \
+ bal_model_types_pb2.BAL_ACTION_ID_O_VID
+ elif 'trap_to_host' in action_info:
+ obj.flow.data.action.cmds_bitmask |= \
+ bal_model_types_pb2.BAL_ACTION_CMD_ID_TRAP_TO_HOST
+ obj.flow.data.action.presence_mask |= \
+ bal_model_types_pb2.BAL_ACTION_ID_CMDS_BITMASK
+ else:
+ self.log.info('Invalid-action-field')
+ return
+ self.log.info('adding-flow-to-OLT-Device',
+ flow_details=obj)
+ yield self.stub.BalCfgSet(obj)
+ except Exception as e:
+ self.log.info('add_flow-exception',
+ flow_id, onu_id, exc=str(e))
+ return
+
+ @inlineCallbacks
+ def create_scheduler(self, id, direction, owner_info, num_priority):
+ try:
+ obj = bal_pb2.BalCfg()
+ # Fill Header details
+ obj.device_id = self.device_id.encode('ascii', 'ignore')
+ obj.hdr.obj_type = bal_model_ids_pb2.BAL_OBJ_ID_TM_SCHED
+ # Fill Access Terminal Details
+ if direction == 'downstream':
+ obj.tm_sched_cfg.key.dir =\
+ bal_model_types_pb2.BAL_TM_SCHED_DIR_DS
+ else:
+ obj.tm_sched_cfg.key.dir = \
+ bal_model_types_pb2.BAL_TM_SCHED_DIR_US
+ obj.tm_sched_cfg.key.id = id
+
+ if owner_info['type'] == 'agg_port':
+ obj.tm_sched_cfg.data.owner.type = \
+ bal_model_types_pb2.BAL_TM_SCHED_OWNER_TYPE_AGG_PORT
+ obj.tm_sched_cfg.data.owner.agg_port.presence_mask = 0
+ obj.tm_sched_cfg.data.owner.agg_port.intf_id =\
+ owner_info['intf_id']
+ obj.tm_sched_cfg.data.owner.agg_port.presence_mask |= \
+ bal_model_types_pb2.BAL_TM_SCHED_OWNER_AGG_PORT_ID_INTF_ID
+ obj.tm_sched_cfg.data.owner.agg_port.sub_term_id = \
+ owner_info['onu_id']
+ obj.tm_sched_cfg.data.owner.agg_port.presence_mask |= \
+ bal_model_types_pb2.BAL_TM_SCHED_OWNER_AGG_PORT_ID_SUB_TERM_ID
+ obj.tm_sched_cfg.data.owner.agg_port.agg_port_id = \
+ owner_info['alloc_id']
+ obj.tm_sched_cfg.data.owner.agg_port.presence_mask |= \
+ bal_model_types_pb2.BAL_TM_SCHED_OWNER_AGG_PORT_ID_AGG_PORT_ID
+ else:
+ self.log.error('Not supported scheduling type',
+ sched_type=owner_info['type'])
+ return
+ obj.tm_sched_cfg.data.sched_type = \
+ bal_model_types_pb2.BAL_TM_SCHED_TYPE_SP_WFQ
+ obj.tm_sched_cfg.data.num_priorities = num_priority
+ self.log.info('Creating Scheduler',
+ scheduler_details=obj)
+ yield self.stub.BalCfgSet(obj)
+ except Exception as e:
+ self.log.info('creat-scheduler-exception',
+ olt=self.olt.olt_id,
+ sched_id=id,
+ direction=direction,
+ owner=owner_info,
+ exc=str(e))
+ return
diff --git a/voltha/adapters/broadcom_onu/broadcom_onu.py b/voltha/adapters/broadcom_onu/broadcom_onu.py
index bef5adf..44bbe48 100644
--- a/voltha/adapters/broadcom_onu/broadcom_onu.py
+++ b/voltha/adapters/broadcom_onu/broadcom_onu.py
@@ -37,6 +37,8 @@
from voltha.protos.logical_device_pb2 import LogicalPort
from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, OFPPF_1GB_FD
from voltha.protos.openflow_13_pb2 import OFPXMC_OPENFLOW_BASIC, ofp_port
+from voltha.protos.bbf_fiber_base_pb2 import VEnetConfig
+
from common.frameio.frameio import hexify
from voltha.extensions.omci.omci import *
@@ -204,7 +206,8 @@
raise NotImplementedError()
def create_tcont(self, device, tcont_data, traffic_descriptor_data):
- raise NotImplementedError()
+ log.info('Not implemented Yet', device_id=device.id)
+ #raise NotImplementedError()
def update_tcont(self, device, tcont_data, traffic_descriptor_data):
raise NotImplementedError()
@@ -213,7 +216,8 @@
raise NotImplementedError()
def create_gemport(self, device, data):
- raise NotImplementedError()
+ log.info('Not implemented Yet', device_id=device.id)
+ #raise NotImplementedError()
def update_gemport(self, device, data):
raise NotImplementedError()
@@ -1308,13 +1312,44 @@
yield self.wait_for_response()
def create_interface(self, data):
- self.log.info('Not Implemented yet')
- return;
+ if isinstance(data, VEnetConfig):
+ parent_port_num = None
+ onu_device = self.adapter_agent.get_device(self.device_id)
+ ports = self.adapter_agent.get_ports(onu_device.parent_id, Port.ETHERNET_UNI)
+ parent_port_num = None
+ for port in ports:
+ if port.label == data.interface.name:
+ parent_port_num = port.port_no
+ break
+
+ if not parent_port_num:
+ self.log.error("matching-parent-uni-port-num-not-found")
+ return
+
+ onu_ports = self.adapter_agent.get_ports(self.device_id, Port.PON_ONU)
+ if onu_ports:
+ # To-Do :
+ # Assumed only one PON port and UNI port per ONU.
+ pon_port = onu_ports[0]
+ else:
+ self.log.error("No-Pon-port-configured-yet")
+ return
+
+ self.adapter_agent.delete_port_reference_from_parent(self.device_id,
+ pon_port)
+
+ pon_port.peers[0].device_id = onu_device.parent_id
+ pon_port.peers[0].port_no = parent_port_num
+ self.adapter_agent.add_port_reference_to_parent(self.device_id,
+ pon_port)
+ else:
+ self.log.info('Not handled Yet')
+ return
def update_interface(self, data):
self.log.info('Not Implemented yet')
- return;
+ return
def remove_interface(self, data):
self.log.info('Not Implemented yet')
- return;
+ return
diff --git a/voltha/core/adapter_agent.py b/voltha/core/adapter_agent.py
index 95fb4d6..2f73505 100644
--- a/voltha/core/adapter_agent.py
+++ b/voltha/core/adapter_agent.py
@@ -478,6 +478,10 @@
self.log.info('delete-port-reference', device_id=device_id, port=port)
self._del_peer_reference(device_id, port)
+ # update child port details
+ self._make_up_to_date('/devices/{}/ports'.format(device_id),
+ port.port_no, port)
+
def add_port_reference_to_parent(self, device_id, port):
"""
Add the port reference to the parent device
@@ -488,6 +492,9 @@
assert isinstance(port, Port)
self.log.info('add-port-reference', device_id=device_id, port=port)
self._add_peer_reference(device_id, port)
+ # update child port details
+ self._make_up_to_date('/devices/{}/ports'.format(device_id),
+ port.port_no, port)
def _find_first_available_id(self):
logical_devices = self.root_proxy.get('/logical_devices')
diff --git a/voltha/core/xpon_handler.py b/voltha/core/xpon_handler.py
index e91a604..c102c1a 100644
--- a/voltha/core/xpon_handler.py
+++ b/voltha/core/xpon_handler.py
@@ -87,7 +87,7 @@
design evolution, for a better approach in future.
'''
self.cg_dict[cg.name] = {'alloc_id': IndexPool(16383, 1024)}
- self.cg_dict[cg.name].update({'gemport_id': IndexPool(64500, 1021)})
+ self.cg_dict[cg.name].update({'gemport_id': IndexPool(64500, 1024)})
self.cg_pool.pre_allocate(cg_tup)
def reinitialize_tcont_and_gemport_ids(self):
@@ -128,7 +128,7 @@
request.cg_index = _id
self.root.add('/channel_groups', request)
self.cg_dict[request.name] = {'alloc_id': IndexPool(16383, 1024)}
- self.cg_dict[request.name].update({'gemport_id': IndexPool(64500, 1021)})
+ self.cg_dict[request.name].update({'gemport_id': IndexPool(64500, 1024)})
return Empty()
except AssertionError, e: