VOL-2823 Change vlan-filter task to support TT case
-Instead of hardcoded values, use the vid and pcp values in flow.
-Add task removal for flow-remove case.
-make incremental EVTO feature configurable 'accept_incremental_evto_update'
parameter. This feature is disabled by default.
Change-Id: Id6178af89daa0b6897274db6067025d271fdd101
diff --git a/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py b/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
index 700a0ee..9c8ebfa 100644
--- a/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
+++ b/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
@@ -502,7 +502,6 @@
_set_vlan_pcp=filter_info.get("set_vlan_pcp"),
tp_id=filter_info.get("tp_id"))
# Now remove the entry from the dictionary
- self._queued_vlan_filter_task[uni_id][tp_id].remove(filter_info)
self.log.debug("executed-queued-vlan-filter-task",
uni_id=uni_id, tp_id=tp_id)
# Now delete the key entries once we have handled the queued vlan filter tasks.
@@ -847,7 +846,18 @@
self.log.debug('The dhcp trap-to-host flow will be discarded', device_id=device.id)
return
- _vlan_vid = 0
+ _match_vlan_vid = None
+ for field in fd.get_ofb_fields(flow):
+ if field.type == fd.VLAN_VID:
+ if field.vlan_vid == RESERVED_TRANSPARENT_VLAN and field.vlan_vid_mask == RESERVED_TRANSPARENT_VLAN:
+ _match_vlan_vid = RESERVED_TRANSPARENT_VLAN
+ else:
+ _match_vlan_vid = field.vlan_vid & 0xfff
+ self.log.debug('field-type-vlan-vid',
+ vlan=_match_vlan_vid)
+
+ _set_vlan_vid = None
+ _set_vlan_pcp = None
# Retrieve the VLAN_VID that needs to be removed from the EVTO rule on the ONU.
for action in fd.get_actions(flow):
if action.type == fd.SET_FIELD:
@@ -855,9 +865,13 @@
assert (action.set_field.field.oxm_class ==
OFPXMC_OPENFLOW_BASIC)
if _field.type == fd.VLAN_VID:
- _vlan_vid = _field.vlan_vid & 0xfff
+ _set_vlan_vid = _field.vlan_vid & 0xfff
self.log.debug('vlan-vid-to-remove',
- _vlan_vid=_vlan_vid, in_port=_in_port)
+ _vlan_vid=_set_vlan_vid, in_port=_in_port)
+ elif _field.type == fd.VLAN_PCP:
+ _set_vlan_pcp = _field.vlan_pcp
+ self.log.debug('set-field-type-vlan-pcp',
+ vlan_pcp=_set_vlan_pcp)
uni_port = self.uni_port(_in_port)
uni_id = _in_port & 0xF
@@ -870,7 +884,8 @@
# The vlan filter remove should be followed by a TP deleted for that TP ID.
# Use this information to re-schedule any vlan filter add tasks for the same TP ID again.
# First check if the TP download was done, before we access that TP delete is necessary
- if uni_id in self._tech_profile_download_done and tp_id in self._tech_profile_download_done[uni_id] and \
+ if uni_id in self._tech_profile_download_done and tp_id in self._tech_profile_download_done[
+ uni_id] and \
self._tech_profile_download_done[uni_id][tp_id] is True:
if uni_id not in self._pending_delete_tp:
self._pending_delete_tp[uni_id] = dict()
@@ -878,9 +893,11 @@
else:
self._pending_delete_tp[uni_id][tp_id] = True
# Deleting flow from ONU.
- self._remove_vlan_filter_task(device, uni_id, uni_port=uni_port, _set_vlan_vid=_vlan_vid,
- match_vlan=_vlan_vid, tp_id=tp_id)
-
+ self._remove_vlan_filter_task(device, uni_id, uni_port=uni_port,
+ _set_vlan_pcp=_set_vlan_pcp,
+ _set_vlan_vid=_set_vlan_vid,
+ match_vlan=_match_vlan_vid,
+ tp_id=tp_id)
# TODO:Delete TD task.
except Exception as e:
self.log.exception('failed-to-remove-flow', e=e)
@@ -916,7 +933,7 @@
_push_tpid = None
_field = None
_set_vlan_vid = None
- _set_vlan_pcp = 0
+ _set_vlan_pcp = None
_tunnel_id = None
self.log.debug("add-flow", device_id=device.id, flow=flow)
@@ -1385,7 +1402,7 @@
self._onu_persisted_state['onu_id'] = onu_indication.onu_id
self._onu_persisted_state['intf_id'] = onu_indication.intf_id
self._onu_persisted_state['admin_state'] = onu_indication.admin_state
- self._onu_persisted_state['oper_state'] = onu_indication.oper_state
+ self._onu_persisted_state['oper_state'] = onu_indication.oper_state
if onu_indication.oper_state == "up":
yield self.create_interface(onu_indication)
@@ -1471,7 +1488,6 @@
self.log.warn('received-onu-indication-for-active-onu', onu_indication=onu_indication)
return
-
yield self.core_proxy.device_state_update(self.device_id, oper_status=OperStatus.ACTIVATING,
connect_status=ConnectStatus.REACHABLE)
diff --git a/python/adapters/brcm_openomci_onu/main.py b/python/adapters/brcm_openomci_onu/main.py
index 54161ec..def8e64 100755
--- a/python/adapters/brcm_openomci_onu/main.py
+++ b/python/adapters/brcm_openomci_onu/main.py
@@ -64,6 +64,7 @@
device_type=os.environ.get('DEVICE_TYPE', 'openonu'),
accept_bulk_flow=os.environ.get('ACCEPT_BULK_FLOW', True),
accept_atomic_flow=os.environ.get('ACCEPT_ATOMIC_FLOW', True),
+ accept_incremental_evto_update=os.environ.get('ACCEPT_INCREMENTAL_EVTO_UPDATE', False),
etcd=os.environ.get('ETCD', 'localhost:2379'),
core_topic=os.environ.get('CORE_TOPIC', 'rwcore'),
event_topic=os.environ.get('EVENT_TOPIC', 'voltha.events'),
@@ -148,6 +149,14 @@
default=defs['accept_atomic_flow'],
help=_help)
+ _help = 'specifies whether the adapter accepts incremental EVTO updates ' \
+ '(default: %s)' % defs['accept_incremental_evto_update']
+ parser.add_argument('-aie', '--accept_incremental_evto_update',
+ dest='accept_incremental_evto_update',
+ action='store',
+ default=defs['accept_incremental_evto_update'],
+ help=_help)
+
_help = '<hostname>:<port> to etcd server (default: %s)' % defs['etcd']
parser.add_argument('-e', '--etcd',
dest='etcd',
diff --git a/python/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py b/python/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py
index 678fd54..1e8003c 100644
--- a/python/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py
+++ b/python/adapters/brcm_openomci_onu/omci/brcm_mib_download_task.py
@@ -17,7 +17,7 @@
from twisted.internet.defer import inlineCallbacks, returnValue, TimeoutError, failure
from pyvoltha.adapters.extensions.omci.omci_me import PptpEthernetUniFrame, GalEthernetProfileFrame, \
MacBridgePortConfigurationDataFrame, MacBridgeServiceProfileFrame, Ieee8021pMapperServiceProfileFrame, \
- VeipUniFrame, ExtendedVlanTaggingOperationConfigurationDataFrame
+ VeipUniFrame, ExtendedVlanTaggingOperationConfigurationDataFrame,Ont2GFrame
from pyvoltha.adapters.extensions.omci.tasks.task import Task
from pyvoltha.adapters.extensions.omci.omci_defs import EntityOperations, ReasonCodes
from uni_port import UniType
@@ -195,6 +195,13 @@
results = yield omci_cc.send(frame)
self.check_status_and_state(results, 'create-gal-ethernet-profile')
+ ont2_attributes = dict(current_connectivity_mode=5)
+ msg = Ont2GFrame(attributes=ont2_attributes)
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-ont2g')
+
except TimeoutError as e:
self.log.warn('rx-timeout-initial-gal-profile', e=e)
raise
@@ -223,12 +230,12 @@
# TODO: magic. event if static, assign to a meaningful variable name
attributes = {
'spanning_tree_ind': False,
- 'learning_ind': True,
+ 'learning_ind': False,
'priority': 0x8000,
'max_age': 20 * 256,
'hello_time': 2 * 256,
'forward_delay': 15 * 256,
- 'unknown_mac_address_discard': True
+ 'unknown_mac_address_discard': False
}
msg = MacBridgeServiceProfileFrame(
self._mac_bridge_service_profile_entity_id + uni_port.mac_bridge_port_num,
@@ -253,10 +260,10 @@
# default to PPTP
tp_type = 1
+ association_type = 2
if uni_port.type.value == UniType.VEIP.value:
tp_type = 11
- elif uni_port.type.value == UniType.PPTP.value:
- tp_type = 1
+ association_type = 10
msg = MacBridgePortConfigurationDataFrame(
self._mac_bridge_port_ani_entity_id + uni_port.entity_id, # Entity ID
@@ -270,6 +277,40 @@
results = yield omci_cc.send(frame)
self.check_status_and_state(results, 'create-mac-bridge-port-configuration-data-uni-port')
+
+ ################################################################################
+ # Create Extended VLAN Tagging Operation config (UNI-side)
+ #
+ # EntityID relates to the VLAN TCIS later used int vlan filter task. This only
+ # sets up the inital MIB entry as it relates to port config, it does not set vlan
+ # that is saved for the vlan filter task
+ #
+ # References:
+ # - PPTP Ethernet or VEIP UNI
+ #
+
+ attributes = dict(
+ association_type=association_type, # Assoc Type, PPTP/VEIP Ethernet UNI
+ associated_me_pointer=uni_port.entity_id, # Assoc ME, PPTP/VEIP Entity Id
+
+ # See VOL-1311 - Need to set table during create to avoid exception
+ # trying to read back table during post-create-read-missing-attributes
+ # But, because this is a R/W attribute. Some ONU may not accept the
+ # value during create. It is repeated again in a set below.
+ input_tpid=self._input_tpid, # input TPID
+ output_tpid=self._output_tpid, # output TPID
+ )
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ self._mac_bridge_service_profile_entity_id + uni_port.mac_bridge_port_num, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.create()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield omci_cc.send(frame)
+ self.check_status_and_state(results, 'create-extended-vlan-tagging-operation-configuration-data')
+
except TimeoutError as e:
self.log.warn('rx-timeout-inital-per-uni-setup', e=e)
raise
diff --git a/python/adapters/brcm_openomci_onu/omci/brcm_vlan_filter_task.py b/python/adapters/brcm_openomci_onu/omci/brcm_vlan_filter_task.py
index 484ed45..83a517f 100644
--- a/python/adapters/brcm_openomci_onu/omci/brcm_vlan_filter_task.py
+++ b/python/adapters/brcm_openomci_onu/omci/brcm_vlan_filter_task.py
@@ -20,8 +20,10 @@
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks, failure, returnValue
from pyvoltha.adapters.extensions.omci.omci_defs import ReasonCodes, EntityOperations
+from pyvoltha.adapters.extensions.omci.omci_entities import VlanTaggingFilterData
from pyvoltha.adapters.extensions.omci.omci_me import \
- VlanTaggingOperation, VlanTaggingFilterDataFrame, ExtendedVlanTaggingOperationConfigurationDataFrame
+ VlanTaggingOperation, VlanTaggingFilterDataFrame, ExtendedVlanTaggingOperationConfigurationDataFrame, \
+ ExtendedVlanTaggingOperationConfigurationData
from uni_port import UniType
from uni_port import RESERVED_TRANSPARENT_VLAN
from pon_port import DEFAULT_TPID
@@ -51,6 +53,7 @@
:param handler: (BrcmOpenomciOnuHandler) ONU Device Handler Instance
:param uni_port: (UniPort) Object instance representing the uni port and its settings
:param set_vlan_id: (int) VLAN to filter for and set
+ :param add_tag: (bool) Flag to identify VLAN Tagging or Untagging
:param tp_id: (int) TP ID for the flow
:param priority: (int) OpenOMCI Task priority (0..255) 255 is the highest
"""
@@ -68,17 +71,40 @@
uni_port=uni_port.port_number,
set_vlan_id=set_vlan_id)
+ self._onu_handler = handler
self._device = omci_agent.get_device(handler.device_id)
self._uni_port = uni_port
self._set_vlan_id = set_vlan_id
- self._set_vlan_pcp = set_vlan_pcp
- self._match_vlan = match_vlan
+
+ # If not setting any pbit, copy the pbit from the received vlan tag
+ if set_vlan_pcp is None:
+ self._set_vlan_pcp = 8 # Copy from the inner priority of the received frame
+ else:
+ self._set_vlan_pcp = set_vlan_pcp
+
+ # If not matching on any vlan do not filter for vlan value. effectively match on untagged
+ if match_vlan is None:
+ self._match_vlan = RESERVED_TRANSPARENT_VLAN # Do not filter on the VID
+ else:
+ self._match_vlan = match_vlan
+
+ self._vlan_pcp = 8 # Do not filter on priority
+
+ # If the tag is not transparent then need to remove it.
+ self._treatment_tags_to_remove = 1
+ if self._match_vlan == RESERVED_TRANSPARENT_VLAN: # Do not filter on the VID
+ self._vlan_pcp = 15 # This entry is a no-tag rule; ignore all other VLAN tag filter fields
+ self._treatment_tags_to_remove = 0
+
+ # If matching on untagged and trying to copy pbit from non-existent received vlan, set pbit to zero
+ if self._match_vlan == RESERVED_TRANSPARENT_VLAN and self._set_vlan_pcp == 8:
+ self._set_vlan_pcp = 0
+
self._add_tag = add_tag
self._tp_id = tp_id
self._results = None
self._local_deferred = None
self._config = self._device.configuration
-
self._input_tpid = DEFAULT_TPID
self._output_tpid = DEFAULT_TPID
@@ -113,223 +139,24 @@
"""
Perform the vlan tagging
"""
- self.log.debug('vlan-filter-tagging-task', device_id=self._device._device_id, uni_port=self._uni_port, set_vlan_id=self._set_vlan_id, \
- set_vlan_pcp=self._set_vlan_pcp, match_vlan=self._match_vlan, tp_id=self._tp_id, add_tag=self._add_tag)
-
+ self.log.debug('vlan-filter-tagging-task', uni_port=self._uni_port, set_vlan_id=self._set_vlan_id,
+ set_vlan_pcp=self._set_vlan_pcp, match_vlan=self._match_vlan, tp_id=self._tp_id,
+ add_tag=self._add_tag)
try:
if self._add_tag:
- ################################################################################
- # VLAN Tagging Filter config
- #
- # EntityID will be referenced by:
- # - Nothing
- # References:
- # - MacBridgePortConfigurationData for the ANI/PON side
- #
-
-
- # Delete bridge ani side vlan filter
- eid = self._mac_bridge_port_ani_entity_id + self._uni_port.entity_id + self._tp_id # Entity ID
- msg = VlanTaggingFilterDataFrame(eid)
- frame = msg.delete()
- self.log.debug('openomci-msg', omci_msg=msg)
- self.strobe_watchdog()
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'flow-delete-vlan-tagging-filter-data')
-
- ################################################################################
- # Create Extended VLAN Tagging Operation config (UNI-side)
- #
- # EntityID relates to the VLAN TCIS later used int vlan filter task. This only
- # sets up the inital MIB entry as it relates to port config, it does not set vlan
- # that is saved for the vlan filter task
- #
- # References:
- # - PPTP Ethernet or VEIP UNI
- #
-
-
- # Delete uni side evto
- msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
- self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num,
- )
- frame = msg.delete()
- self.log.debug('openomci-msg', omci_msg=msg)
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'delete-extended-vlan-tagging-operation-configuration-data')
-
-
- # Re-Create uni side evto
- # default to PPTP
- association_type = 2
- if self._uni_port.type.value == UniType.VEIP.value:
- association_type = 10
- elif self._uni_port.type.value == UniType.PPTP.value:
- association_type = 2
-
- attributes = dict(
- association_type=association_type, # Assoc Type, PPTP/VEIP Ethernet UNI
- associated_me_pointer=self._uni_port.entity_id, # Assoc ME, PPTP/VEIP Entity Id
-
- # See VOL-1311 - Need to set table during create to avoid exception
- # trying to read back table during post-create-read-missing-attributes
- # But, because this is a R/W attribute. Some ONU may not accept the
- # value during create. It is repeated again in a set below.
- input_tpid=self._input_tpid, # input TPID
- output_tpid=self._output_tpid, # output TPID
- )
-
- msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
- self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num, # Bridge Entity ID
- attributes=attributes
- )
-
- frame = msg.create()
- self.log.debug('openomci-msg', omci_msg=msg)
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'create-extended-vlan-tagging-operation-configuration-data')
-
- attributes = dict(
- # Specifies the TPIDs in use and that operations in the downstream direction are
- # inverse to the operations in the upstream direction
- input_tpid=self._input_tpid, # input TPID
- output_tpid=self._output_tpid, # output TPID
- downstream_mode=0, # inverse of upstream
- )
-
- msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
- self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num, # Bridge Entity ID
- attributes=attributes
- )
-
- frame = msg.set()
- self.log.debug('openomci-msg', omci_msg=msg)
- self.strobe_watchdog()
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'set-extended-vlan-tagging-operation-configuration-data')
-
- # Onu-Transparent
- if self._set_vlan_id == RESERVED_TRANSPARENT_VLAN:
- # Transparently send any single tagged packet.
- # As the onu is to be transparent, no need to create VlanTaggingFilterData ME.
- # Any other specific rules will take priority over this, so not setting any other vlan specific rules
- attributes = dict(
- received_frame_vlan_tagging_operation_table=
- VlanTaggingOperation(
- filter_outer_priority=15,
- filter_outer_vid=4096,
- filter_outer_tpid_de=0,
- filter_inner_priority=14,
- filter_inner_vid=4096,
- filter_inner_tpid_de=0,
- filter_ether_type=0,
- treatment_tags_to_remove=0,
- treatment_outer_priority=15,
- treatment_outer_vid=0,
- treatment_outer_tpid_de=0,
- treatment_inner_priority=15,
- treatment_inner_vid=0,
- treatment_inner_tpid_de=4
- )
- )
-
- msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
- self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num, # Bridge Entity ID
- attributes=attributes
- )
-
- frame = msg.set()
- self.log.debug('openomci-msg', omci_msg=msg)
- self.strobe_watchdog()
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'set-evto-table-transparent-vlan')
-
+ if not self._onu_handler.args.accept_incremental_evto_update:
+ yield self._bulk_update_evto_and_vlan_tag_filter()
else:
- # Re-Create bridge ani side vlan filter
- forward_operation = 0x10 # VID investigation
-
- msg = VlanTaggingFilterDataFrame(
- eid,
- vlan_tcis=[self._set_vlan_id], # VLAN IDs
- forward_operation=forward_operation
- )
- frame = msg.create()
- self.log.debug('openomci-msg', omci_msg=msg)
- self.strobe_watchdog()
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'flow-create-vlan-tagging-filter-data')
- # Update uni side extended vlan filter
- # filter for untagged
- attributes = dict(
- received_frame_vlan_tagging_operation_table=
- VlanTaggingOperation(
- filter_outer_priority=15,
- filter_outer_vid=4096,
- filter_outer_tpid_de=0,
- filter_inner_priority=15,
- filter_inner_vid=4096,
- filter_inner_tpid_de=0,
- filter_ether_type=0,
- treatment_tags_to_remove=0,
- treatment_outer_priority=15,
- treatment_outer_vid=0,
- treatment_outer_tpid_de=0,
- treatment_inner_priority=0,
- treatment_inner_vid=self._set_vlan_id,
- treatment_inner_tpid_de=4
- )
- )
-
- msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
- self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num, # Bridge Entity ID
- attributes=attributes
- )
-
- frame = msg.set()
- self.log.debug('openomci-msg', omci_msg=msg)
- self.strobe_watchdog()
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'set-evto-table-untagged')
-
- # Update uni side extended vlan filter
- # filter for vlan 0
- attributes = dict(
- received_frame_vlan_tagging_operation_table=
- VlanTaggingOperation(
- filter_outer_priority=15, # This entry is not a double-tag rule
- filter_outer_vid=4096, # Do not filter on the outer VID value
- filter_outer_tpid_de=0, # Do not filter on the outer TPID field
-
- filter_inner_priority=8, # Filter on inner vlan
- filter_inner_vid=0x0, # Look for vlan 0
- filter_inner_tpid_de=0, # Do not filter on inner TPID field
- filter_ether_type=0, # Do not filter on EtherType
-
- treatment_tags_to_remove=1,
- treatment_outer_priority=15,
- treatment_outer_vid=0,
- treatment_outer_tpid_de=0,
-
- treatment_inner_priority=8, # Add an inner tag and insert this value as the priority
- treatment_inner_vid=self._set_vlan_id, # use this value as the VID in the inner VLAN tag
- treatment_inner_tpid_de=4, # set TPID
- )
- )
- msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
- self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num, # Bridge Entity ID
- attributes=attributes # See above
- )
- frame = msg.set()
- self.log.debug('openomci-msg', omci_msg=msg)
- self.strobe_watchdog()
- results = yield self._device.omci_cc.send(frame)
- self.check_status_and_state(results, 'set-evto-table-zero-tagged')
-
- else: #addTag = False
- #TODO: needs to be implemented - future task.
- self.log.debug('removing-vlan-filter-tag', uni_port=self._uni_port, match_vlan=self._match_vlan, )
+ yield self._incremental_update_evto_and_vlan_tag_filter()
+ else: # addTag = False
+ if self._onu_handler.args.accept_incremental_evto_update:
+ self.log.info('removing-vlan-tagging')
+ yield self._delete_service_flow()
+ yield self._delete_vlan_filter_entity()
+ else:
+ # Will be reset anyway on new vlan tagging operation
+ self.log.info("not-removing-vlan-tagging")
self.deferred.callback(self)
-
except Exception as e:
self.log.exception('setting-vlan-tagging', e=e)
self.deferred.errback(failure.Failure(e))
@@ -361,3 +188,411 @@
elif status == RC.InstanceExists:
return False
+ @inlineCallbacks
+ def _delete_service_flow(self):
+ extended_vlan_tagging_entity_id = self._mac_bridge_service_profile_entity_id + \
+ self._uni_port.mac_bridge_port_num
+
+ # See G.988 regarding evto row deletes for "default" flows:
+ #
+ # As an exception to the rule on ordered processing, these default rules are always
+ # considered as a last resort for frames that do not match any other rule. Best
+ # practice dictates that these entries not be deleted by the OLT; however, they
+ # can be modified to produce the desired default behaviour.
+ #
+ # 15, 4096, x, 15, 4096, x, 0, (0, 15, x, x, 15, x, x) – no tags
+ # 15, 4096, x, 14, 4096, x, 0, (0, 15, x, x, 15, x, x) – 1 tag
+ # 14, 4096, x, 14, 4096, x, 0, (0, 15, x, x, 15, x, x) – 2 tags
+
+ # outer_prio is 15, outer vid is 4096 inner prio is 15, inner vid is 4096
+ # its a default rule... dont delete it.
+ if self._match_vlan == RESERVED_TRANSPARENT_VLAN and self._vlan_pcp == 15:
+ self.log.warn("should-not-delete-onu-builtin-no-tag-flow")
+ return
+
+ # outer_prio is 15, outer vid is 4096 inner prio is 14, inner vid is 4096
+ # its a default rule... dont delete it.
+ if self._match_vlan == RESERVED_TRANSPARENT_VLAN and self._vlan_pcp == 14:
+ self.log.warn("should-not-delete-onu-builtin-single-tag-flow")
+ return
+
+ entry = VlanTaggingOperation(
+ filter_outer_priority=15,
+ filter_outer_vid=4096,
+ filter_outer_tpid_de=0,
+
+ filter_inner_priority=self._vlan_pcp,
+ filter_inner_vid=self._match_vlan,
+ filter_inner_tpid_de=0,
+ filter_ether_type=0
+ )
+ # delete this entry using the filter rules as the key.
+ # this function automatically fills 0xFF in the last 8 treatment bytes
+ entry = entry.delete()
+ attributes = dict(received_frame_vlan_tagging_operation_table=entry)
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes # See above
+ )
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'delete-service-flow')
+
+ @inlineCallbacks
+ def _delete_vlan_filter_entity(self):
+ vlan_tagging_entity_id = int(self._mac_bridge_port_ani_entity_id + self._uni_port.entity_id
+ + self._tp_id)
+ self.log.debug("Vlan tagging filter data frame will be deleted.",
+ expected_me_id=vlan_tagging_entity_id)
+ msg = VlanTaggingFilterDataFrame(vlan_tagging_entity_id)
+ frame = msg.delete()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'flow-delete-vlan-tagging-filter-data')
+
+ @inlineCallbacks
+ def _create_vlan_filter_entity(self, vlan_tagging_entity_id):
+
+ self.log.debug("Vlan tagging filter data frame will be created.",
+ expected_me_id=vlan_tagging_entity_id)
+ vlan_tagging_me = self._device.query_mib(VlanTaggingFilterData.class_id,
+ instance_id=int(vlan_tagging_entity_id))
+ if len(vlan_tagging_me) == 0:
+ forward_operation = 0x10 # VID investigation
+ self.log.debug("vlan id isn't reserved")
+ self.log.debug("forward_operation", forward_operation=forward_operation)
+ self.log.debug("set_vlan_id", vlan_id=self._set_vlan_id)
+ # When the PUSH VLAN is RESERVED_VLAN (4095), let ONU be transparent
+ if self._set_vlan_id == RESERVED_TRANSPARENT_VLAN:
+ forward_operation = 0x00 # no investigation, ONU transparent
+
+ # Create bridge ani side vlan filter
+ msg = VlanTaggingFilterDataFrame(
+ int(vlan_tagging_entity_id), # Entity ID
+ vlan_tcis=[self._set_vlan_id], # VLAN IDs
+ forward_operation=forward_operation
+ )
+
+ self.log.debug("created vlan tagging data frame msg")
+ frame = msg.create()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'create-vlan-tagging-filter-data')
+
+ @inlineCallbacks
+ def _reset_evto_and_vlan_tag_filter(self):
+ self.log.info("resetting-evto-and-vlan-tag-filter")
+ # Delete bridge ani side vlan filter
+ eid = self._mac_bridge_port_ani_entity_id + self._uni_port.entity_id + self._tp_id # Entity ID
+ msg = VlanTaggingFilterDataFrame(eid)
+ frame = msg.delete()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'flow-delete-vlan-tagging-filter-data')
+
+ ################################################################################
+ # Create Extended VLAN Tagging Operation config (UNI-side)
+ #
+ # EntityID relates to the VLAN TCIS later used int vlan filter task. This only
+ # sets up the inital MIB entry as it relates to port config, it does not set vlan
+ # that is saved for the vlan filter task
+ #
+ # References:
+ # - PPTP Ethernet or VEIP UNI
+ #
+
+ # Delete uni side evto
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num,
+ )
+ frame = msg.delete()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'delete-extended-vlan-tagging-operation-configuration-data')
+
+ # Re-Create uni side evto
+ # default to PPTP
+ association_type = 2
+ if self._uni_port.type.value == UniType.VEIP.value:
+ association_type = 10
+ elif self._uni_port.type.value == UniType.PPTP.value:
+ association_type = 2
+
+ attributes = dict(
+ association_type=association_type, # Assoc Type, PPTP/VEIP Ethernet UNI
+ associated_me_pointer=self._uni_port.entity_id, # Assoc ME, PPTP/VEIP Entity Id
+
+ # See VOL-1311 - Need to set table during create to avoid exception
+ # trying to read back table during post-create-read-missing-attributes
+ # But, because this is a R/W attribute. Some ONU may not accept the
+ # value during create. It is repeated again in a set below.
+ input_tpid=self._input_tpid, # input TPID
+ output_tpid=self._output_tpid, # output TPID
+ )
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ self._mac_bridge_service_profile_entity_id + self._uni_port.mac_bridge_port_num, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.create()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'create-extended-vlan-tagging-operation-configuration-data')
+
+ @inlineCallbacks
+ def _incremental_update_evto_and_vlan_tag_filter(self):
+ self.log.info("incremental-update-evto-and-vlan-tag-filter")
+ vlan_tagging_entity_id = int(self._mac_bridge_port_ani_entity_id + self._uni_port.entity_id
+ + self._tp_id)
+ extended_vlan_tagging_entity_id = self._mac_bridge_service_profile_entity_id + \
+ self._uni_port.mac_bridge_port_num
+ ################################################################################
+ # VLAN Tagging Filter config
+ #
+ # EntityID will be referenced by:
+ # - Nothing
+ # References:
+ # - MacBridgePortConfigurationData for the ANI/PON side
+ #
+
+ # TODO: check if its in our local mib first before blindly deleting
+ if self._tp_id != 0:
+ yield self._create_vlan_filter_entity(vlan_tagging_entity_id)
+
+ self.log.info('setting-vlan-tagging')
+ attributes = dict(
+ # Specifies the TPIDs in use and that operations in the downstream direction are
+ # inverse to the operations in the upstream direction
+ input_tpid=self._input_tpid, # input TPID
+ output_tpid=self._output_tpid, # output TPID
+ downstream_mode=0, # inverse of upstream
+ )
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-extended-vlan-tagging-operation-configuration-data')
+
+ # Onu-Transparent
+ if self._set_vlan_id == RESERVED_TRANSPARENT_VLAN:
+ # Transparently send any single tagged packet.
+ # As the onu is to be transparent, no need to create VlanTaggingFilterData ME.
+ # Any other specific rules will take priority over this, so not setting any other vlan specific rules
+ entry = VlanTaggingOperation(
+ filter_outer_priority=15, # not an outer tag rule, ignore all other outers
+ filter_outer_vid=4096, # ignore
+ filter_outer_tpid_de=0, # ignore
+ filter_inner_priority=14, # default single tagged rule
+ filter_inner_vid=4096, # do not match on vlan value
+ filter_inner_tpid_de=0, # do not match on tpid
+ filter_ether_type=0, # do not filter on untagged ethertype
+ treatment_tags_to_remove=0, # do not remove any tags
+ treatment_outer_priority=15, # do not add outer tag
+ treatment_outer_vid=0, # ignore
+ treatment_outer_tpid_de=0, # ignore
+ treatment_inner_priority=15, # do not add inner tag
+ treatment_inner_vid=0, # ignore
+ treatment_inner_tpid_de=4 # set TPID 0x8100
+ )
+
+ attributes = dict(received_frame_vlan_tagging_operation_table=entry)
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-evto-table-transparent-vlan')
+ else:
+ # Update uni side extended vlan filter
+ # filter for any set vlan - even its match tag is TRANSPARENT.
+ # For TRANSPARENT match_vlan tag case we modified vlan_pcp and treatment_tags_to_remove values during init.
+ entry = VlanTaggingOperation(
+ filter_outer_priority=15, # This entry is not a double-tag rule
+ filter_outer_vid=4096, # Do not filter on the outer VID value
+ filter_outer_tpid_de=0, # Do not filter on the outer TPID field
+
+ filter_inner_priority=self._vlan_pcp, # Filter on inner vlan
+ filter_inner_vid=self._match_vlan, # Look for match vlan
+ filter_inner_tpid_de=0, # Do not filter on inner TPID field
+ filter_ether_type=0, # Do not filter on EtherType
+
+ treatment_tags_to_remove=self._treatment_tags_to_remove,
+ treatment_outer_priority=15,
+ treatment_outer_vid=0,
+ treatment_outer_tpid_de=0,
+
+ treatment_inner_priority=self._set_vlan_pcp, # Add an inner priority
+ treatment_inner_vid=self._set_vlan_id, # use this value as the VID in the inner VLAN tag
+ treatment_inner_tpid_de=4, # set TPID
+ )
+
+ attributes = dict(received_frame_vlan_tagging_operation_table=entry)
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes # See above
+ )
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-evto-table')
+
+ @inlineCallbacks
+ def _bulk_update_evto_and_vlan_tag_filter(self):
+ self.log.info("bulk-update-evto-and-vlan-tag-filter")
+ # First reset any existing config EVTO and vlan tag filter on the ONU
+ yield self._reset_evto_and_vlan_tag_filter()
+
+ vlan_tagging_entity_id = int(self._mac_bridge_port_ani_entity_id + self._uni_port.entity_id
+ + self._tp_id)
+ extended_vlan_tagging_entity_id = self._mac_bridge_service_profile_entity_id + \
+ self._uni_port.mac_bridge_port_num
+ attributes = dict(
+ # Specifies the TPIDs in use and that operations in the downstream direction are
+ # inverse to the operations in the upstream direction
+ input_tpid=self._input_tpid, # input TPID
+ output_tpid=self._output_tpid, # output TPID
+ downstream_mode=0, # inverse of upstream
+ )
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-extended-vlan-tagging-operation-configuration-data')
+
+ # Onu-Transparent
+ if self._set_vlan_id == RESERVED_TRANSPARENT_VLAN:
+ # Transparently send any single tagged packet.
+ # As the onu is to be transparent, no need to create VlanTaggingFilterData ME.
+ # Any other specific rules will take priority over this, so not setting any other vlan specific rules
+ attributes = dict(
+ received_frame_vlan_tagging_operation_table=
+ VlanTaggingOperation(
+ filter_outer_priority=15,
+ filter_outer_vid=4096,
+ filter_outer_tpid_de=0,
+ filter_inner_priority=14,
+ filter_inner_vid=4096,
+ filter_inner_tpid_de=0,
+ filter_ether_type=0,
+ treatment_tags_to_remove=0,
+ treatment_outer_priority=15,
+ treatment_outer_vid=0,
+ treatment_outer_tpid_de=0,
+ treatment_inner_priority=15,
+ treatment_inner_vid=0,
+ treatment_inner_tpid_de=4
+ )
+ )
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-evto-table-transparent-vlan')
+
+ else:
+ # Re-Create bridge ani side vlan filter
+ forward_operation = 0x10 # VID investigation
+
+ msg = VlanTaggingFilterDataFrame(
+ vlan_tagging_entity_id,
+ vlan_tcis=[self._set_vlan_id], # VLAN IDs
+ forward_operation=forward_operation
+ )
+ frame = msg.create()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'flow-create-vlan-tagging-filter-data')
+ # Update uni side extended vlan filter
+ # filter for untagged
+ attributes = dict(
+ received_frame_vlan_tagging_operation_table=
+ VlanTaggingOperation(
+ filter_outer_priority=15,
+ filter_outer_vid=4096,
+ filter_outer_tpid_de=0,
+ filter_inner_priority=15,
+ filter_inner_vid=4096,
+ filter_inner_tpid_de=0,
+ filter_ether_type=0,
+ treatment_tags_to_remove=0,
+ treatment_outer_priority=15,
+ treatment_outer_vid=0,
+ treatment_outer_tpid_de=0,
+ treatment_inner_priority=0,
+ treatment_inner_vid=self._set_vlan_id,
+ treatment_inner_tpid_de=4
+ )
+ )
+
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes
+ )
+
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-evto-table-untagged')
+
+ # Update uni side extended vlan filter
+ # filter for vlan 0
+ attributes = dict(
+ received_frame_vlan_tagging_operation_table=
+ VlanTaggingOperation(
+ filter_outer_priority=15, # This entry is not a double-tag rule
+ filter_outer_vid=4096, # Do not filter on the outer VID value
+ filter_outer_tpid_de=0, # Do not filter on the outer TPID field
+
+ filter_inner_priority=8, # Filter on inner vlan
+ filter_inner_vid=0x0, # Look for vlan 0
+ filter_inner_tpid_de=0, # Do not filter on inner TPID field
+ filter_ether_type=0, # Do not filter on EtherType
+
+ treatment_tags_to_remove=1,
+ treatment_outer_priority=15,
+ treatment_outer_vid=0,
+ treatment_outer_tpid_de=0,
+
+ treatment_inner_priority=8, # Add an inner tag and insert this value as the priority
+ treatment_inner_vid=self._set_vlan_id, # use this value as the VID in the inner VLAN tag
+ treatment_inner_tpid_de=4, # set TPID
+ )
+ )
+ msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
+ extended_vlan_tagging_entity_id, # Bridge Entity ID
+ attributes=attributes # See above
+ )
+ frame = msg.set()
+ self.log.debug('openomci-msg', omci_msg=msg)
+ self.strobe_watchdog()
+ results = yield self._device.omci_cc.send(frame)
+ self.check_status_and_state(results, 'set-evto-table-zero-tagged')