VOL-1023 - Supporting multiple UNI per ONU
Added support for multiple UNIs per ONU by enabling an opt-in parameter in Resource Manager Profile
attribute key "uni_id_start" and "uni_id_end". This represents the 0 based local-device uni
index range. So, for an ONU to support a single UNI, the default (including omitted) value is 0.
To support multiple UNIs per ONU, set "uni_id_end" to the maximum (0-based) index on the ONU.
Plumbed in support throughout for multiple UNIs. Each UNI receives a dedicated TCONT/GEM from
TechProfile and is applied a dedicated MAC Bridge Instance in the ONU. Each UNI is effectively
treated the same whether on the same or different ONUs.
uni_id is used throughout to be the ONU-relative device port number (0-based)
port_no is the logical port number
Change-Id: I443d2322a2d414a358f1e0c629779c4929ce13c8
diff --git a/common/pon_resource_manager/resource_manager.py b/common/pon_resource_manager/resource_manager.py
index 9e249fb..a88b407 100644
--- a/common/pon_resource_manager/resource_manager.py
+++ b/common/pon_resource_manager/resource_manager.py
@@ -43,6 +43,7 @@
"""Implements APIs to initialize/allocate/release alloc/gemport/onu IDs."""
# Constants to identify resource pool
+ UNI_ID = 'UNI_ID'
ONU_ID = 'ONU_ID'
ALLOC_ID = 'ALLOC_ID'
GEMPORT_ID = 'GEMPORT_ID'
@@ -67,12 +68,16 @@
"gemport_id_end": 8960,
"flow_id_start": 1,
"flow_id_end": 16383,
+ "uni_id_start": 0,
+ "uni_id_end": 0,
"pon_ports": 16
}
'''
# constants used as keys to reference the resource range parameters from
# and external KV store.
+ UNI_ID_START_IDX = "uni_id_start"
+ UNI_ID_END_IDX = "uni_id_end"
ONU_ID_START_IDX = "onu_id_start"
ONU_ID_END_IDX = "onu_id_end"
ONU_ID_SHARED_IDX = "onu_id_shared"
@@ -202,7 +207,16 @@
resource_range_config = result
if resource_range_config is not None:
- self.pon_resource_ranges = json.loads(resource_range_config)
+ # update internal ranges from kv ranges. If there are missing
+ # values in the KV profile, continue to use the defaults
+ for key,value in json.loads(resource_range_config): self.pon_resource_ranges[key] = value
+
+ # initialize optional elements that may not be in the profile
+ if self.pon_resource_ranges[PONResourceManager.UNI_ID_START_IDX] is None:
+ self.pon_resource_ranges[PONResourceManager.UNI_ID_START_IDX] = 0
+ if self.pon_resource_ranges[PONResourceManager.UNI_ID_END_IDX] is None:
+ self.pon_resource_ranges[PONResourceManager.UNI_ID_END_IDX] = 0
+
self._log.debug("Init-resource-ranges-from-kvstore-success",
pon_resource_ranges=self.pon_resource_ranges,
path=path)
@@ -213,7 +227,8 @@
e=e)
return False
- def update_range_(self, start_idx, start, end_idx, end, shared_idx, shared_pool_id, shared_resource_mgr):
+ def update_range_(self, start_idx, start, end_idx, end, shared_idx = None, shared_pool_id = None,
+ shared_resource_mgr = None):
if (start is not None) and \
(start_idx not in self.pon_resource_ranges or self.pon_resource_ranges[start_idx] < start):
self.pon_resource_ranges[start_idx] = start
@@ -243,7 +258,9 @@
flow_id_start_idx=None,
flow_id_end_idx=None,
flow_id_shared_pool_id=None,
- flow_id_shared_resource_mgr=None):
+ flow_id_shared_resource_mgr=None,
+ uni_id_start_idx=None,
+ uni_id_end_idx=None):
self.update_range_(PONResourceManager.ONU_ID_START_IDX, onu_id_start_idx,
PONResourceManager.ONU_ID_END_IDX, onu_id_end_idx,
@@ -265,6 +282,9 @@
PONResourceManager.FLOW_ID_SHARED_IDX, flow_id_shared_pool_id,
flow_id_shared_resource_mgr)
+ self.update_range_(PONResourceManager.UNI_ID_START_IDX, uni_id_start_idx,
+ PONResourceManager.UNI_ID_END_IDX, uni_id_end_idx)
+
def init_default_pon_resource_ranges(self,
onu_id_start_idx=1,
onu_id_end_idx=127,
@@ -278,6 +298,8 @@
flow_id_start_idx=1,
flow_id_end_idx=16383,
flow_id_shared_pool_id=None,
+ uni_id_start_idx=0,
+ uni_id_end_idx=0,
num_of_pon_ports=16,
intf_ids=None):
"""
@@ -303,7 +325,8 @@
self.update_ranges(onu_id_start_idx, onu_id_end_idx, onu_id_shared_pool_id, None,
alloc_id_start_idx, alloc_id_end_idx, alloc_id_shared_pool_id, None,
gemport_id_start_idx, gemport_id_end_idx, gemport_id_shared_pool_id, None,
- flow_id_start_idx, flow_id_end_idx, flow_id_shared_pool_id, None)
+ flow_id_start_idx, flow_id_end_idx, flow_id_shared_pool_id, None,
+ uni_id_start_idx, uni_id_end_idx)
if intf_ids is None:
intf_ids = range(0, num_of_pon_ports)
@@ -468,6 +491,27 @@
return status
+ def assert_resource_limits(self, id, resource_type):
+ """
+ Assert the specified id value is in the limit bounds of he requested resource type.
+
+ :param id: The value to assert is in limits
+ :param resource_type: String to identify type of resource
+ """
+ start_idx = PONResourceManager.ONU_ID_START_IDX if resource_type == PONResourceManager.ONU_ID \
+ else PONResourceManager.ALLOC_ID_START_IDX if resource_type == PONResourceManager.ALLOC_ID \
+ else PONResourceManager.GEMPORT_ID_START_IDX if resource_type == PONResourceManager.GEMPORT_ID \
+ else PONResourceManager.FLOW_ID_START_IDX if resource_type == PONResourceManager.FLOW_ID \
+ else PONResourceManager.UNI_ID_START_IDX if resource_type == PONResourceManager.UNI_ID \
+ else None
+ end_idx = PONResourceManager.ONU_ID_END_IDX if resource_type == PONResourceManager.ONU_ID \
+ else PONResourceManager.ALLOC_ID_END_IDX if resource_type == PONResourceManager.ALLOC_ID \
+ else PONResourceManager.GEMPORT_ID_END_IDX if resource_type == PONResourceManager.GEMPORT_ID \
+ else PONResourceManager.FLOW_ID_END_IDX if resource_type == PONResourceManager.FLOW_ID \
+ else PONResourceManager.UNI_ID_END_IDX if resource_type == PONResourceManager.UNI_ID \
+ else None
+ assert id >= self.pon_resource_ranges[start_idx] and id <= self.pon_resource_ranges[end_idx]
+
def get_resource_id(self, pon_intf_id, resource_type, num_of_id=1):
"""
Create alloc/gemport/onu/flow id for given OLT PON interface.