VOL-1943 Adding multi tcont support to openolt adapter
Change-Id: Ibdc18b9c2f1cac3abbc43ba77512484d4574347b
diff --git a/adaptercore/resourcemanager/resourcemanager.go b/adaptercore/resourcemanager/resourcemanager.go
index a6a7921..b43aa2b 100755
--- a/adaptercore/resourcemanager/resourcemanager.go
+++ b/adaptercore/resourcemanager/resourcemanager.go
@@ -37,10 +37,10 @@
KvstoreTimeout = 5
// BasePathKvStore - service/voltha/openolt/<device_id>
BasePathKvStore = "service/voltha/openolt/{%s}"
- // TpIDPathSuffix - tp_id/<(pon_id, onu_id, uni_id)>
- TpIDPathSuffix = "tp_id/{%d,%d,%d}"
- //MeterIDPathSuffix - meter_id/<(pon_id, onu_id, uni_id)>/<direction>
- MeterIDPathSuffix = "meter_id/{%d,%d,%d}/{%s}"
+ // TpIDPathSuffix - <(pon_id, onu_id, uni_id)>/tp_id
+ TpIDPathSuffix = "{%d,%d,%d}/tp_id"
+ //MeterIDPathSuffix - <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+ MeterIDPathSuffix = "{%d,%d,%d}/{%d}/meter_id/{%s}"
)
// FlowInfo holds the flow information
@@ -96,7 +96,7 @@
return kvbackend
}
-// NewResourceMgr init a New resource maanger instance which in turn instantiates pon resource manager
+// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
// instances according to technology. Initializes the default resource ranges for all
// the resources.
func NewResourceMgr(deviceID string, KVStoreHostPort string, kvStoreType string, deviceType string, devInfo *openolt.DeviceInfo) *OpenOltResourceMgr {
@@ -123,7 +123,7 @@
/*
If a legacy driver returns protobuf without any ranges,s synthesize one from
- the legacy global per-device informaiton. This, in theory, is temporary until
+ the legacy global per-device information. This, in theory, is temporary until
the legacy drivers are upgrade to support pool ranges.
*/
if devInfo.Ranges == nil {
@@ -178,7 +178,7 @@
RsrcMgrsByTech[technology], err = ponrmgr.NewPONResourceManager(technology, deviceType, deviceID,
Backend, ResourceMgr.Host, ResourceMgr.Port)
if err != nil {
- log.Errorf("Failed to create pon resource manager instacnce for technology %s", technology)
+ log.Errorf("Failed to create pon resource manager instance for technology %s", technology)
return nil
}
// resource_mgrs_by_tech[technology] = resource_mgr
@@ -219,7 +219,7 @@
/*
Then apply device specific information. If KV doesn't exist
- or is broader than the device, the device's informationw ill
+ or is broader than the device, the device's information will
dictate the range limits
*/
log.Debugf("Using device info to init pon resource ranges for tech", ponRMgr.Technology)
@@ -517,19 +517,47 @@
return RsrcMgr.ResourceMgrs[intfID].GetCurrentGEMPortIDsForOnu(IntfOnuIDUniID)
}
-// GetCurrentAllocIDForOnu returns alloc ids for given pon interface and onu id
-// Currently of all the alloc_ids available, it returns the first alloc_id in the list for tha given ONU
-func (RsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDForOnu(intfID uint32, onuID uint32, uniID uint32) uint32 {
+// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
+func (RsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(intfID uint32, onuID uint32, uniID uint32) []uint32 {
IntfOnuIDUniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
AllocID := RsrcMgr.ResourceMgrs[intfID].GetCurrentAllocIDForOnu(IntfOnuIDUniID)
if AllocID != nil {
- // Since we support only one alloc_id for the ONU at the moment,
- // return the first alloc_id in the list, if available, for that
- // ONU.
- return AllocID[0]
+ return AllocID
}
- return 0
+ return []uint32{}
+}
+
+// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
+func (RsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(intfID uint32, onuID uint32, uniID uint32, allocID uint32) {
+ allocIDs := RsrcMgr.GetCurrentAllocIDsForOnu(intfID, onuID, uniID)
+ for i := 0; i < len(allocIDs); i++ {
+ if allocIDs[i] == allocID {
+ allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
+ break
+ }
+ }
+ err := RsrcMgr.UpdateAllocIdsForOnu(intfID, onuID, uniID, allocIDs)
+ if err != nil {
+ log.Errorf("Failed to Remove Alloc Id For Onu. IntfID %d onuID %d uniID %d allocID %d",
+ intfID, onuID, uniID, allocID)
+ }
+}
+
+// RemoveGemPortIDForOnu removes the gem port id for given pon interface, onu id, uni id and gem port id
+func (RsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(intfID uint32, onuID uint32, uniID uint32, gemPortID uint32) {
+ gemPortIDs := RsrcMgr.GetCurrentGEMPortIDsForOnu(intfID, onuID, uniID)
+ for i := 0; i < len(gemPortIDs); i++ {
+ if gemPortIDs[i] == gemPortID {
+ gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
+ break
+ }
+ }
+ err := RsrcMgr.UpdateGEMPortIDsForOnu(intfID, onuID, uniID, gemPortIDs)
+ if err != nil {
+ log.Errorf("Failed to Remove Gem Id For Onu. IntfID %d onuID %d uniID %d gemPortId %d",
+ intfID, onuID, uniID, gemPortID)
+ }
}
// UpdateGEMportsPonportToOnuMapOnKVStore updates onu and uni id associated with the gem port to the kv store
@@ -557,6 +585,15 @@
return nil
}
+// RemoveGEMportPonportToOnuMapOnKVStore removes the relationship between the gem port and pon port
+func (RsrcMgr *OpenOltResourceMgr) RemoveGEMportPonportToOnuMapOnKVStore(GemPort uint32, PonPort uint32) {
+ IntfGEMPortPath := fmt.Sprintf("%d,%d", PonPort, GemPort)
+ err := RsrcMgr.KVStore.Delete(IntfGEMPortPath)
+ if err != nil {
+ log.Errorf("Failed to Remove Gem port-Pon port to onu map on kv store. Gem %d PonPort %d", GemPort, PonPort)
+ }
+}
+
// GetGEMPortID gets gem port id for a particular pon port, onu id and uni id and then update the resource map on
// the KV store with the list of gemport_id allocated for the pon_intf_onu_id tuple
func (RsrcMgr *OpenOltResourceMgr) GetGEMPortID(ponPort uint32, onuID uint32,
@@ -651,6 +688,26 @@
}
}
+// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
+// for the given OLT device.
+func (RsrcMgr *OpenOltResourceMgr) FreeAllocID(IntfID uint32, onuID uint32,
+ uniID uint32, allocID uint32) {
+ RsrcMgr.RemoveAllocIDForOnu(IntfID, onuID, uniID, allocID)
+ allocIDs := make([]uint32, 0)
+ allocIDs = append(allocIDs, allocID)
+ RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.ALLOC_ID, allocIDs)
+}
+
+// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
+// for the given OLT device.
+func (RsrcMgr *OpenOltResourceMgr) FreeGemPortID(IntfID uint32, onuID uint32,
+ uniID uint32, gemPortID uint32) {
+ RsrcMgr.RemoveGemPortIDForOnu(IntfID, onuID, uniID, gemPortID)
+ gemPortIDs := make([]uint32, 0)
+ gemPortIDs = append(gemPortIDs, gemPortID)
+ RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.GEMPORT_ID, gemPortIDs)
+}
+
// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id, and the clears the
// resource map and the onuID associated with (pon_intf_id, gemport_id) tuple,
func (RsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(intfID uint32, onuID uint32, uniID uint32) {
@@ -714,10 +771,10 @@
}
// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
-// This path is formed as the following: tp_id/{IntfID, OnuID, UniID}
-func (RsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(IntfID uint32, OnuID uint32, UniID uint32) uint32 {
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(IntfID uint32, OnuID uint32, UniID uint32) []uint32 {
Path := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
- var Data uint32
+ var Data []uint32
Value, err := RsrcMgr.KVStore.Get(Path)
if err == nil {
if Value != nil {
@@ -739,9 +796,9 @@
}
-// RemoveTechProfileIDForOnu deletes the tech-profile-id from the KV-Store for the given onu based on the path
-// This path is formed as the following: tp_id/{IntfID, OnuID, UniID}
-func (RsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(IntfID uint32, OnuID uint32, UniID uint32) error {
+// RemoveTechProfileIDsForOnu deletes all tech profile ids from the KV-Store for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(IntfID uint32, OnuID uint32, UniID uint32) error {
IntfOnuUniID := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
if err := RsrcMgr.KVStore.Delete(IntfOnuUniID); err != nil {
log.Error("Failed to delete techprofile id resource %s in KV store", IntfOnuUniID)
@@ -750,16 +807,47 @@
return nil
}
-//UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
-// This path is formed as the following: tp_id/{IntfID, OnuID, UniID}
+// RemoveTechProfileIDForOnu deletes a specific tech profile id from the KV-Store for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
+func (RsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(IntfID uint32, OnuID uint32, UniID uint32, TpID uint32) error {
+ tpIDList := RsrcMgr.GetTechProfileIDForOnu(IntfID, OnuID, UniID)
+ for i, tpIDInList := range tpIDList {
+ if tpIDInList == TpID {
+ tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
+ }
+ }
+ IntfOnuUniID := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
+ Value, err := json.Marshal(tpIDList)
+ if err != nil {
+ log.Error("failed to Marshal")
+ return err
+ }
+ if err = RsrcMgr.KVStore.Put(IntfOnuUniID, Value); err != nil {
+ log.Errorf("Failed to update resource %s", IntfOnuUniID)
+ return err
+ }
+ return err
+}
+
+// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
+// This path is formed as the following: {IntfID, OnuID, UniID}/tp_id
func (RsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(IntfID uint32, OnuID uint32,
UniID uint32, TpID uint32) error {
var Value []byte
var err error
IntfOnuUniID := fmt.Sprintf(TpIDPathSuffix, IntfID, OnuID, UniID)
+
+ tpIDList := RsrcMgr.GetTechProfileIDForOnu(IntfID, OnuID, UniID)
+ for _, value := range tpIDList {
+ if value == TpID {
+ log.Debugf("TpID %d is already in tpIdList for the path %s", TpID, IntfOnuUniID)
+ return err
+ }
+ }
log.Debugf("updating tp id %d on path %s", TpID, IntfOnuUniID)
- Value, err = json.Marshal(TpID)
+ tpIDList = append(tpIDList, TpID)
+ Value, err = json.Marshal(tpIDList)
if err != nil {
log.Error("failed to Marshal")
return err
@@ -772,13 +860,13 @@
}
// UpdateMeterIDForOnu updates the meter id in the KV-Store for the given onu based on the path
-// This path is formed as the following: tp_id/{IntfID, OnuID, UniID}/direction
+// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
func (RsrcMgr *OpenOltResourceMgr) UpdateMeterIDForOnu(Direction string, IntfID uint32, OnuID uint32,
- UniID uint32, MeterConfig *ofp.OfpMeterConfig) error {
+ UniID uint32, TpID uint32, MeterConfig *ofp.OfpMeterConfig) error {
var Value []byte
var err error
- IntfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, Direction)
+ IntfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, TpID, Direction)
Value, err = json.Marshal(*MeterConfig)
if err != nil {
log.Error("failed to Marshal meter config")
@@ -791,10 +879,11 @@
return err
}
-// GetMeterIDForOnu fetches the meter-id fromthe kv store for the given onu based on the path
-// This path is formed as the following: tp_id/{IntfID, OnuID, UniID}/direction
-func (RsrcMgr *OpenOltResourceMgr) GetMeterIDForOnu(Direction string, IntfID uint32, OnuID uint32, UniID uint32) (*ofp.OfpMeterConfig, error) {
- Path := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, Direction)
+// GetMeterIDForOnu fetches the meter id from the kv store for the given onu based on the path
+// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+func (RsrcMgr *OpenOltResourceMgr) GetMeterIDForOnu(Direction string, IntfID uint32, OnuID uint32,
+ UniID uint32, TpID uint32) (*ofp.OfpMeterConfig, error) {
+ Path := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, TpID, Direction)
var meterConfig ofp.OfpMeterConfig
Value, err := RsrcMgr.KVStore.Get(Path)
if err == nil {
@@ -820,10 +909,11 @@
return &meterConfig, err
}
-// RemoveMeterIDForOnu deletes the meter-id from the kV-Store for the given onu based on the path
-// This path is formed as the following: tp_id/{IntfID, OnuID, UniID}/direction
-func (RsrcMgr *OpenOltResourceMgr) RemoveMeterIDForOnu(Direction string, IntfID uint32, OnuID uint32, UniID uint32) error {
- Path := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, Direction)
+// RemoveMeterIDForOnu deletes the meter id from the kV-Store for the given onu based on the path
+// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
+func (RsrcMgr *OpenOltResourceMgr) RemoveMeterIDForOnu(Direction string, IntfID uint32, OnuID uint32,
+ UniID uint32, TpID uint32) error {
+ Path := fmt.Sprintf(MeterIDPathSuffix, IntfID, OnuID, UniID, TpID, Direction)
if err := RsrcMgr.KVStore.Delete(Path); err != nil {
log.Errorf("Failed to delete meter id %s from kvstore ", Path)
return err
@@ -849,6 +939,6 @@
}
}
}
- log.Errorw("invalid flow-info", log.Fields{"flow_info": FlowInfo})
+ log.Debugw("the flow can be related to a different service", log.Fields{"flow_info": FlowInfo})
return errors.New("invalid flow-info")
}