VOL-4625: Support for FTTB flows in openolt adapter
Change-Id: Icdf3c66f310f68101e8a84ef272ed38b849d77bf
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
index 8b24630..06ad2c0 100644
--- a/internal/pkg/core/openolt_flowmgr.go
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -91,6 +91,8 @@
EthType = "eth_type"
//EthDst constant
EthDst = "eth_dst"
+ //EthSrc constant
+ EthSrc = "eth_src"
//TPID constant
TPID = "tpid"
//IPProto constant
@@ -978,28 +980,38 @@
}
func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
- flowContext.classifier[PacketTagType] = SingleTag // FIXME: This hardcoding needs to be removed.
+ flowContext.classifier[PacketTagType] = SingleTag
+ // extract the cvid/inner-vid from the write metadata
+ writeMetadata := flows.GetMetadataFromWriteMetadataAction(ctx, flowContext.logicalFlow)
+ if writeMetadata != 0 {
+ // Writemetadata field is 8 bytes
+ // cvid is on the outer most two bytes of the write metadata
+ cvid := (writeMetadata & 0xffff000000000000) >> 48
+ // if the cvid does not match the classifier vlan, then this indicates it is a double tagged packet
+ if cvid != flowContext.classifier[VlanVid] && cvid != 0 {
+ flowContext.classifier[PacketTagType] = DoubleTag
+ }
+ }
logger.Debugw(ctx, "adding-upstream-data-flow",
log.Fields{
"uplinkClassifier": flowContext.classifier,
"uplinkAction": flowContext.action})
return f.addSymmetricDataPathFlow(ctx, flowContext, Upstream)
- /* TODO: Install Secondary EAP on the subscriber vlan */
}
func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
downlinkClassifier := flowContext.classifier
downlinkAction := flowContext.action
-
- // TODO: For now mark the PacketTagType as SingleTag when OLT is transparent to VLAN
- // Per some deployment models, it is also possible that ONU operates on double tagged packets,
- // so this hardcoding of SingeTag packet-tag-type may be problem for such deployment models.
- // Need a better way for detection of packet tag type from OpenFlow message.
- if _, ok := downlinkClassifier[VlanVid]; !ok {
- downlinkClassifier[PacketTagType] = SingleTag
- } else {
- downlinkClassifier[PacketTagType] = DoubleTag
- downlinkAction[PopVlan] = true
+ // default to single tag. If we detect an inner cvid from write-metadata, then we mark the PacketTagType as DoubleTag
+ downlinkClassifier[PacketTagType] = SingleTag
+ // extract the cvid/inner-vid from the write metadata
+ writeMetadata := flows.GetMetadataFromWriteMetadataAction(ctx, flowContext.logicalFlow)
+ if writeMetadata != 0 {
+ // Writemetadata field is 8 bytes
+ // cvid is on the outer most two bytes of the write metadata
+ if cvid := (writeMetadata & 0xffff000000000000) >> 48; cvid != 0 {
+ downlinkClassifier[PacketTagType] = DoubleTag
+ }
}
logger.Debugw(ctx, "adding-downstream-data-flow",
log.Fields{
@@ -1022,10 +1034,14 @@
}
}
- // vlan_vid is a uint32. must be type asserted as such or conversion fails
- dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
- if ok {
- downlinkAction[VlanVid] = dlClVid & 0xfff
+ // If Pop Vlan action is specified, set the vlan to be popped from the classifier vlan match field.
+ // The matched vlan is the one that is getting popped.
+ if val, ok := downlinkAction[PopVlan]; ok && val.(bool) {
+ // vlan_vid is a uint32. must be type asserted as such or conversion fails
+ dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
+ if ok {
+ downlinkAction[VlanVid] = dlClVid & 0xfff
+ }
}
return f.addSymmetricDataPathFlow(ctx, flowContext, Downstream)
@@ -1464,6 +1480,7 @@
classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
+ classifier.SrcMac, _ = classifierInfo[EthSrc].([]uint8)
if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
classifier.PktTagType = pktTagType
@@ -1483,28 +1500,38 @@
var action openoltpb2.Action
action.Cmd = &actionCmd
if _, ok := actionInfo[PopVlan]; ok {
+ // Pop outer vid
action.Cmd.RemoveOuterTag = true
if _, ok := actionInfo[VlanPcp]; ok {
+ // Remark inner pbit
action.Cmd.RemarkInnerPbits = true
action.IPbits = actionInfo[VlanPcp].(uint32)
if _, ok := actionInfo[VlanVid]; ok {
+ // Remark inner vid
action.Cmd.TranslateInnerTag = true
action.IVid = actionInfo[VlanVid].(uint32)
}
}
} else if _, ok := actionInfo[PushVlan]; ok {
+ // push outer vid
action.OVid = actionInfo[VlanVid].(uint32)
action.Cmd.AddOuterTag = true
if _, ok := actionInfo[VlanPcp]; ok {
+ // translate outer pbit
action.OPbits = actionInfo[VlanPcp].(uint32)
action.Cmd.RemarkOuterPbits = true
if _, ok := classifierInfo[VlanVid]; ok {
+ // translate inner vid
action.IVid = classifierInfo[VlanVid].(uint32)
action.Cmd.TranslateInnerTag = true
}
}
} else if _, ok := actionInfo[TrapToHost]; ok {
action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
+ } else if _, ok := actionInfo[VlanVid]; ok {
+ // Translate outer vid
+ action.Cmd.TranslateOuterTag = true
+ action.OVid = actionInfo[VlanVid].(uint32)
}
// When OLT is transparent to vlans no-action is valid.
/*
@@ -2965,7 +2992,10 @@
logger.Debug(ctx, "field-type-eth-type", log.Fields{"classifierInfo[ETH_TYPE]": classifierInfo[EthType].(uint32)})
} else if field.Type == flows.ETH_DST {
classifierInfo[EthDst] = field.GetEthDst()
- logger.Debug(ctx, "field-type-eth-type", log.Fields{"classifierInfo[ETH_DST]": classifierInfo[EthDst].([]uint8)})
+ logger.Debug(ctx, "field-type-eth-dst", log.Fields{"classifierInfo[ETH_DST]": classifierInfo[EthDst].([]uint8)})
+ } else if field.Type == flows.ETH_SRC {
+ classifierInfo[EthSrc] = field.GetEthSrc()
+ logger.Debug(ctx, "field-type-eth-src", log.Fields{"classifierInfo[ETH_SRC]": classifierInfo[EthSrc].([]uint8)})
} else if field.Type == flows.IP_PROTO {
classifierInfo[IPProto] = field.GetIpProto()
logger.Debug(ctx, "field-type-ip-proto", log.Fields{"classifierInfo[IP_PROTO]": classifierInfo[IPProto].(uint32)})