[VOL-4439] Support transparent VLAN at the OLT.
Change-Id: Iac79acb1a380a807ed589c2c48d128a7c3fe891b
diff --git a/VERSION b/VERSION
index ad6abd3..1454f6e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.0.1-dev
+4.0.1
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
index 82c77f6..8699740 100644
--- a/internal/pkg/core/openolt_flowmgr.go
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -968,7 +968,7 @@
}
func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
- flowContext.classifier[PacketTagType] = SingleTag
+ flowContext.classifier[PacketTagType] = SingleTag // FIXME: This hardcoding needs to be removed.
logger.Debugw(ctx, "adding-upstream-data-flow",
log.Fields{
"uplinkClassifier": flowContext.classifier,
@@ -981,7 +981,16 @@
downlinkClassifier := flowContext.classifier
downlinkAction := flowContext.action
- downlinkClassifier[PacketTagType] = DoubleTag
+ // 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
+ }
logger.Debugw(ctx, "adding-downstream-data-flow",
log.Fields{
"downlinkClassifier": downlinkClassifier,
@@ -1003,17 +1012,10 @@
}
}
- /* Already this info available classifier? */
- downlinkAction[PopVlan] = true
// 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
- } else {
- return olterrors.NewErrInvalidValue(log.Fields{
- "reason": "failed-to-convert-vlanid-classifier",
- "vlan-id": VlanVid,
- "device-id": f.deviceHandler.device.Id}, nil).Log()
}
return f.addSymmetricDataPathFlow(ctx, flowContext, Downstream)
@@ -1403,10 +1405,21 @@
classifier.OVid = vid
}
}
+ // The classifierInfo[Metadata] carries the vlan that the OLT see when it receives packet from the ONU
if metadata, ok := classifierInfo[Metadata].(uint64); ok {
vid := uint32(metadata)
- if vid != ReservedVlan {
- classifier.IVid = vid
+ // Set the OVid or IVid classifier based on the whether OLT is using a transparent tag or not
+ // If OLT is using transparent tag mechanism, then it classifies whatever tag it sees to/from ONU which
+ //is OVid from the perspective of the OLT. When OLT also places or pops the outer tag, then classifierInfo[Metadata]
+ // becomes the IVid.
+ if classifier.OVid != 0 && classifier.OVid != ReservedVlan { // This is case when classifier.OVid is not set
+ if vid != ReservedVlan {
+ classifier.IVid = vid
+ }
+ } else {
+ if vid != ReservedVlan {
+ classifier.OVid = vid
+ }
}
}
// Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
@@ -1461,9 +1474,13 @@
}
} else if _, ok := actionInfo[TrapToHost]; ok {
action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
- } else {
- return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
}
+ // When OLT is transparent to vlans no-action is valid.
+ /*
+ else {
+ return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
+ }
+ */
return &action, nil
}
@@ -3029,8 +3046,11 @@
classifierInfo[InPort] = field.GetPort()
logger.Debug(ctx, "field-type-in-port", log.Fields{"classifierInfo[IN_PORT]": classifierInfo[InPort].(uint32)})
} else if field.Type == flows.VLAN_VID {
- classifierInfo[VlanVid] = field.GetVlanVid() & 0xfff
- logger.Debug(ctx, "field-type-vlan-vid", log.Fields{"classifierInfo[VLAN_VID]": classifierInfo[VlanVid].(uint32)})
+ // The ReservedVlan is used to signify transparent vlan. Do not do any classification when we see ReservedVlan
+ if field.GetVlanVid() != ReservedVlan {
+ classifierInfo[VlanVid] = field.GetVlanVid() & 0xfff
+ logger.Debug(ctx, "field-type-vlan-vid", log.Fields{"classifierInfo[VLAN_VID]": classifierInfo[VlanVid].(uint32)})
+ }
} else if field.Type == flows.VLAN_PCP {
classifierInfo[VlanPcp] = field.GetVlanPcp()
logger.Debug(ctx, "field-type-vlan-pcp", log.Fields{"classifierInfo[VLAN_PCP]": classifierInfo[VlanPcp].(uint32)})