[VOL-2774] Allow not filtering the pbit values for the TT workflow
Change-Id: I64b991143b7654807af10359ba67fab0af7b76a1
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
index 07469d7..9640251 100644
--- a/internal/pkg/core/openolt_flowmgr.go
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -733,18 +733,23 @@
"action": action, "direction": direction, "allocId": allocID, "gemPortId": gemPortID,
"logicalFlow": *logicalFlow})
var vlanPbit uint32 = 0xff // means no pbit
+ var vlanVid uint32
if _, ok := classifier[VlanPcp]; ok {
vlanPbit = classifier[VlanPcp].(uint32)
logger.Debugw("Found pbit in the flow", log.Fields{"VlanPbit": vlanPbit})
} else {
logger.Debugw("pbit-not-found-in-flow", log.Fields{"vlan-pcp": VlanPcp})
}
+ if _, ok := classifier[VlanVid]; ok {
+ vlanVid = classifier[VlanVid].(uint32)
+ log.Debugw("Found vlan in the flow", log.Fields{"VlanVid": vlanVid})
+ }
flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
logger.Debug("flow-already-exists")
return nil
}
- flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, HsiaFlow, vlanPbit)
+ flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, HsiaFlow, vlanVid, vlanPbit)
if err != nil {
return olterrors.NewErrNotFound("hsia-flow-id", log.Fields{"direction": direction}, err).Log()
}
@@ -753,7 +758,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
}
logger.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(action)
+ actionProto, err := makeOpenOltActionField(action, classifier)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
}
@@ -837,7 +842,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
}
logger.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(action)
+ actionProto, err := makeOpenOltActionField(action, classifier)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
}
@@ -922,7 +927,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
}
logger.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(action)
+ actionProto, err := makeOpenOltActionField(action, classifier)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
}
@@ -968,6 +973,7 @@
uplinkClassifier[EthType] = uint32(EapEthType)
uplinkClassifier[PacketTagType] = SingleTag
uplinkClassifier[VlanVid] = vlanID
+ uplinkClassifier[VlanPcp] = classifier[VlanPcp]
// Fill action
uplinkAction[TrapToHost] = true
flowStoreCookie := getFlowStoreCookie(uplinkClassifier, gemPortID)
@@ -976,7 +982,7 @@
return nil
}
//Add Uplink EAPOL Flow
- uplinkFlowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, "", 0)
+ uplinkFlowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, "", 0, 0)
if err != nil {
return olterrors.NewErrNotFound("flow-id", log.Fields{
"interface-id": intfID,
@@ -991,7 +997,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": uplinkClassifier}, err).Log()
}
logger.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(uplinkAction)
+ actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction}, err).Log()
}
@@ -1078,16 +1084,31 @@
return &classifier, nil
}
-func makeOpenOltActionField(actionInfo map[string]interface{}) (*openoltpb2.Action, error) {
+func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
var actionCmd openoltpb2.ActionCmd
var action openoltpb2.Action
action.Cmd = &actionCmd
if _, ok := actionInfo[PopVlan]; ok {
- action.OVid = actionInfo[VlanVid].(uint32)
action.Cmd.RemoveOuterTag = true
+ if _, ok := actionInfo[VlanPcp]; ok {
+ action.Cmd.RemarkInnerPbits = true
+ action.IPbits = actionInfo[VlanPcp].(uint32)
+ if _, ok := actionInfo[VlanVid]; ok {
+ action.Cmd.TranslateInnerTag = true
+ action.IVid = actionInfo[VlanVid].(uint32)
+ }
+ }
} else if _, ok := actionInfo[PushVlan]; ok {
action.OVid = actionInfo[VlanVid].(uint32)
action.Cmd.AddOuterTag = true
+ if _, ok := actionInfo[VlanPcp]; ok {
+ action.OPbits = actionInfo[VlanPcp].(uint32)
+ action.Cmd.RemarkOuterPbits = true
+ if _, ok := classifierInfo[VlanVid]; ok {
+ action.IVid = classifierInfo[VlanVid].(uint32)
+ action.Cmd.TranslateInnerTag = true
+ }
+ }
} else if _, ok := actionInfo[TrapToHost]; ok {
action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
} else {
@@ -1347,7 +1368,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifierInfo}, err)
}
logger.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(actionInfo)
+ actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": actionInfo}, err)
}
@@ -2418,35 +2439,60 @@
gemPorts []uint32,
TpInst *tp.TechProfile,
FlowType string,
+ direction string,
vlanID ...uint32) {
logger.Debugw("Installing flow on all GEM ports", log.Fields{"FlowType": FlowType, "gemPorts": gemPorts, "vlan": vlanID})
- for _, gemPortAttribute := range TpInst.UpstreamGemPortAttributeList {
- var gemPortID uint32
- // The bit mapping for a gemport is expressed in tech-profile as a binary string. For example, 0b00000001
- // We need to trim prefix "0b", before further processing
- // Once the "0b" prefix is trimmed, we iterate each character in the string to identify which index
- // in the string is set to binary bit 1 (expressed as char '1' in the binary string).
- for pos, pbitSet := range strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix) {
- // If a particular character in the string is set to '1', identify the index of this character from
- // the LSB position which marks the PCP bit consumed by the given gem port.
- // This PCP bit now becomes a classifier in the flow.
- if pbitSet == BinaryBit1 {
- classifier[VlanPcp] = uint32(len(strings.TrimPrefix(gemPortAttribute.PbitMap, BinaryStringPrefix))) - 1 - uint32(pos)
- gemPortID = gemPortAttribute.GemportID
- if FlowType == HsiaFlow || FlowType == DhcpFlow || FlowType == IgmpFlow {
- f1(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID)
- } else if FlowType == EapolFlow {
- f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0])
- } else {
- logger.Errorw("Unrecognized Flow Type", log.Fields{"FlowType": FlowType})
- return
+ // The bit mapping for a gemport is expressed in tech-profile as a binary string. For example, 0b00000001
+ // We need to trim prefix "0b", before further processing
+ // Once the "0b" prefix is trimmed, we iterate each character in the string to identify which index
+ // in the string is set to binary bit 1 (expressed as char '1' in the binary string).
+
+ // If a particular character in the string is set to '1', identify the index of this character from
+ // 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
+ }
+ 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)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0])
+ }
+ } 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)
+ } else if FlowType == EapolFlow {
+ f2(ctx, args["intfId"], args["onuId"], args["uniId"], args["portNo"], classifier, action, logicalFlow, args["allocId"], gemPortID, vlanID[0])
+ }
}
}
}
}
}
+func allPbitsMarked(pbitMap string) bool {
+ for pos, pBit := range pbitMap {
+ if pos >= 2 && pBit != BinaryBit1 {
+ return false
+ }
+ }
+ return true
+}
+
func (f *OpenOltFlowMgr) addDHCPTrapFlowOnNNI(ctx context.Context, logicalFlow *ofp.OfpFlowStats, classifier map[string]interface{}, portNo uint32) error {
logger.Debug("Adding trap-dhcp-of-nni-flow")
action := make(map[string]interface{})
@@ -2480,7 +2526,7 @@
logger.Debug("Flow-exists-not-re-adding")
return nil
}
- flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0)
+ flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0, 0)
if err != nil {
return olterrors.NewErrNotFound("dhcp-trap-nni-flow-id", log.Fields{
"interface-id": networkInterfaceID,
@@ -2495,7 +2541,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err)
}
logger.Debugw("Created classifier proto", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(action)
+ actionProto, err := makeOpenOltActionField(action, classifier)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err)
}
@@ -2601,7 +2647,7 @@
return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err)
}
logger.Debugw("Created classifier proto for the IGMP flow", log.Fields{"classifier": *classifierProto})
- actionProto, err := makeOpenOltActionField(action)
+ actionProto, err := makeOpenOltActionField(action, classifier)
if err != nil {
return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err)
}
@@ -2662,10 +2708,11 @@
tp_pb.Direction_UPSTREAM,
pcp.(uint32))
//Adding DHCP upstream flow
+
f.addDHCPTrapFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
} else {
//Adding DHCP upstream flow to all gemports
- installFlowOnAllGemports(ctx, f.addDHCPTrapFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, DhcpFlow)
+ installFlowOnAllGemports(ctx, f.addDHCPTrapFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, DhcpFlow, Upstream)
}
} else if ipProto == IgmpProto {
@@ -2677,7 +2724,7 @@
f.addIGMPTrapFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
} else {
//Adding IGMP upstream flow to all gem ports
- installFlowOnAllGemports(ctx, f.addIGMPTrapFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, IgmpFlow)
+ installFlowOnAllGemports(ctx, f.addIGMPTrapFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, IgmpFlow, Upstream)
}
} else {
logger.Errorw("Invalid-Classifier-to-handle", log.Fields{"classifier": classifierInfo, "action": actionInfo})
@@ -2699,7 +2746,7 @@
f.addEAPOLFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort, vlanID)
} else {
- installFlowOnAllGemports(ctx, nil, f.addEAPOLFlow, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, EapolFlow, vlanID)
+ installFlowOnAllGemports(ctx, nil, f.addEAPOLFlow, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, EapolFlow, Upstream, vlanID)
}
}
} else if _, ok := actionInfo[PushVlan]; ok {
@@ -2712,7 +2759,7 @@
f.addUpstreamDataFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
} else {
//Adding HSIA upstream flow to all gemports
- installFlowOnAllGemports(ctx, f.addUpstreamDataFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, HsiaFlow)
+ installFlowOnAllGemports(ctx, f.addUpstreamDataFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, HsiaFlow, Upstream)
}
} else if _, ok := actionInfo[PopVlan]; ok {
logger.Info("Adding Downstream data rule")
@@ -2724,7 +2771,7 @@
f.addDownstreamDataFlow(ctx, intfID, onuID, uniID, portNo, classifierInfo, actionInfo, flow, allocID, gemPort)
} else {
//Adding HSIA downstream flow to all gemports
- installFlowOnAllGemports(ctx, f.addDownstreamDataFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, HsiaFlow)
+ installFlowOnAllGemports(ctx, f.addDownstreamDataFlow, nil, args, classifierInfo, actionInfo, flow, gemPorts, TpInst, HsiaFlow, Downstream)
}
} else {
logger.Errorw("Invalid-flow-type-to-handle", log.Fields{"classifier": classifierInfo, "action": actionInfo, "flow": flow})