[VOL-2552][VOL-2517] Handling 4096 as transaprent VLAN

Change-Id: I537f7a374b3f25b4c077b9088088f44aac92cd74
diff --git a/VERSION b/VERSION
index 13c0078..45a1b3f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1.2-dev
+1.1.2
diff --git a/internal/pkg/openflow/flowMod.go b/internal/pkg/openflow/flowMod.go
index 4ab1afc..da4fc1d 100644
--- a/internal/pkg/openflow/flowMod.go
+++ b/internal/pkg/openflow/flowMod.go
@@ -26,46 +26,47 @@
 )
 
 var oxmMap = map[string]int32{
-	"in_port":        0,
-	"in_phy_port":    1,
-	"metadata":       2,
-	"eth_dst":        3,
-	"eth_src":        4,
-	"eth_type":       5,
-	"vlan_vid":       6,
-	"vlan_pcp":       7,
-	"ip_dscp":        8,
-	"ip_ecn":         9,
-	"ip_proto":       10,
-	"ipv4_src":       11,
-	"ipv4_dst":       12,
-	"tcp_src":        13,
-	"tcp_dst":        14,
-	"udp_src":        15,
-	"udp_dst":        16,
-	"sctp_src":       17,
-	"sctp_dst":       18,
-	"icmpv4_type":    19,
-	"icmpv4_code":    20,
-	"arp_op":         21,
-	"arp_spa":        22,
-	"arp_tpa":        23,
-	"arp_sha":        24,
-	"arp_tha":        25,
-	"ipv6_src":       26,
-	"ipv6_dst":       27,
-	"ipv6_flabel":    28,
-	"icmpv6_type":    29,
-	"icmpv6_code":    30,
-	"ipv6_nd_target": 31,
-	"ipv6_nd_sll":    32,
-	"ipv6_nd_tll":    33,
-	"mpls_label":     34,
-	"mpls_tc":        35,
-	"mpls_bos":       36,
-	"pbb_isid":       37,
-	"tunnel_id":      38,
-	"ipv6_exthdr":    39,
+	"in_port":         0,
+	"in_phy_port":     1,
+	"metadata":        2,
+	"eth_dst":         3,
+	"eth_src":         4,
+	"eth_type":        5,
+	"vlan_vid":        6,
+	"vlan_pcp":        7,
+	"ip_dscp":         8,
+	"ip_ecn":          9,
+	"ip_proto":        10,
+	"ipv4_src":        11,
+	"ipv4_dst":        12,
+	"tcp_src":         13,
+	"tcp_dst":         14,
+	"udp_src":         15,
+	"udp_dst":         16,
+	"sctp_src":        17,
+	"sctp_dst":        18,
+	"icmpv4_type":     19,
+	"icmpv4_code":     20,
+	"arp_op":          21,
+	"arp_spa":         22,
+	"arp_tpa":         23,
+	"arp_sha":         24,
+	"arp_tha":         25,
+	"ipv6_src":        26,
+	"ipv6_dst":        27,
+	"ipv6_flabel":     28,
+	"icmpv6_type":     29,
+	"icmpv6_code":     30,
+	"ipv6_nd_target":  31,
+	"ipv6_nd_sll":     32,
+	"ipv6_nd_tll":     33,
+	"mpls_label":      34,
+	"mpls_tc":         35,
+	"mpls_bos":        36,
+	"pbb_isid":        37,
+	"tunnel_id":       38,
+	"ipv6_exthdr":     39,
+	"vlan_vid_masked": 200, //made up
 }
 
 func (ofc *OFClient) handleFlowAdd(flowAdd *ofp.FlowAdd) {
@@ -126,6 +127,20 @@
 			field.Value = &voltha.OfpOxmOfbField_VlanVid{
 				VlanVid: uint32((val.(uint16) & 0xfff) | 0x1000),
 			}
+		case 200: // voltha-protos doesn't actually have a type for vlan_mask
+			field = voltha.OfpOxmOfbField{Type: voltha.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
+			field.HasMask = true
+			ofpOxmField = voltha.OfpOxmField{
+				OxmClass: ofp.OFPXMCOpenflowBasic,
+				Field:    &openflow_13.OfpOxmField_OfbField{OfbField: &field},
+			}
+			field.Value = &voltha.OfpOxmOfbField_VlanVid{
+				VlanVid: uint32(val.(uint16)),
+			}
+			vidMask := val.(uint16)
+			field.Mask = &voltha.OfpOxmOfbField_VlanVidMask{
+				VlanVidMask: uint32(vidMask),
+			}
 		}
 		oxmList = append(oxmList, &ofpOxmField)
 	}
