[VOL-1348] EPON tech profile support
Change-Id: I5dfbc17fe6787f255d22d0b5d640bc636bfb172d
diff --git a/VERSION b/VERSION
index 1a45714..31c3bb8 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.4.9-dev
+2.4.11-dev
diff --git a/go.mod b/go.mod
index d7a5201..dd9b888 100755
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@
github.com/cenkalti/backoff/v3 v3.1.1
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.2
- github.com/opencord/voltha-lib-go/v3 v3.1.19
+ github.com/opencord/voltha-lib-go/v3 v3.1.20
github.com/opencord/voltha-protos/v3 v3.3.9
go.etcd.io/etcd v0.0.0-20190930204107-236ac2a90522
google.golang.org/grpc v1.25.1
diff --git a/go.sum b/go.sum
index 827bbb6..a1dbbd9 100644
--- a/go.sum
+++ b/go.sum
@@ -204,8 +204,8 @@
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/opencord/voltha-lib-go/v3 v3.1.19 h1:WrjN/qi1pQCszoSTlf4jr7hBfKuma7Xeaq/a6V+nsa4=
-github.com/opencord/voltha-lib-go/v3 v3.1.19/go.mod h1:sa508HZ5vlOauh0i+WC0XFX1JZnfHtJqNIms5XBT/Z0=
+github.com/opencord/voltha-lib-go/v3 v3.1.20 h1:TXSz3mivOShau8YkKvXOQrWMWyjqZTnzG/+1U6+2r5Y=
+github.com/opencord/voltha-lib-go/v3 v3.1.20/go.mod h1:sa508HZ5vlOauh0i+WC0XFX1JZnfHtJqNIms5XBT/Z0=
github.com/opencord/voltha-protos/v3 v3.3.9 h1:BnfDN9oaRBgyAiH9ZN7LpBpEJYxjX/ZS7R4OT2hDrtY=
github.com/opencord/voltha-protos/v3 v3.3.9/go.mod h1:nl1ETp5Iw3avxOaKD8BJlYY5wYI4KeV95aT1pL63nto=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
index 4a8df12..d14194e 100644
--- a/internal/pkg/core/openolt_flowmgr.go
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -199,7 +199,7 @@
uniID uint32
tpID uint32
uniPort uint32
- tpInst *tp.TechProfile
+ tpInst interface{}
meterID uint32
flowMetadata *voltha.FlowMetadata
}
@@ -299,7 +299,7 @@
UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) {
var allocID uint32
var gemPorts []uint32
- var TpInst *tp.TechProfile
+ var TpInst interface{}
logger.Infow("dividing-flow", log.Fields{
"device-id": f.deviceHandler.device.Id,
@@ -427,9 +427,9 @@
"device-id": f.deviceHandler.device.Id})
if sq.direction == tp_pb.Direction_UPSTREAM {
- SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst)
+ SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst.(*tp.TechProfile))
} else if sq.direction == tp_pb.Direction_DOWNSTREAM {
- SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst)
+ SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst.(*tp.TechProfile))
}
if err != nil {
@@ -481,7 +481,7 @@
pbs := cbs + ebs
TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
- TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst, SchedCfg, TrafficShaping)}
+ TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
TrafficSched[0].TechProfileId = sq.tpID
if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficShaping, TrafficSched); err != nil {
@@ -509,7 +509,7 @@
func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficShaping *tp_pb.TrafficShapingInfo, TrafficSched []*tp_pb.TrafficScheduler) error {
- trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst, sq.direction)
+ trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst.(*tp.TechProfile), sq.direction)
if err != nil {
return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
@@ -553,7 +553,7 @@
"device-id": f.deviceHandler.device.Id})
if sq.direction == tp_pb.Direction_DOWNSTREAM {
- multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(sq.tpInst)
+ multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(sq.tpInst.(*tp.TechProfile))
if len(multicastTrafficQueues) > 0 {
if _, present := f.interfaceToMcastQueueMap[sq.intfID]; !present {
//assumed that there is only one queue per PON for the multicast service
@@ -592,10 +592,10 @@
"uni-port": sq.uniPort,
"device-id": f.deviceHandler.device.Id})
if sq.direction == tp_pb.Direction_UPSTREAM {
- SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst)
+ SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst.(*tp.TechProfile))
Direction = "upstream"
} else if sq.direction == tp_pb.Direction_DOWNSTREAM {
- SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst)
+ SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst.(*tp.TechProfile))
Direction = "downstream"
}
@@ -633,10 +633,10 @@
TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
- TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst, SchedCfg, TrafficShaping)}
+ TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
TrafficSched[0].TechProfileId = sq.tpID
- TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst, sq.direction)
+ TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst.(*tp.TechProfile), sq.direction)
if err != nil {
return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
log.Fields{
@@ -689,7 +689,7 @@
}
// This function allocates tconts and GEM ports for an ONU
-func (f *OpenOltFlowMgr) createTcontGemports(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uni string, uniPort uint32, TpID uint32, UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) (uint32, []uint32, *tp.TechProfile) {
+func (f *OpenOltFlowMgr) createTcontGemports(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uni string, uniPort uint32, TpID uint32, UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) (uint32, []uint32, interface{}) {
var allocIDs []uint32
var allgemPortIDs []uint32
var gemPortIDs []uint32
@@ -733,53 +733,85 @@
"device-id": f.deviceHandler.device.Id})
tpInstanceExists = true
}
- if UsMeterID != 0 {
- sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
- uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
- if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
- logger.Errorw("CreateSchedulerQueues-failed-upstream",
- log.Fields{
- "error": err,
- "meter-id": UsMeterID,
- "device-id": f.deviceHandler.device.Id})
- return 0, nil, nil
- }
- }
- if DsMeterID != 0 {
- sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
- uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
- if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
- logger.Errorw("CreateSchedulerQueues-failed-downstream",
- log.Fields{
- "error": err,
- "meter-id": DsMeterID,
- "device-id": f.deviceHandler.device.Id})
- return 0, nil, nil
- }
- }
- allocID := techProfileInstance.UsScheduler.AllocID
- for _, gem := range techProfileInstance.UpstreamGemPortAttributeList {
- gemPortIDs = append(gemPortIDs, gem.GemportID)
- }
+ switch tpInst := techProfileInstance.(type) {
+ case *tp.TechProfile:
+ if UsMeterID != 0 {
+ sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
+ uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
+ if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
+ logger.Errorw("CreateSchedulerQueues-failed-upstream",
+ log.Fields{
+ "error": err,
+ "meter-id": UsMeterID,
+ "device-id": f.deviceHandler.device.Id})
+ return 0, nil, nil
+ }
+ }
+ if DsMeterID != 0 {
+ sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
+ uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
+ if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
+ logger.Errorw("CreateSchedulerQueues-failed-downstream",
+ log.Fields{
+ "error": err,
+ "meter-id": DsMeterID,
+ "device-id": f.deviceHandler.device.Id})
+ return 0, nil, nil
+ }
+ }
+ allocID := tpInst.UsScheduler.AllocID
+ for _, gem := range tpInst.UpstreamGemPortAttributeList {
+ gemPortIDs = append(gemPortIDs, gem.GemportID)
+ }
+ allocIDs = appendUnique(allocIDs, allocID)
- if tpInstanceExists {
+ if tpInstanceExists {
+ return allocID, gemPortIDs, techProfileInstance
+ }
+
+ for _, gemPortID := range gemPortIDs {
+ allgemPortIDs = appendUnique(allgemPortIDs, gemPortID)
+ }
+ logger.Infow("allocated-tcont-and-gem-ports",
+ log.Fields{
+ "alloc-ids": allocIDs,
+ "gemports": allgemPortIDs,
+ "device-id": f.deviceHandler.device.Id})
+ // Send Tconts and GEM ports to KV store
+ f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
return allocID, gemPortIDs, techProfileInstance
+ case *tp.EponProfile:
+ // CreateSchedulerQueues for EPON needs to be implemented here
+ // when voltha-protos for EPON is completed.
+ allocID := tpInst.AllocID
+ for _, gem := range tpInst.UpstreamQueueAttributeList {
+ gemPortIDs = append(gemPortIDs, gem.GemportID)
+ }
+ allocIDs = appendUnique(allocIDs, allocID)
+
+ if tpInstanceExists {
+ return allocID, gemPortIDs, techProfileInstance
+ }
+
+ for _, gemPortID := range gemPortIDs {
+ allgemPortIDs = appendUnique(allgemPortIDs, gemPortID)
+ }
+ logger.Infow("allocated-tcont-and-gem-ports",
+ log.Fields{
+ "alloc-ids": allocIDs,
+ "gemports": allgemPortIDs,
+ "device-id": f.deviceHandler.device.Id})
+ // Send Tconts and GEM ports to KV store
+ f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
+ return allocID, gemPortIDs, techProfileInstance
+ default:
+ logger.Errorw("unknown-tech",
+ log.Fields{
+ "tpInst": tpInst})
+ return 0, nil, nil
}
- allocIDs = appendUnique(allocIDs, allocID)
- for _, gemPortID := range gemPortIDs {
- allgemPortIDs = appendUnique(allgemPortIDs, gemPortID)
- }
-
- logger.Infow("allocated-tcont-and-gem-ports",
- log.Fields{
- "alloc-ids": allocIDs,
- "gemports": allgemPortIDs,
- "device-id": f.deviceHandler.device.Id})
- // Send Tconts and GEM ports to KV store
- f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
- return allocID, gemPortIDs, techProfileInstance
}
func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
@@ -2006,6 +2038,7 @@
}
//clearResources clears pon resources in kv store and the device
+// nolint: gocyclo
func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, Intf uint32, onuID int32, uniID int32,
gemPortID int32, flowID uint32, flowDirection string,
portNum uint32, updatedFlows []rsrcMgr.FlowInfo) error {
@@ -2128,24 +2161,44 @@
"device-id": f.deviceHandler.device.Id,
"gemport-id": gemPortID})
}
-
- ok, _ := f.isTechProfileUsedByAnotherGem(ctx, Intf, uint32(onuID), uint32(uniID), tpID, techprofileInst, uint32(gemPortID))
- if !ok {
+ switch techprofileInst := techprofileInst.(type) {
+ case *tp.TechProfile:
+ ok, _ := f.isTechProfileUsedByAnotherGem(ctx, Intf, uint32(onuID), uint32(uniID), tpID, techprofileInst, uint32(gemPortID))
+ if !ok {
+ f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID)
+ f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID)
+ f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst})
+ f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst})
+ f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID)
+ // Delete the TCONT on the ONU.
+ if err := f.sendDeleteTcontToChild(Intf, uint32(onuID), uint32(uniID), uint32(techprofileInst.UsScheduler.AllocID), tpPath); err != nil {
+ logger.Errorw("error-processing-delete-tcont-towards-onu",
+ log.Fields{
+ "intf": Intf,
+ "onu-id": onuID,
+ "uni-id": uniID,
+ "device-id": f.deviceHandler.device.Id,
+ "alloc-id": techprofileInst.UsScheduler.AllocID})
+ }
+ }
+ case *tp.EponProfile:
f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID)
- f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst})
- f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst})
f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID)
- f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID)
+ f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.AllocID)
// Delete the TCONT on the ONU.
- if err := f.sendDeleteTcontToChild(Intf, uint32(onuID), uint32(uniID), uint32(techprofileInst.UsScheduler.AllocID), tpPath); err != nil {
+ if err := f.sendDeleteTcontToChild(Intf, uint32(onuID), uint32(uniID), uint32(techprofileInst.AllocID), tpPath); err != nil {
logger.Errorw("error-processing-delete-tcont-towards-onu",
log.Fields{
"intf": Intf,
"onu-id": onuID,
"uni-id": uniID,
"device-id": f.deviceHandler.device.Id,
- "alloc-id": techprofileInst.UsScheduler.AllocID})
+ "alloc-id": techprofileInst.AllocID})
}
+ default:
+ logger.Errorw("error-unknown-tech",
+ log.Fields{
+ "techprofileInst": techprofileInst})
}
}
}
@@ -3053,6 +3106,7 @@
"gem": gemPortID}, err)
}
+// nolint: gocyclo
func installFlowOnAllGemports(ctx context.Context,
f1 func(ctx context.Context, intfId uint32, onuId uint32, uniId uint32,
portNo uint32, classifier map[string]interface{}, action map[string]interface{},
@@ -3065,7 +3119,7 @@
classifier map[string]interface{}, action map[string]interface{},
logicalFlow *ofp.OfpFlowStats,
gemPorts []uint32,
- TpInst *tp.TechProfile,
+ TpInst interface{},
FlowType string,
direction string,
tpID uint32,
@@ -3085,35 +3139,90 @@
// the LSB position which marks the PCP bit consumed by the given gem port.
// This PCP bit now becomes a classifier in the flow.
- attributes := TpInst.DownstreamGemPortAttributeList
- if direction == Upstream {
- attributes = TpInst.UpstreamGemPortAttributeList
- }
-
- for _, gemPortAttribute := range attributes {
- if direction == Downstream && strings.ToUpper(gemPortAttribute.IsMulticast) == "TRUE" {
- continue
+ switch TpInst := TpInst.(type) {
+ case *tp.TechProfile:
+ attributes := TpInst.DownstreamGemPortAttributeList
+ if direction == Upstream {
+ attributes = TpInst.UpstreamGemPortAttributeList
}
- gemPortID := gemPortAttribute.GemportID
- if allPbitsMarked(gemPortAttribute.PbitMap) {
- classifier[VlanPcp] = uint32(VlanPCPMask)
- if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
- f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
- } else if FlowType == EapolFlow {
- f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
+
+ for _, gemPortAttribute := range attributes {
+ if direction == Downstream && strings.ToUpper(gemPortAttribute.IsMulticast) == "TRUE" {
+ continue
}
- } else {
- for pos, pbitSet := range strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix) {
- if pbitSet == BinaryBit1 {
- classifier[VlanPcp] = uint32(len(strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix))) - 1 - uint32(pos)
+ gemPortID := gemPortAttribute.GemportID
+ if allPbitsMarked(gemPortAttribute.PbitMap) {
+ classifier[VlanPcp] = uint32(VlanPCPMask)
+ if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
+ f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
+ }
+ } else {
+ for pos, pbitSet := range strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix) {
+ if pbitSet == BinaryBit1 {
+ classifier[VlanPcp] = uint32(len(strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix))) - 1 - uint32(pos)
+ if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
+ f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
+ }
+ }
+ }
+ }
+ }
+ case *tp.EponProfile:
+ if direction == Upstream {
+ attributes := TpInst.UpstreamQueueAttributeList
+ for _, queueAttribute := range attributes {
+ gemPortID := queueAttribute.GemportID
+ if allPbitsMarked(queueAttribute.PbitMap) {
+ classifier[VlanPcp] = uint32(VlanPCPMask)
if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
} else if FlowType == EapolFlow {
f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
}
+ } else {
+ for pos, pbitSet := range strings.TrimPrefix(queueAttribute.PbitMap, BinaryStringPrefix) {
+ if pbitSet == BinaryBit1 {
+ classifier[VlanPcp] = uint32(len(strings.TrimPrefix(queueAttribute.PbitMap, BinaryStringPrefix))) - 1 - uint32(pos)
+ if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
+ f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
+ }
+ }
+ }
+ }
+ }
+ } else {
+ attributes := TpInst.DownstreamQueueAttributeList
+ for _, queueAttribute := range attributes {
+ gemPortID := queueAttribute.GemportID
+ if allPbitsMarked(queueAttribute.PbitMap) {
+ classifier[VlanPcp] = uint32(VlanPCPMask)
+ if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
+ f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
+ }
+ } else {
+ for pos, pbitSet := range strings.TrimPrefix(queueAttribute.PbitMap, BinaryStringPrefix) {
+ if pbitSet == BinaryBit1 {
+ classifier[VlanPcp] = uint32(len(strings.TrimPrefix(queueAttribute.PbitMap, BinaryStringPrefix))) - 1 - uint32(pos)
+ if FlowType == DhcpFlow || FlowType == IgmpFlow || FlowType == HsiaFlow {
+ f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, tpID)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0], tpID)
+ }
+ }
+ }
}
}
}
+ default:
+ logger.Errorw("unknown-tech", log.Fields{"tpInst": TpInst})
}
}
@@ -3328,14 +3437,14 @@
}
func (f *OpenOltFlowMgr) checkAndAddFlow(ctx context.Context, args map[string]uint32, classifierInfo map[string]interface{},
- actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpInst *tp.TechProfile, gemPorts []uint32,
+ actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpInst interface{}, gemPorts []uint32,
tpID uint32, uni string) {
var gemPort uint32
intfID := args[IntfID]
onuID := args[OnuID]
uniID := args[UniID]
portNo := args[PortNo]
- allocID := TpInst.UsScheduler.AllocID
+ allocID := args[AllocID]
if ipProto, ok := classifierInfo[IPProto]; ok {
if ipProto.(uint32) == IPProtoDhcp {
logger.Infow("adding-dhcp-flow", log.Fields{
@@ -3474,7 +3583,7 @@
// still be used on other uni ports.
// So, we need to check and make sure that no other gem port is referring to the given TP ID
// on any other uni port.
- tpInstances := f.techprofile[ponIntf].FindAllTpInstances(ctx, tpID, ponIntf, onuID)
+ tpInstances := f.techprofile[ponIntf].FindAllTpInstances(ctx, tpID, ponIntf, onuID).([]tp.TechProfile)
logger.Debugw("got-single-instance-tp-instances", log.Fields{"tp-instances": tpInstances})
for i := 0; i < len(tpInstances); i++ {
tpI := tpInstances[i]
diff --git a/internal/pkg/core/openolt_flowmgr_test.go b/internal/pkg/core/openolt_flowmgr_test.go
index 1e3dca3..4a74e9a 100644
--- a/internal/pkg/core/openolt_flowmgr_test.go
+++ b/internal/pkg/core/openolt_flowmgr_test.go
@@ -216,6 +216,54 @@
}
+func TestOpenOltFlowMgr_createTcontGemports(t *testing.T) {
+ // flowMgr := newMockFlowmgr()
+ bands := make([]*ofp.OfpMeterBandHeader, 2)
+ bands[0] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 1000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
+ bands[1] = &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DROP, Rate: 2000, BurstSize: 5000, Data: &ofp.OfpMeterBandHeader_Drop{}}
+ ofpMeterConfig := &ofp.OfpMeterConfig{Flags: 1, MeterId: 1, Bands: bands}
+ flowmetadata := &voltha.FlowMetadata{
+ Meters: []*ofp.OfpMeterConfig{ofpMeterConfig},
+ }
+ type args struct {
+ intfID uint32
+ onuID uint32
+ uniID uint32
+ uni string
+ uniPort uint32
+ TpID uint32
+ UsMeterID uint32
+ DsMeterID uint32
+ flowMetadata *voltha.FlowMetadata
+ }
+ tests := []struct {
+ name string
+ args args
+ }{
+ {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 64, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
+ {"createTcontGemports-1", args{intfID: 0, onuID: 1, uniID: 1, uni: "16", uniPort: 1, TpID: 65, UsMeterID: 1, DsMeterID: 1, flowMetadata: flowmetadata}},
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ _, _, tpInst := flowMgr.createTcontGemports(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID, tt.args.uni, tt.args.uniPort, tt.args.TpID, tt.args.UsMeterID, tt.args.DsMeterID, tt.args.flowMetadata)
+ switch tpInst := tpInst.(type) {
+ case *tp.TechProfile:
+ if tt.args.TpID != 64 {
+ t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
+ }
+ case *tp.EponProfile:
+ if tt.args.TpID != 65 {
+ t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
+ }
+ default:
+ t.Errorf("OpenOltFlowMgr.createTcontGemports() error = different tech, tech %v", tpInst)
+ }
+ })
+ }
+}
+
func TestOpenOltFlowMgr_RemoveFlow(t *testing.T) {
// flowMgr := newMockFlowmgr()
logger.Debug("Info Warning Error: Starting RemoveFlow() test")
diff --git a/pkg/mocks/mockTechprofile.go b/pkg/mocks/mockTechprofile.go
index 8937459..d47864c 100644
--- a/pkg/mocks/mockTechprofile.go
+++ b/pkg/mocks/mockTechprofile.go
@@ -19,6 +19,7 @@
import (
"context"
+
"github.com/opencord/voltha-lib-go/v3/pkg/db"
tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
tp_pb "github.com/opencord/voltha-protos/v3/go/tech_profile"
@@ -41,24 +42,38 @@
}
// GetTPInstanceFromKVStore to mock techprofile GetTPInstanceFromKVStore method
-func (m MockTechProfile) GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (*tp.TechProfile, error) {
+func (m MockTechProfile) GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (interface{}, error) {
logger.Debug("Warning Warning Warning: GetTPInstanceFromKVStore")
return nil, nil
}
// CreateTechProfInstance to mock techprofile CreateTechProfInstance method
-func (m MockTechProfile) CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfID uint32) (*tp.TechProfile, error) {
+func (m MockTechProfile) CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfID uint32) (interface{}, error) {
- return &tp.TechProfile{
- Name: "mock-tech-profile",
- SubscriberIdentifier: "257",
- ProfileType: "mock",
- Version: 0,
- NumGemPorts: 2,
- UpstreamGemPortAttributeList: nil,
- DownstreamGemPortAttributeList: nil,
- }, nil
+ if techProfiletblID == 64 {
+ return &tp.TechProfile{
+ Name: "mock-tech-profile",
+ SubscriberIdentifier: "257",
+ ProfileType: "mock",
+ Version: 0,
+ NumGemPorts: 2,
+ UpstreamGemPortAttributeList: nil,
+ DownstreamGemPortAttributeList: nil,
+ }, nil
+ } else if techProfiletblID == 65 {
+ return &tp.EponProfile{
+ Name: "mock-epon-profile",
+ SubscriberIdentifier: "257",
+ ProfileType: "mock",
+ Version: 0,
+ NumGemPorts: 2,
+ UpstreamQueueAttributeList: nil,
+ DownstreamQueueAttributeList: nil,
+ }, nil
+ } else {
+ return nil, nil
+ }
}
@@ -102,11 +117,11 @@
}
// GetGemportIDForPbit to mock techprofile GetGemportIDForPbit method
-func (m MockTechProfile) GetGemportIDForPbit(tp *tp.TechProfile, Dir tp_pb.Direction, pbit uint32) uint32 {
+func (m MockTechProfile) GetGemportIDForPbit(tp interface{}, Dir tp_pb.Direction, pbit uint32) uint32 {
return 0
}
// FindAllTpInstances to mock techprofile FindAllTpInstances method
-func (m MockTechProfile) FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) []tp.TechProfile {
+func (m MockTechProfile) FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) interface{} {
return []tp.TechProfile{}
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/config.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/config.go
index fe3e4a2..fa2a6de 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/config.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/config.go
@@ -72,6 +72,23 @@
SCHEDULING_POLICY = "scheduling_policy"
MAX_Q_SIZE = "max_q_size"
AES_ENCRYPTION = "aes_encryption"
+ // String Keys for EPON
+ EPON_ATTRIBUTE = "epon_attribute"
+ PACKAGE_TYPE = "package_type"
+ TRAFFIC_TYPE = "traffic type"
+ UNSOLICITED_GRANT_SIZE = "unsolicited_grant_size"
+ NOMINAL_INTERVAL = "nominal_interval"
+ TOLERATED_POLL_JITTER = "tolerated_poll_jitter"
+ REQUEST_TRANSMISSION_POLICY = "request_transmission_policy"
+ NUM_Q_SETS = "num_q_sets"
+ Q_THRESHOLDS = "q_thresholds"
+ Q_THRESHOLD1 = "q_threshold1"
+ Q_THRESHOLD2 = "q_threshold2"
+ Q_THRESHOLD3 = "q_threshold3"
+ Q_THRESHOLD4 = "q_threshold4"
+ Q_THRESHOLD5 = "q_threshold5"
+ Q_THRESHOLD6 = "q_threshold6"
+ Q_THRESHOLD7 = "q_threshold7"
)
// TechprofileFlags represents the set of configurations used
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile.go
index 60e4dae..492c9e8 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile.go
@@ -105,19 +105,19 @@
var uniPortNameFormat = regexp.MustCompile(`^olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}$`)
/*
-type InferredAdditionBWIndication int32
+ type InferredAdditionBWIndication int32
-const (
- InferredAdditionBWIndication_InferredAdditionBWIndication_None InferredAdditionBWIndication = 0
- InferredAdditionBWIndication_InferredAdditionBWIndication_Assured InferredAdditionBWIndication = 1
- InferredAdditionBWIndication_InferredAdditionBWIndication_BestEffort InferredAdditionBWIndication = 2
-)
+ const (
+ InferredAdditionBWIndication_InferredAdditionBWIndication_None InferredAdditionBWIndication = 0
+ InferredAdditionBWIndication_InferredAdditionBWIndication_Assured InferredAdditionBWIndication = 1
+ InferredAdditionBWIndication_InferredAdditionBWIndication_BestEffort InferredAdditionBWIndication = 2
+ )
-var InferredAdditionBWIndication_name = map[int32]string{
- 0: "InferredAdditionBWIndication_None",
- 1: "InferredAdditionBWIndication_Assured",
- 2: "InferredAdditionBWIndication_BestEffort",
-}
+ var InferredAdditionBWIndication_name = map[int32]string{
+ 0: "InferredAdditionBWIndication_None",
+ 1: "InferredAdditionBWIndication_Assured",
+ 2: "InferredAdditionBWIndication_BestEffort",
+ }
*/
// instance control defaults
const (
@@ -245,6 +245,141 @@
DownstreamGemPortAttributeList []iGemPortAttribute `json:"downstream_gem_port_attribute_list"`
}
+// QThresholds struct for EPON
+type QThresholds struct {
+ QThreshold1 uint32 `json:"q_threshold1"`
+ QThreshold2 uint32 `json:"q_threshold2"`
+ QThreshold3 uint32 `json:"q_threshold3"`
+ QThreshold4 uint32 `json:"q_threshold4"`
+ QThreshold5 uint32 `json:"q_threshold5"`
+ QThreshold6 uint32 `json:"q_threshold6"`
+ QThreshold7 uint32 `json:"q_threshold7"`
+}
+
+// UpstreamQueueAttribute struct for EPON
+type UpstreamQueueAttribute struct {
+ MaxQueueSize string `json:"max_q_size"`
+ PbitMap string `json:"pbit_map"`
+ AesEncryption string `json:"aes_encryption"`
+ TrafficType string `json:"traffic_type"`
+ UnsolicitedGrantSize uint32 `json:"unsolicited_grant_size"`
+ NominalInterval uint32 `json:"nominal_interval"`
+ ToleratedPollJitter uint32 `json:"tolerated_poll_jitter"`
+ RequestTransmissionPolicy uint32 `json:"request_transmission_policy"`
+ NumQueueSet uint32 `json:"num_q_sets"`
+ QThresholds QThresholds `json:"q_thresholds"`
+ SchedulingPolicy string `json:"scheduling_policy"`
+ PriorityQueue uint32 `json:"priority_q"`
+ Weight uint32 `json:"weight"`
+ DiscardPolicy string `json:"discard_policy"`
+ DiscardConfig DiscardConfig `json:"discard_config"`
+}
+
+// Default EPON constants
+const (
+ defaultPakageType = "B"
+)
+const (
+ defaultTrafficType = "BE"
+ defaultUnsolicitedGrantSize = 0
+ defaultNominalInterval = 0
+ defaultToleratedPollJitter = 0
+ defaultRequestTransmissionPolicy = 0
+ defaultNumQueueSet = 2
+)
+const (
+ defaultQThreshold1 = 5500
+ defaultQThreshold2 = 0
+ defaultQThreshold3 = 0
+ defaultQThreshold4 = 0
+ defaultQThreshold5 = 0
+ defaultQThreshold6 = 0
+ defaultQThreshold7 = 0
+)
+
+// DownstreamQueueAttribute struct for EPON
+type DownstreamQueueAttribute struct {
+ MaxQueueSize string `json:"max_q_size"`
+ PbitMap string `json:"pbit_map"`
+ AesEncryption string `json:"aes_encryption"`
+ SchedulingPolicy string `json:"scheduling_policy"`
+ PriorityQueue uint32 `json:"priority_q"`
+ Weight uint32 `json:"weight"`
+ DiscardPolicy string `json:"discard_policy"`
+ DiscardConfig DiscardConfig `json:"discard_config"`
+}
+
+// iUpstreamQueueAttribute struct for EPON
+type iUpstreamQueueAttribute struct {
+ GemportID uint32 `json:"q_id"`
+ MaxQueueSize string `json:"max_q_size"`
+ PbitMap string `json:"pbit_map"`
+ AesEncryption string `json:"aes_encryption"`
+ TrafficType string `json:"traffic_type"`
+ UnsolicitedGrantSize uint32 `json:"unsolicited_grant_size"`
+ NominalInterval uint32 `json:"nominal_interval"`
+ ToleratedPollJitter uint32 `json:"tolerated_poll_jitter"`
+ RequestTransmissionPolicy uint32 `json:"request_transmission_policy"`
+ NumQueueSet uint32 `json:"num_q_sets"`
+ QThresholds QThresholds `json:"q_thresholds"`
+ SchedulingPolicy string `json:"scheduling_policy"`
+ PriorityQueue uint32 `json:"priority_q"`
+ Weight uint32 `json:"weight"`
+ DiscardPolicy string `json:"discard_policy"`
+ DiscardConfig DiscardConfig `json:"discard_config"`
+}
+
+// iDownstreamQueueAttribute struct for EPON
+type iDownstreamQueueAttribute struct {
+ GemportID uint32 `json:"q_id"`
+ MaxQueueSize string `json:"max_q_size"`
+ PbitMap string `json:"pbit_map"`
+ AesEncryption string `json:"aes_encryption"`
+ SchedulingPolicy string `json:"scheduling_policy"`
+ PriorityQueue uint32 `json:"priority_q"`
+ Weight uint32 `json:"weight"`
+ DiscardPolicy string `json:"discard_policy"`
+ DiscardConfig DiscardConfig `json:"discard_config"`
+}
+
+// EponAttribute struct for EPON
+type EponAttribute struct {
+ PackageType string `json:"pakage_type"`
+}
+
+// DefaultTechProfile struct for EPON
+type DefaultEponProfile struct {
+ Name string `json:"name"`
+ ProfileType string `json:"profile_type"`
+ Version int `json:"version"`
+ NumGemPorts uint32 `json:"num_gem_ports"`
+ InstanceCtrl InstanceControl `json:"instance_control"`
+ EponAttribute EponAttribute `json:"epon_attribute"`
+ UpstreamQueueAttributeList []UpstreamQueueAttribute `json:"upstream_queue_attribute_list"`
+ DownstreamQueueAttributeList []DownstreamQueueAttribute `json:"downstream_queue_attribute_list"`
+}
+
+// TechProfile struct for EPON
+type EponProfile struct {
+ Name string `json:"name"`
+ SubscriberIdentifier string `json:"subscriber_identifier"`
+ ProfileType string `json:"profile_type"`
+ Version int `json:"version"`
+ NumGemPorts uint32 `json:"num_gem_ports"`
+ InstanceCtrl InstanceControl `json:"instance_control"`
+ EponAttribute EponAttribute `json:"epon_attribute"`
+ AllocID uint32 `json:"llid"`
+ UpstreamQueueAttributeList []iUpstreamQueueAttribute `json:"upstream_queue_attribute_list"`
+ DownstreamQueueAttributeList []iDownstreamQueueAttribute `json:"downstream_queue_attribute_list"`
+}
+
+const (
+ xgspon = "xgspon"
+ xgsponBbsim = "XGS-PON"
+ gpon = "gpon"
+ epon = "EPON"
+)
+
func (t *TechProfileMgr) SetKVClient() *db.Backend {
kvClient, err := newKVClient(t.config.KVStoreType, t.config.KVStoreAddress, t.config.KVStoreTimeout)
if err != nil {
@@ -264,9 +399,9 @@
PathPrefix: t.config.TPKVPathPrefix}
/* TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
- issue between kv store and backend , core is not calling NewBackend directly
- kv := model.NewBackend(t.config.KVStoreType, t.config.KVStoreHost, t.config.KVStorePort,
- t.config.KVStoreTimeout, kvStoreTechProfilePathPrefix)
+ issue between kv store and backend , core is not calling NewBackend directly
+ kv := model.NewBackend(t.config.KVStoreType, t.config.KVStoreHost, t.config.KVStorePort,
+ t.config.KVStoreTimeout, kvStoreTechProfilePathPrefix)
*/
}
@@ -304,22 +439,34 @@
return fmt.Sprintf(t.config.TPInstanceKVPath, t.resourceMgr.GetTechnology(), techProfiletblID, uniPortName)
}
-func (t *TechProfileMgr) GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (*TechProfile, error) {
- var KvTpIns TechProfile
- var resPtr *TechProfile = &KvTpIns
+func (t *TechProfileMgr) GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (interface{}, error) {
var err error
var kvResult *kvstore.KVPair
-
- logger.Infow("get-tp-instance-form-kv-store", log.Fields{"path": path, "tpid": techProfiletblID})
+ var KvTpIns TechProfile
+ var KvEponIns EponProfile
+ var resPtr interface{}
+ // For example:
+ // tpInstPath like "XGS-PON/64/uni_port_name"
+ // is broken into ["XGS-PON" "64" ...]
+ pathSlice := regexp.MustCompile(`/`).Split(path, -1)
+ switch pathSlice[0] {
+ case xgspon, xgsponBbsim, gpon:
+ resPtr = &KvTpIns
+ case epon:
+ resPtr = &KvEponIns
+ default:
+ log.Errorw("unknown-tech", log.Fields{"tech": pathSlice[0]})
+ return nil, fmt.Errorf("unknown-tech-%s", pathSlice[0])
+ }
kvResult, _ = t.config.KVBackend.Get(ctx, path)
if kvResult == nil {
- logger.Infow("tp-instance-not-found-on-kv", log.Fields{"key": path})
+ log.Infow("tp-instance-not-found-on-kv", log.Fields{"key": path})
return nil, nil
} else {
if value, err := kvstore.ToByte(kvResult.Value); err == nil {
if err = json.Unmarshal(value, resPtr); err != nil {
- logger.Errorw("error-unmarshal-kv-result", log.Fields{"key": path, "value": value})
+ log.Errorw("error-unmarshal-kv-result", log.Fields{"key": path, "value": value})
return nil, errors.New("error-unmarshal-kv-result")
} else {
return resPtr, nil
@@ -342,6 +489,21 @@
}
return err
}
+
+func (t *TechProfileMgr) addEponProfInstanceToKVStore(ctx context.Context, techProfiletblID uint32, uniPortName string, tpInstance *EponProfile) error {
+ path := t.GetTechProfileInstanceKVPath(techProfiletblID, uniPortName)
+ logger.Debugw("Adding techprof instance to kvstore", log.Fields{"key": path, "tpinstance": tpInstance})
+ tpInstanceJson, err := json.Marshal(*tpInstance)
+ if err == nil {
+ // Backend will convert JSON byte array into string format
+ logger.Debugw("Storing tech profile instance to KV Store", log.Fields{"key": path, "val": tpInstanceJson})
+ err = t.config.KVBackend.Put(ctx, path, tpInstanceJson)
+ } else {
+ logger.Errorw("Error in marshaling into Json format", log.Fields{"key": path, "tpinstance": tpInstance})
+ }
+ return err
+}
+
func (t *TechProfileMgr) getTPFromKVStore(ctx context.Context, techProfiletblID uint32) *DefaultTechProfile {
var kvtechprofile DefaultTechProfile
key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
@@ -366,8 +528,34 @@
return nil
}
-func (t *TechProfileMgr) CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfId uint32) (*TechProfile, error) {
+func (t *TechProfileMgr) getEponTPFromKVStore(ctx context.Context, techProfiletblID uint32) *DefaultEponProfile {
+ var kvtechprofile DefaultEponProfile
+ key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
+ logger.Debugw("Getting techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "Key": key})
+ kvresult, err := t.config.KVBackend.Get(ctx, key)
+ if err != nil {
+ logger.Errorw("Error while fetching value from KV store", log.Fields{"key": key})
+ return nil
+ }
+ if kvresult != nil {
+ /* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
+ if value, err := kvstore.ToByte(kvresult.Value); err == nil {
+ if err = json.Unmarshal(value, &kvtechprofile); err != nil {
+ logger.Errorw("Error unmarshaling techprofile fetched from KV store", log.Fields{"techProfiletblID": techProfiletblID, "error": err, "techprofile_json": value})
+ return nil
+ }
+
+ logger.Debugw("Success fetched techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "value": kvtechprofile})
+ return &kvtechprofile
+ }
+ }
+ return nil
+}
+
+func (t *TechProfileMgr) CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfId uint32) (interface{}, error) {
var tpInstance *TechProfile
+ var tpEponInstance *EponProfile
+
logger.Infow("creating-tp-instance", log.Fields{"tableid": techProfiletblID, "uni": uniPortName, "intId": intfId})
// Make sure the uniPortName is as per format pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}
@@ -375,31 +563,62 @@
logger.Errorw("uni-port-name-not-confirming-to-format", log.Fields{"uniPortName": uniPortName})
return nil, errors.New("uni-port-name-not-confirming-to-format")
}
-
- tp := t.getTPFromKVStore(ctx, techProfiletblID)
- if tp != nil {
- if err := t.validateInstanceControlAttr(tp.InstanceCtrl); err != nil {
- logger.Error("invalid-instance-ctrl-attr--using-default-tp")
- tp = t.getDefaultTechProfile()
- } else {
- logger.Infow("using-specified-tp-from-kv-store", log.Fields{"tpid": techProfiletblID})
- }
- } else {
- logger.Info("tp-not-found-on-kv--creating-default-tp")
- tp = t.getDefaultTechProfile()
- }
tpInstancePath := t.GetTechProfileInstanceKVPath(techProfiletblID, uniPortName)
- if tpInstance = t.allocateTPInstance(ctx, uniPortName, tp, intfId, tpInstancePath); tpInstance == nil {
- logger.Error("tp-intance-allocation-failed")
- return nil, errors.New("tp-intance-allocation-failed")
+ // For example:
+ // tpInstPath like "XGS-PON/64/uni_port_name"
+ // is broken into ["XGS-PON" "64" ...]
+ pathSlice := regexp.MustCompile(`/`).Split(tpInstancePath, -1)
+ if pathSlice[0] == epon {
+ tp := t.getEponTPFromKVStore(ctx, techProfiletblID)
+ if tp != nil {
+ if err := t.validateInstanceControlAttr(tp.InstanceCtrl); err != nil {
+ logger.Error("invalid-instance-ctrl-attr--using-default-tp")
+ tp = t.getDefaultEponProfile()
+ } else {
+ logger.Infow("using-specified-tp-from-kv-store", log.Fields{"tpid": techProfiletblID})
+ }
+ } else {
+ logger.Info("tp-not-found-on-kv--creating-default-tp")
+ tp = t.getDefaultEponProfile()
+ }
+
+ if tpEponInstance = t.allocateEponTPInstance(ctx, uniPortName, tp, intfId, tpInstancePath); tpEponInstance == nil {
+ logger.Error("tp-intance-allocation-failed")
+ return nil, errors.New("tp-intance-allocation-failed")
+ }
+ if err := t.addEponProfInstanceToKVStore(ctx, techProfiletblID, uniPortName, tpEponInstance); err != nil {
+ logger.Errorw("error-adding-tp-to-kv-store", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
+ return nil, errors.New("error-adding-tp-to-kv-store")
+ }
+ logger.Infow("tp-added-to-kv-store-successfully",
+ log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
+ return tpEponInstance, nil
+ } else {
+ tp := t.getTPFromKVStore(ctx, techProfiletblID)
+ if tp != nil {
+ if err := t.validateInstanceControlAttr(tp.InstanceCtrl); err != nil {
+ logger.Error("invalid-instance-ctrl-attr--using-default-tp")
+ tp = t.getDefaultTechProfile()
+ } else {
+ logger.Infow("using-specified-tp-from-kv-store", log.Fields{"tpid": techProfiletblID})
+ }
+ } else {
+ logger.Info("tp-not-found-on-kv--creating-default-tp")
+ tp = t.getDefaultTechProfile()
+ }
+
+ if tpInstance = t.allocateTPInstance(ctx, uniPortName, tp, intfId, tpInstancePath); tpInstance == nil {
+ logger.Error("tp-intance-allocation-failed")
+ return nil, errors.New("tp-intance-allocation-failed")
+ }
+ if err := t.addTechProfInstanceToKVStore(ctx, techProfiletblID, uniPortName, tpInstance); err != nil {
+ logger.Errorw("error-adding-tp-to-kv-store", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
+ return nil, errors.New("error-adding-tp-to-kv-store")
+ }
+ logger.Infow("tp-added-to-kv-store-successfully",
+ log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
+ return tpInstance, nil
}
- if err := t.addTechProfInstanceToKVStore(ctx, techProfiletblID, uniPortName, tpInstance); err != nil {
- logger.Errorw("error-adding-tp-to-kv-store", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
- return nil, errors.New("error-adding-tp-to-kv-store")
- }
- logger.Infow("tp-added-to-kv-store-successfully",
- log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
- return tpInstance, nil
}
func (t *TechProfileMgr) DeleteTechProfileInstance(ctx context.Context, techProfiletblID uint32, uniPortName string) error {
@@ -561,6 +780,91 @@
DownstreamGemPortAttributeList: dsGemPortAttributeList}
}
+// allocateTPInstance function for EPON
+func (t *TechProfileMgr) allocateEponTPInstance(ctx context.Context, uniPortName string, tp *DefaultEponProfile, intfId uint32, tpInstPath string) *EponProfile {
+
+ var usQueueAttributeList []iUpstreamQueueAttribute
+ var dsQueueAttributeList []iDownstreamQueueAttribute
+ var tcontIDs []uint32
+ var gemPorts []uint32
+ var err error
+
+ log.Infow("Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
+
+ if tp.InstanceCtrl.Onu == "multi-instance" {
+ if tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
+ log.Errorw("Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
+ return nil
+ }
+ } else { // "single-instance"
+ if tpInst, err := t.getSingleInstanceEponTp(ctx, tpInstPath); err != nil {
+ log.Errorw("Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
+ return nil
+ } else if tpInst == nil {
+ // No "single-instance" tp found on one any uni port for the given TP ID
+ // Allocate a new TcontID or AllocID
+ if tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
+ log.Errorw("Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
+ return nil
+ }
+ } else {
+ // Use the alloc-id from the existing TpInstance
+ tcontIDs = append(tcontIDs, tpInst.AllocID)
+ }
+ }
+ log.Debugw("Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
+ if gemPorts, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
+ log.Errorw("Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
+ return nil
+ }
+ log.Infow("Allocated tconts and GEM ports successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
+ for index := 0; index < int(tp.NumGemPorts); index++ {
+ usQueueAttributeList = append(usQueueAttributeList,
+ iUpstreamQueueAttribute{GemportID: gemPorts[index],
+ MaxQueueSize: tp.UpstreamQueueAttributeList[index].MaxQueueSize,
+ PbitMap: tp.UpstreamQueueAttributeList[index].PbitMap,
+ AesEncryption: tp.UpstreamQueueAttributeList[index].AesEncryption,
+ TrafficType: tp.UpstreamQueueAttributeList[index].TrafficType,
+ UnsolicitedGrantSize: tp.UpstreamQueueAttributeList[index].UnsolicitedGrantSize,
+ NominalInterval: tp.UpstreamQueueAttributeList[index].NominalInterval,
+ ToleratedPollJitter: tp.UpstreamQueueAttributeList[index].ToleratedPollJitter,
+ RequestTransmissionPolicy: tp.UpstreamQueueAttributeList[index].RequestTransmissionPolicy,
+ NumQueueSet: tp.UpstreamQueueAttributeList[index].NumQueueSet,
+ QThresholds: tp.UpstreamQueueAttributeList[index].QThresholds,
+ SchedulingPolicy: tp.UpstreamQueueAttributeList[index].SchedulingPolicy,
+ PriorityQueue: tp.UpstreamQueueAttributeList[index].PriorityQueue,
+ Weight: tp.UpstreamQueueAttributeList[index].Weight,
+ DiscardPolicy: tp.UpstreamQueueAttributeList[index].DiscardPolicy,
+ DiscardConfig: tp.UpstreamQueueAttributeList[index].DiscardConfig})
+ }
+
+ log.Info("length of DownstreamGemPortAttributeList", len(tp.DownstreamQueueAttributeList))
+ for index := 0; index < int(tp.NumGemPorts); index++ {
+ dsQueueAttributeList = append(dsQueueAttributeList,
+ iDownstreamQueueAttribute{GemportID: gemPorts[index],
+ MaxQueueSize: tp.DownstreamQueueAttributeList[index].MaxQueueSize,
+ PbitMap: tp.DownstreamQueueAttributeList[index].PbitMap,
+ AesEncryption: tp.DownstreamQueueAttributeList[index].AesEncryption,
+ SchedulingPolicy: tp.DownstreamQueueAttributeList[index].SchedulingPolicy,
+ PriorityQueue: tp.DownstreamQueueAttributeList[index].PriorityQueue,
+ Weight: tp.DownstreamQueueAttributeList[index].Weight,
+ DiscardPolicy: tp.DownstreamQueueAttributeList[index].DiscardPolicy,
+ DiscardConfig: tp.DownstreamQueueAttributeList[index].DiscardConfig})
+ }
+
+ return &EponProfile{
+ SubscriberIdentifier: uniPortName,
+ Name: tp.Name,
+ ProfileType: tp.ProfileType,
+ Version: tp.Version,
+ NumGemPorts: tp.NumGemPorts,
+ InstanceCtrl: tp.InstanceCtrl,
+ EponAttribute: tp.EponAttribute,
+ AllocID: tcontIDs[0],
+ UpstreamQueueAttributeList: usQueueAttributeList,
+ DownstreamQueueAttributeList: dsQueueAttributeList}
+}
+
// getSingleInstanceTp returns another TpInstance for an ONU on a different
// uni port for the same TP ID, if it finds one, else nil.
func (t *TechProfileMgr) getSingleInstanceTp(ctx context.Context, tpPath string) (*TechProfile, error) {
@@ -587,6 +891,30 @@
return nil, nil
}
+func (t *TechProfileMgr) getSingleInstanceEponTp(ctx context.Context, tpPath string) (*EponProfile, error) {
+ var tpInst EponProfile
+
+ // For example:
+ // tpPath like "service/voltha/technology_profiles/xgspon/64/pon-{0}/onu-{1}/uni-{1}"
+ // is broken into ["service/voltha/technology_profiles/xgspon/64/pon-{0}/onu-{1}" ""]
+ uniPathSlice := regexp.MustCompile(`/uni-{[0-9]+}$`).Split(tpPath, 2)
+ kvPairs, _ := t.config.KVBackend.List(ctx, uniPathSlice[0])
+
+ // Find a valid TP Instance among all the UNIs of that ONU for the given TP ID
+ for keyPath, kvPair := range kvPairs {
+ if value, err := kvstore.ToByte(kvPair.Value); err == nil {
+ if err = json.Unmarshal(value, &tpInst); err != nil {
+ logger.Errorw("error-unmarshal-kv-pair", log.Fields{"keyPath": keyPath, "value": value})
+ return nil, errors.New("error-unmarshal-kv-pair")
+ } else {
+ logger.Debugw("found-valid-tp-instance-on-another-uni", log.Fields{"keyPath": keyPath})
+ return &tpInst, nil
+ }
+ }
+ }
+ return nil, nil
+}
+
func (t *TechProfileMgr) getDefaultTechProfile() *DefaultTechProfile {
var usGemPortAttributeList []GemPortAttribute
@@ -650,6 +978,70 @@
DownstreamGemPortAttributeList: dsGemPortAttributeList}
}
+// getDefaultTechProfile function for EPON
+func (t *TechProfileMgr) getDefaultEponProfile() *DefaultEponProfile {
+
+ var usQueueAttributeList []UpstreamQueueAttribute
+ var dsQueueAttributeList []DownstreamQueueAttribute
+
+ for _, pbit := range t.config.DefaultPbits {
+ log.Debugw("Creating Queue", log.Fields{"pbit": pbit})
+ usQueueAttributeList = append(usQueueAttributeList,
+ UpstreamQueueAttribute{
+ MaxQueueSize: defaultMaxQueueSize,
+ PbitMap: pbit,
+ AesEncryption: defaultAESEncryption,
+ TrafficType: defaultTrafficType,
+ UnsolicitedGrantSize: defaultUnsolicitedGrantSize,
+ NominalInterval: defaultNominalInterval,
+ ToleratedPollJitter: defaultToleratedPollJitter,
+ RequestTransmissionPolicy: defaultRequestTransmissionPolicy,
+ NumQueueSet: defaultNumQueueSet,
+ QThresholds: QThresholds{
+ QThreshold1: defaultQThreshold1,
+ QThreshold2: defaultQThreshold2,
+ QThreshold3: defaultQThreshold3,
+ QThreshold4: defaultQThreshold4,
+ QThreshold5: defaultQThreshold5,
+ QThreshold6: defaultQThreshold6,
+ QThreshold7: defaultQThreshold7},
+ SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
+ PriorityQueue: defaultPriorityQueue,
+ Weight: defaultQueueWeight,
+ DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
+ DiscardConfig: DiscardConfig{
+ MinThreshold: defaultMinThreshold,
+ MaxThreshold: defaultMaxThreshold,
+ MaxProbability: defaultMaxProbability}})
+ dsQueueAttributeList = append(dsQueueAttributeList,
+ DownstreamQueueAttribute{
+ MaxQueueSize: defaultMaxQueueSize,
+ PbitMap: pbit,
+ AesEncryption: defaultAESEncryption,
+ SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
+ PriorityQueue: defaultPriorityQueue,
+ Weight: defaultQueueWeight,
+ DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
+ DiscardConfig: DiscardConfig{
+ MinThreshold: defaultMinThreshold,
+ MaxThreshold: defaultMaxThreshold,
+ MaxProbability: defaultMaxProbability}})
+ }
+ return &DefaultEponProfile{
+ Name: t.config.DefaultTPName,
+ ProfileType: t.resourceMgr.GetTechnology(),
+ Version: t.config.TPVersion,
+ NumGemPorts: uint32(len(usQueueAttributeList)),
+ InstanceCtrl: InstanceControl{
+ Onu: defaultOnuInstance,
+ Uni: defaultUniInstance,
+ MaxGemPayloadSize: defaultGemPayloadSize},
+ EponAttribute: EponAttribute{
+ PackageType: defaultPakageType},
+ UpstreamQueueAttributeList: usQueueAttributeList,
+ DownstreamQueueAttributeList: dsQueueAttributeList}
+}
+
func (t *TechProfileMgr) GetprotoBufParamValue(paramType string, paramKey string) int32 {
var result int32 = -1
@@ -880,65 +1272,128 @@
Scheduler: UsScheduler}
}
-func (t *TechProfileMgr) GetGemportIDForPbit(tp *TechProfile, dir tp_pb.Direction, pbit uint32) uint32 {
+func (t *TechProfileMgr) GetGemportIDForPbit(tp interface{}, dir tp_pb.Direction, pbit uint32) uint32 {
/*
- Function to get the Gemport ID mapped to a pbit.
+ Function to get the Gemport ID mapped to a pbit.
*/
- if dir == tp_pb.Direction_UPSTREAM {
- // upstream GEM ports
- numGemPorts := len(tp.UpstreamGemPortAttributeList)
- for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
- lenOfPbitMap := len(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap)
- for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
- // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
- // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
- if p, err := strconv.Atoi(string(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
- if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
- logger.Debugw("Found-US-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.UpstreamGemPortAttributeList[gemCnt].GemportID})
- return tp.UpstreamGemPortAttributeList[gemCnt].GemportID
+ switch tp := tp.(type) {
+ case *TechProfile:
+ if dir == tp_pb.Direction_UPSTREAM {
+ // upstream GEM ports
+ numGemPorts := len(tp.UpstreamGemPortAttributeList)
+ for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
+ lenOfPbitMap := len(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap)
+ for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
+ // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
+ // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
+ if p, err := strconv.Atoi(string(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
+ if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
+ logger.Debugw("Found-US-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.UpstreamGemPortAttributeList[gemCnt].GemportID})
+ return tp.UpstreamGemPortAttributeList[gemCnt].GemportID
+ }
+ }
+ }
+ }
+ } else if dir == tp_pb.Direction_DOWNSTREAM {
+ //downstream GEM ports
+ numGemPorts := len(tp.DownstreamGemPortAttributeList)
+ for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
+ lenOfPbitMap := len(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap)
+ for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
+ // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
+ // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
+ if p, err := strconv.Atoi(string(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
+ if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
+ logger.Debugw("Found-DS-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.DownstreamGemPortAttributeList[gemCnt].GemportID})
+ return tp.DownstreamGemPortAttributeList[gemCnt].GemportID
+ }
}
}
}
}
- } else if dir == tp_pb.Direction_DOWNSTREAM {
- //downstream GEM ports
- numGemPorts := len(tp.DownstreamGemPortAttributeList)
- for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
- lenOfPbitMap := len(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap)
- for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
- // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
- // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
- if p, err := strconv.Atoi(string(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
- if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
- logger.Debugw("Found-DS-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.DownstreamGemPortAttributeList[gemCnt].GemportID})
- return tp.DownstreamGemPortAttributeList[gemCnt].GemportID
+ logger.Errorw("No-GemportId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
+ case *EponProfile:
+ if dir == tp_pb.Direction_UPSTREAM {
+ // upstream GEM ports
+ numGemPorts := len(tp.UpstreamQueueAttributeList)
+ for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
+ lenOfPbitMap := len(tp.UpstreamQueueAttributeList[gemCnt].PbitMap)
+ for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
+ // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
+ // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
+ if p, err := strconv.Atoi(string(tp.UpstreamQueueAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
+ if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
+ logger.Debugw("Found-US-Queue-for-Pcp", log.Fields{"pbit": pbit, "Queue": tp.UpstreamQueueAttributeList[gemCnt].GemportID})
+ return tp.UpstreamQueueAttributeList[gemCnt].GemportID
+ }
+ }
+ }
+ }
+ } else if dir == tp_pb.Direction_DOWNSTREAM {
+ //downstream GEM ports
+ numGemPorts := len(tp.DownstreamQueueAttributeList)
+ for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
+ lenOfPbitMap := len(tp.DownstreamQueueAttributeList[gemCnt].PbitMap)
+ for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
+ // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
+ // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
+ if p, err := strconv.Atoi(string(tp.DownstreamQueueAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
+ if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
+ logger.Debugw("Found-DS-Queue-for-Pcp", log.Fields{"pbit": pbit, "Queue": tp.DownstreamQueueAttributeList[gemCnt].GemportID})
+ return tp.DownstreamQueueAttributeList[gemCnt].GemportID
+ }
}
}
}
}
+ logger.Errorw("No-QueueId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
+ default:
+ logger.Errorw("unknown-tech", log.Fields{"tp": tp})
}
- logger.Errorw("No-GemportId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
return 0
}
// FindAllTpInstances returns all TechProfile instances for a given TechProfile table-id, pon interface ID and onu ID.
-func (t *TechProfileMgr) FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) []TechProfile {
- var tp TechProfile
+func (t *TechProfileMgr) FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) interface{} {
+ var tpTech TechProfile
+ var tpEpon EponProfile
+
onuTpInstancePath := fmt.Sprintf("%s/%d/pon-{%d}/onu-{%d}", t.resourceMgr.GetTechnology(), techProfiletblID, ponIntf, onuID)
if kvPairs, _ := t.config.KVBackend.List(ctx, onuTpInstancePath); kvPairs != nil {
- tpInstances := make([]TechProfile, 0, len(kvPairs))
+ tech := t.resourceMgr.GetTechnology()
+ tpInstancesTech := make([]TechProfile, 0, len(kvPairs))
+ tpInstancesEpon := make([]EponProfile, 0, len(kvPairs))
+
for kvPath, kvPair := range kvPairs {
if value, err := kvstore.ToByte(kvPair.Value); err == nil {
- if err = json.Unmarshal(value, &tp); err != nil {
- logger.Errorw("error-unmarshal-kv-pair", log.Fields{"kvPath": kvPath, "value": value})
- continue
- } else {
- tpInstances = append(tpInstances, tp)
+ if tech == xgspon || tech == xgsponBbsim || tech == gpon {
+ if err = json.Unmarshal(value, &tpTech); err != nil {
+ logger.Errorw("error-unmarshal-kv-pair", log.Fields{"kvPath": kvPath, "value": value})
+ continue
+ } else {
+ tpInstancesTech = append(tpInstancesTech, tpTech)
+ }
+ } else if tech == epon {
+ if err = json.Unmarshal(value, &tpEpon); err != nil {
+ logger.Errorw("error-unmarshal-kv-pair", log.Fields{"kvPath": kvPath, "value": value})
+ continue
+ } else {
+ tpInstancesEpon = append(tpInstancesEpon, tpEpon)
+ }
}
}
}
- return tpInstances
+
+ switch tech {
+ case xgspon, xgsponBbsim, gpon:
+ return tpInstancesTech
+ case epon:
+ return tpInstancesEpon
+ default:
+ log.Errorw("unknown-technology", log.Fields{"tech": tech})
+ return nil
+ }
}
return nil
}
diff --git a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile_if.go b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile_if.go
index e605d49..8391a5b 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile_if.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v3/pkg/techprofile/tech_profile_if.go
@@ -26,8 +26,8 @@
type TechProfileIf interface {
SetKVClient() *db.Backend
GetTechProfileInstanceKVPath(techProfiletblID uint32, uniPortName string) string
- GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (*TechProfile, error)
- CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfId uint32) (*TechProfile, error)
+ GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (interface{}, error)
+ CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfId uint32) (interface{}, error)
DeleteTechProfileInstance(ctx context.Context, techProfiletblID uint32, uniPortName string) error
GetprotoBufParamValue(paramType string, paramKey string) int32
GetUsScheduler(tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error)
@@ -36,6 +36,6 @@
ShapingCfg *tp_pb.TrafficShapingInfo) *tp_pb.TrafficScheduler
GetTrafficQueues(tp *TechProfile, Dir tp_pb.Direction) ([]*tp_pb.TrafficQueue, error)
GetMulticastTrafficQueues(tp *TechProfile) []*tp_pb.TrafficQueue
- GetGemportIDForPbit(tp *TechProfile, Dir tp_pb.Direction, pbit uint32) uint32
- FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) []TechProfile
+ GetGemportIDForPbit(tp interface{}, Dir tp_pb.Direction, pbit uint32) uint32
+ FindAllTpInstances(ctx context.Context, techProfiletblID uint32, ponIntf uint32, onuID uint32) interface{}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 2b9c41a..af2b034 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -67,7 +67,7 @@
github.com/mitchellh/go-homedir
# github.com/mitchellh/mapstructure v1.1.2
github.com/mitchellh/mapstructure
-# github.com/opencord/voltha-lib-go/v3 v3.1.19
+# github.com/opencord/voltha-lib-go/v3 v3.1.20
github.com/opencord/voltha-lib-go/v3/pkg/adapters
github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif
github.com/opencord/voltha-lib-go/v3/pkg/adapters/common