initial add - go fmt on grpc

Change-Id: Ib0afadd2fe5571d1456a091f94f5644458f7d3f4
diff --git a/openflow/flowMod.go b/openflow/flowMod.go
new file mode 100644
index 0000000..37e6864
--- /dev/null
+++ b/openflow/flowMod.go
@@ -0,0 +1,283 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package openflow
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/opencord/voltha-protos/go/openflow_13"
+	pb "github.com/opencord/voltha-protos/go/voltha"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+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,
+}
+
+func handleFlowAdd(flowAdd *ofp.FlowAdd, deviceId string) {
+	js, _ := json.Marshal(flowAdd)
+	log.Printf("handleFlowAdd called with %s", js)
+
+	var flowUpdate openflow_13.FlowTableUpdate
+	flowUpdate.Id = deviceId
+	var flowMod pb.OfpFlowMod
+	flowMod.Cookie = flowAdd.Cookie
+	flowMod.CookieMask = flowAdd.CookieMask
+	flowMod.TableId = uint32(flowAdd.TableId)
+	flowMod.Command = pb.OfpFlowModCommand_OFPFC_ADD
+	flowMod.IdleTimeout = uint32(flowAdd.IdleTimeout)
+	flowMod.HardTimeout = uint32(flowAdd.HardTimeout)
+	flowMod.Priority = uint32(flowAdd.Priority)
+	flowMod.BufferId = flowAdd.BufferId
+	flowMod.OutPort = uint32(flowAdd.OutPort)
+	flowMod.OutGroup = uint32(flowAdd.OutGroup)
+	flowMod.Flags = uint32(flowAdd.Flags)
+	inMatch := flowAdd.Match
+	var flowMatch pb.OfpMatch
+	flowMatch.Type = pb.OfpMatchType(inMatch.GetType())
+	var oxmList []*pb.OfpOxmField
+	inOxmList := inMatch.GetOxmList()
+	for i := 0; i < len(inOxmList); i++ {
+		oxmField := inOxmList[i]
+		j, _ := json.Marshal(oxmField)
+
+		name := oxmMap[oxmField.GetOXMName()]
+		log.Printf("\n\n\n %s  %d  %s\n\n\n", j, name, oxmField.GetOXMName())
+
+		val := oxmField.GetOXMValue()
+		var ofpOxmField pb.OfpOxmField
+		ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
+		var field pb.OfpOxmOfbField
+
+		field.Type = pb.OxmOfbFieldTypes(name)
+		log.Println("****\nFieldType: " + openflow_13.OxmOfbFieldTypes_name[name] + "\n\n\n\n")
+
+		var x openflow_13.OfpOxmField_OfbField
+		x.OfbField = &field
+		ofpOxmField.Field = &x
+
+		switch pb.OxmOfbFieldTypes(name) {
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
+			port := val.(ofp.Port)
+			var value pb.OfpOxmOfbField_Port
+			value.Port = uint32(port)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
+			phyPort := val.(uint32)
+			var value pb.OfpOxmOfbField_PhysicalPort
+			value.PhysicalPort = phyPort
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
+			metadata := val.(uint64)
+			var value pb.OfpOxmOfbField_TableMetadata
+			value.TableMetadata = metadata
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
+			ethType := val.(ofp.EthernetType)
+			var value pb.OfpOxmOfbField_EthType
+			value.EthType = uint32(ethType)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
+			proto := val.(ofp.IpPrototype)
+			var value pb.OfpOxmOfbField_IpProto
+			value.IpProto = uint32(proto)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
+			udpSrc := val.(uint16)
+			var value pb.OfpOxmOfbField_UdpSrc
+			value.UdpSrc = uint32(udpSrc)
+			log.Printf("udpSrc %v", udpSrc)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
+			udpDst := val.(uint16)
+			var value pb.OfpOxmOfbField_UdpDst
+			value.UdpDst = uint32(udpDst)
+			field.Value = &value
+		}
+		oxmList = append(oxmList, &ofpOxmField)
+	}
+	flowMatch.OxmFields = oxmList
+	flowMod.Match = &flowMatch
+	var instructions []*pb.OfpInstruction
+	ofpInstructions := flowAdd.GetInstructions()
+	for i := 0; i < len(ofpInstructions); i++ {
+		var instruction pb.OfpInstruction
+		ofpInstruction := ofpInstructions[i]
+		instructionType := ofpInstruction.GetType()
+		instruction.Type = uint32(instructionType)
+		switch instructionType {
+		case 1:
+			goToTable := ofpInstruction.(ofp.IInstructionGotoTable)
+			var ofpGoToTable openflow_13.OfpInstruction_GotoTable
+			ofpGoToTable.GotoTable.TableId = uint32(goToTable.GetTableId())
+			instruction.Data = &ofpGoToTable
+		case 2:
+			writeMetaData := ofpInstruction.(ofp.IInstructionWriteMetadata)
+			var ofpWriteMetadata openflow_13.OfpInstruction_WriteMetadata
+			ofpWriteMetadata.WriteMetadata.Metadata = writeMetaData.GetMetadata()
+			ofpWriteMetadata.WriteMetadata.MetadataMask = writeMetaData.GetMetadataMask()
+			instruction.Data = &ofpWriteMetadata
+		case 3:
+			writeAction := ofpInstruction.(ofp.IInstructionWriteActions)
+			var ofpInstructionActions openflow_13.OfpInstruction_Actions
+			var ofpActions []*openflow_13.OfpAction
+			actions := writeAction.GetActions()
+			for i := 0; i < len(actions); i++ {
+				action := actions[i]
+				ofpAction := extractAction(action)
+				ofpActions = append(ofpActions, ofpAction)
+			}
+			instruction.Data = &ofpInstructionActions
+		case 4:
+			applyAction := ofpInstruction.(ofp.IInstructionApplyActions)
+			var ofpInstructionActions openflow_13.OfpInstruction_Actions
+			var ofpActions []*openflow_13.OfpAction
+			actions := applyAction.GetActions()
+			for i := 0; i < len(actions); i++ {
+				action := actions[i]
+				ofpAction := extractAction(action)
+				ofpActions = append(ofpActions, ofpAction)
+			}
+			var actionsHolder openflow_13.OfpInstructionActions
+			actionsHolder.Actions = ofpActions
+			ofpInstructionActions.Actions = &actionsHolder
+			instruction.Data = &ofpInstructionActions
+
+		}
+		instructions = append(instructions, &instruction)
+	}
+
+	flowMod.Instructions = instructions
+	flowUpdate.FlowMod = &flowMod
+	grpcClient := *getGrpcClient()
+	flowUpdateJs, _ := json.Marshal(flowUpdate)
+	log.Printf("FLOW UPDATE %s", flowUpdateJs)
+	empty, err := grpcClient.UpdateLogicalDeviceFlowTable(context.Background(), &flowUpdate)
+	if err != nil {
+		log.Printf("ERROR DOING FLOW MOD ADD %v", err)
+	}
+	emptyJs, _ := json.Marshal(empty)
+	log.Printf("FLOW MOD RESPONSE %s", emptyJs)
+
+}
+
+func handleFlowMod(flowMod *ofp.FlowMod, deviceId string) {
+	js, _ := json.Marshal(flowMod)
+	log.Printf("handleFlowMod called with %s", js)
+}
+
+func handleFlowModStrict(flowModStrict *ofp.FlowModifyStrict, deviceId string) {
+	js, _ := json.Marshal(flowModStrict)
+	log.Printf("handleFlowModStrict called with %s", js)
+}
+func handleFlowDelete(flowDelete *ofp.FlowDelete, deviceId string) {
+	js, _ := json.Marshal(flowDelete)
+	log.Printf("handleFlowDelete called with %s", js)
+
+}
+func handleFlowDeleteStrict(flowDeleteStrict *ofp.FlowDeleteStrict, deviceId string) {
+	js, _ := json.Marshal(flowDeleteStrict)
+	log.Printf("handleFlowDeleteStrict called with %s", js)
+
+}
+func extractAction(action ofp.IAction) *openflow_13.OfpAction {
+	var ofpAction openflow_13.OfpAction
+	switch action.GetType() {
+	case 0: // Output
+		var outputAction openflow_13.OfpAction_Output
+		loxiOutputAction := action.(*ofp.ActionOutput)
+		var output openflow_13.OfpActionOutput
+		output.Port = uint32(loxiOutputAction.Port)
+		output.MaxLen = uint32(loxiOutputAction.MaxLen)
+		outputAction.Output = &output
+		ofpAction.Action = &outputAction
+	case 11: //CopyTtlOut
+	case 12: //CopyTtlIn
+	case 15: //SetMplsTtl
+	case 16: //DecMplsTtl
+	case 17: //PushVlan
+		var pushVlan openflow_13.OfpAction_Push
+		loxiPushAction := action.(*ofp.ActionPopVlan)
+		fields := loxiPushAction.GetActionFields()
+		fieldsJS, _ := json.Marshal(fields)
+		log.Printf("\n\nPushVlan fields %s\n\n", fieldsJS)
+		pushVlan.Push.Ethertype = 0x8100 //TODO This should be available in the fields
+		ofpAction.Type = openflow_13.OfpActionType_OFPAT_PUSH_VLAN
+	case 18: //PopVlan
+		ofpAction.Type = openflow_13.OfpActionType_OFPAT_POP_VLAN
+	case 19: //PushMpls
+	case 20: //PopMpls
+	case 21: //SetQueue
+	case 22: //ActionGroup
+	case 23: //SetNwTtl
+	case 24: //DecNwTtl
+	case 25: //SetField
+		var setField openflow_13.OfpAction_SetField
+		loxiSetField := action.(*ofp.ActionSetField)
+		fields := loxiSetField.GetActionFields()
+		fieldsJS, _ := json.Marshal(fields)
+		log.Printf("\n\nSet Fields fields %s\n\n", fieldsJS)
+
+		ofpAction.Action = &setField
+	case 26: //PushPbb
+	case 27: //PopPbb
+	case 65535: //Experimenter
+
+	}
+	return &ofpAction
+
+}