@@ -207,6 +222,7 @@
 		logger.Debugf("FlowUpdate being sent to Voltha",
 			log.Fields{
 				"device-id":        ofc.DeviceID,
+				"flow-mod-object":  flowUpdate,
 				"flow-mod-request": flowUpdateJs})
 	}
 	if _, err := ofc.VolthaClient.UpdateLogicalDeviceFlowTable(context.Background(), &flowUpdate); err != nil {
@@ -316,7 +332,22 @@
 			field.Value = &voltha.OfpOxmOfbField_VlanVid{
 				VlanVid: uint32(val.(uint16)),
 			}
+		case 200: // voltha-protos doesn't actually have a type for vlan_mask
+			field = voltha.OfpOxmOfbField{Type: voltha.OxmOfbFieldTypes(oxmMap["vlan_vid"])}
+			field.HasMask = true
+			ofpOxmField = voltha.OfpOxmField{
+				OxmClass: ofp.OFPXMCOpenflowBasic,
+				Field:    &openflow_13.OfpOxmField_OfbField{OfbField: &field},
+			}
+			field.Value = &voltha.OfpOxmOfbField_VlanVid{
+				VlanVid: uint32(val.(uint16)),
+			}
+			vidMask := val.(uint16)
+			field.Mask = &voltha.OfpOxmOfbField_VlanVidMask{
+				VlanVidMask: uint32(vidMask),
+			}
 		}
+
 		oxmList = append(oxmList, &ofpOxmField)
 	}
 
diff --git a/internal/pkg/openflow/parseGrpcReturn.go b/internal/pkg/openflow/parseGrpcReturn.go
index 0ee2cec..a5bd1d1 100644
--- a/internal/pkg/openflow/parseGrpcReturn.go
+++ b/internal/pkg/openflow/parseGrpcReturn.go
@@ -67,12 +67,26 @@
 	case voltha.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
 		ofpVlanVid := ofp.NewOxmVlanVid()
 		val := ofbField.GetValue()
-		if val != nil {
-			vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
-			ofpVlanVid.Value = uint16(vlanId.VlanVid) | 0x1000
-		} else {
+		if val == nil {
 			ofpVlanVid.Value = uint16(0)
+			return ofpVlanVid, 2
 		}
+		vlanId := val.(*openflow_13.OfpOxmOfbField_VlanVid)
+		if ofbField.HasMask {
+			ofpVlanVidMasked := ofp.NewOxmVlanVidMasked()
+			valMask := ofbField.GetMask()
+			vlanMask := valMask.(*openflow_13.OfpOxmOfbField_VlanVidMask)
+			if vlanId.VlanVid == 4096 && vlanMask.VlanVidMask == 4096 {
+				ofpVlanVidMasked.Value = uint16(vlanId.VlanVid)
+				ofpVlanVidMasked.ValueMask = uint16(vlanMask.VlanVidMask)
+			} else {
+				ofpVlanVidMasked.Value = uint16(vlanId.VlanVid) | 0x1000
+				ofpVlanVidMasked.ValueMask = uint16(vlanMask.VlanVidMask)
+
+			}
+			return ofpVlanVidMasked, 4
+		}
+		ofpVlanVid.Value = uint16(vlanId.VlanVid) | 0x1000
 		return ofpVlanVid, 2
 	case voltha.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
 		ofpMetadata := ofp.NewOxmMetadata()
diff --git a/internal/pkg/openflow/stats.go b/internal/pkg/openflow/stats.go
index 613b476..520b5a2 100644
--- a/internal/pkg/openflow/stats.go
+++ b/internal/pkg/openflow/stats.go
@@ -67,9 +67,10 @@
 			resJs, _ := json.Marshal(response)
 			logger.Debugw("handle-stats-request-flow",
 				log.Fields{
-					"device-id": ofc.DeviceID,
-					"request":   reqJs,
-					"response":  resJs})
+					"device-id":       ofc.DeviceID,
+					"request":         reqJs,
+					"response-object": response,
+					"response":        resJs})
 		}
 		return ofc.SendMessage(response)