VOL-3347 GEM ports kept for packet-outs should be in pon-onu-uni-vlan-pbit basis instead of per pon-onu-uni basis.
Change-Id: I7e9ca29295d28d97908a99ba8c34c4c9b52046c4
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
index 520ee7a..f2fec23 100644
--- a/internal/pkg/core/openolt_flowmgr.go
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -3045,7 +3045,7 @@
logicalPortNum = MkUniPortNum(ctx, packetIn.IntfId, onuID, uniID)
}
// Store the gem port through which the packet_in came. Use the same gem port for packet_out
- f.UpdateGemPortForPktIn(ctx, packetIn.IntfId, onuID, logicalPortNum, packetIn.GemportId)
+ f.UpdateGemPortForPktIn(ctx, packetIn.IntfId, onuID, logicalPortNum, packetIn.GemportId, packetIn.Pkt)
} else if packetIn.IntfType == "nni" {
logicalPortNum = IntfIDToPortNo(packetIn.IntfId, voltha.Port_ETHERNET_NNI)
}
@@ -3059,13 +3059,17 @@
}
//GetPacketOutGemPortID returns gemPortId
-func (f *OpenOltFlowMgr) GetPacketOutGemPortID(ctx context.Context, intfID uint32, onuID uint32, portNum uint32) (uint32, error) {
+func (f *OpenOltFlowMgr) GetPacketOutGemPortID(ctx context.Context, intfID uint32, onuID uint32, portNum uint32, packet []byte) (uint32, error) {
var gemPortID uint32
- var err error
+
+ ctag, priority, err := getCTagFromPacket(ctx, packet)
+ if err != nil {
+ return 0, err
+ }
f.onuGemInfoLock.RLock()
defer f.onuGemInfoLock.RUnlock()
- pktInkey := rsrcMgr.PacketInInfoKey{IntfID: intfID, OnuID: onuID, LogicalPort: portNum}
+ pktInkey := rsrcMgr.PacketInInfoKey{IntfID: intfID, OnuID: onuID, LogicalPort: portNum, VlanID: ctag, Priority: priority}
var ok bool
gemPortID, ok = f.packetInGemPort[pktInkey]
if ok {
@@ -3077,7 +3081,7 @@
return gemPortID, nil
}
//If gem is not found in cache try to get it from kv store, if found in kv store, update the cache and return.
- gemPortID, err = f.resourceMgr.GetGemPortFromOnuPktIn(ctx, intfID, onuID, portNum)
+ gemPortID, err = f.resourceMgr.GetGemPortFromOnuPktIn(ctx, pktInkey)
if err == nil {
if gemPortID != 0 {
f.packetInGemPort[pktInkey] = gemPortID
@@ -3818,12 +3822,18 @@
}
// UpdateGemPortForPktIn updates gemport for packet-in in to the cache and to the kv store as well.
-func (f *OpenOltFlowMgr) UpdateGemPortForPktIn(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32, gemPort uint32) {
+func (f *OpenOltFlowMgr) UpdateGemPortForPktIn(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32, gemPort uint32, pkt []byte) {
+ cTag, priority, err := getCTagFromPacket(ctx, pkt)
+ if err != nil {
+ logger.Errorw(ctx, "unable-to-update-gem-port-for-packet-in",
+ log.Fields{"intfID": intfID, "onuID": onuID, "logicalPort": logicalPort, "gemPort": gemPort, "err": err})
+ return
+ }
+ pktInkey := rsrcMgr.PacketInInfoKey{IntfID: intfID, OnuID: onuID, LogicalPort: logicalPort, VlanID: cTag, Priority: priority}
f.onuGemInfoLock.Lock()
defer f.onuGemInfoLock.Unlock()
- pktInkey := rsrcMgr.PacketInInfoKey{IntfID: intfID, OnuID: onuID, LogicalPort: logicalPort}
lookupGemPort, ok := f.packetInGemPort[pktInkey]
if ok {
if lookupGemPort == gemPort {
@@ -3845,6 +3855,33 @@
}
+//getCTagFromPacket retrieves and returns c-tag and priority value from a packet.
+func getCTagFromPacket(ctx context.Context, packet []byte) (uint16, uint8, error) {
+ if packet == nil || len(packet) < 18 {
+ log.Error("unable-get-c-tag-from-the-packet--invalid-packet-length ")
+ return 0, 0, errors.New("invalid packet length")
+ }
+ outerEthType := (uint16(packet[12]) << 8) | uint16(packet[13])
+ innerEthType := (uint16(packet[16]) << 8) | uint16(packet[17])
+
+ var index int8
+ if outerEthType == 0x8100 {
+ if innerEthType == 0x8100 {
+ // q-in-q 802.1ad or 802.1q double tagged packet.
+ // get the inner vlanId
+ index = 18
+ } else {
+ index = 14
+ }
+ priority := (packet[index] >> 5) & 0x7
+ //13 bits composes vlanId value
+ vlan := ((uint16(packet[index]) << 8) & 0x0fff) | uint16(packet[index+1])
+ return vlan, priority, nil
+ }
+ logger.Debugf(ctx, "No vlanId found in the packet. Returning zero as c-tag")
+ return 0, 0, nil
+}
+
// AddUniPortToOnuInfo adds uni port to the onugem info both in cache and kvstore.
func (f *OpenOltFlowMgr) AddUniPortToOnuInfo(ctx context.Context, intfID uint32, onuID uint32, portNum uint32) {