// Install all flow actions func (self *Flow) installFlowActions(flowMod *openflow13.FlowMod, instr openflow13.Instruction) error { var actInstr openflow13.Instruction var addActn bool = false // Create a apply_action instruction to be used if its not already created switch instr.(type) { case *openflow13.InstrActions: actInstr = instr default: actInstr = openflow13.NewInstrApplyActions() } // Loop thru all actions for _, flowAction := range self.flowActions { switch flowAction.actionType { case "setVlan": // Push Vlan Tag action pushVlanAction := openflow13.NewActionPushVlan(0x8100) // Set Outer vlan tag field vlanField := openflow13.NewVlanIdField(flowAction.vlanId, nil) setVlanAction := openflow13.NewActionSetField(*vlanField) // Prepend push vlan & setvlan actions to existing instruction actInstr.AddAction(setVlanAction, true) actInstr.AddAction(pushVlanAction, true) addActn = true log.Debugf("flow install. Added pushvlan action: %+v, setVlan actions: %+v", pushVlanAction, setVlanAction) case "popVlan": // Create pop vln action popVlan := openflow13.NewActionPopVlan() // Add it to instruction actInstr.AddAction(popVlan, true) addActn = true log.Debugf("flow install. Added popVlan action: %+v", popVlan) case "setMacDa": // Set Outer MacDA field macDaField := openflow13.NewEthDstField(flowAction.macAddr, nil) setMacDaAction := openflow13.NewActionSetField(*macDaField) // Add set macDa action to the instruction actInstr.AddAction(setMacDaAction, true) addActn = true log.Debugf("flow install. Added setMacDa action: %+v", setMacDaAction) case "setMacSa": // Set Outer MacSA field macSaField := openflow13.NewEthSrcField(flowAction.macAddr, nil) setMacSaAction := openflow13.NewActionSetField(*macSaField) // Add set macDa action to the instruction actInstr.AddAction(setMacSaAction, true) addActn = true log.Debugf("flow install. Added setMacSa Action: %+v", setMacSaAction) case "setTunnelId": // Set tunnelId field tunnelIdField := openflow13.NewTunnelIdField(flowAction.tunnelId) setTunnelAction := openflow13.NewActionSetField(*tunnelIdField) // Add set tunnel action to the instruction actInstr.AddAction(setTunnelAction, true) addActn = true log.Debugf("flow install. Added setTunnelId Action: %+v", setTunnelAction) case "setMetadata": // Set Metadata instruction metadataInstr := openflow13.NewInstrWriteMetadata(flowAction.metadata, flowAction.metadataMask) // Add the instruction to flowmod flowMod.AddInstruction(metadataInstr) case "setIPSa": // Set IP src ipSaField := openflow13.NewIpv4SrcField(flowAction.ipAddr, nil) setIPSaAction := openflow13.NewActionSetField(*ipSaField) // Add set action to the instruction actInstr.AddAction(setIPSaAction, true) addActn = true log.Debugf("flow install. Added setIPSa Action: %+v", setIPSaAction) case "setIPDa": // Set IP dst ipDaField := openflow13.NewIpv4DstField(flowAction.ipAddr, nil) setIPDaAction := openflow13.NewActionSetField(*ipDaField) // Add set action to the instruction actInstr.AddAction(setIPDaAction, true) addActn = true log.Debugf("flow install. Added setIPDa Action: %+v", setIPDaAction) case "setDscp": // Set DSCP field ipDscpField := openflow13.NewIpDscpField(flowAction.dscp) setIPDscpAction := openflow13.NewActionSetField(*ipDscpField) // Add set action to the instruction actInstr.AddAction(setIPDscpAction, true) addActn = true log.Debugf("flow install. Added setDscp Action: %+v", setIPDscpAction) case "setTCPSrc": // Set TCP src tcpSrcField := openflow13.NewTcpSrcField(flowAction.l4Port) setTCPSrcAction := openflow13.NewActionSetField(*tcpSrcField) // Add set action to the instruction actInstr.AddAction(setTCPSrcAction, true) addActn = true log.Debugf("flow install. Added setTCPSrc Action: %+v", setTCPSrcAction) case "setTCPDst": // Set TCP dst tcpDstField := openflow13.NewTcpDstField(flowAction.l4Port) setTCPDstAction := openflow13.NewActionSetField(*tcpDstField) // Add set action to the instruction actInstr.AddAction(setTCPDstAction, true) addActn = true log.Debugf("flow install. Added setTCPDst Action: %+v", setTCPDstAction) case "setUDPSrc": // Set UDP src udpSrcField := openflow13.NewUdpSrcField(flowAction.l4Port) setUDPSrcAction := openflow13.NewActionSetField(*udpSrcField) // Add set action to the instruction actInstr.AddAction(setUDPSrcAction, true) addActn = true log.Debugf("flow install. Added setUDPSrc Action: %+v", setUDPSrcAction) case "setUDPDst": // Set UDP dst udpDstField := openflow13.NewUdpDstField(flowAction.l4Port) setUDPDstAction := openflow13.NewActionSetField(*udpDstField) // Add set action to the instruction actInstr.AddAction(setUDPDstAction, true) addActn = true log.Debugf("flow install. Added setUDPDst Action: %+v", setUDPDstAction) default: log.Fatalf("Unknown action type %s", flowAction.actionType) } } // Add the instruction to flow if its not already added if (addActn) && (actInstr != instr) { // Add the instrction to flowmod flowMod.AddInstruction(actInstr) } return nil }
// Translate our match fields into openflow 1.3 match fields func (self *Flow) xlateMatch() openflow13.Match { ofMatch := openflow13.NewMatch() // Handle input poty if self.Match.InputPort != 0 { inportField := openflow13.NewInPortField(self.Match.InputPort) ofMatch.AddField(*inportField) } // Handle mac DA field if self.Match.MacDa != nil { if self.Match.MacDaMask != nil { macDaField := openflow13.NewEthDstField(*self.Match.MacDa, self.Match.MacDaMask) ofMatch.AddField(*macDaField) } else { macDaField := openflow13.NewEthDstField(*self.Match.MacDa, nil) ofMatch.AddField(*macDaField) } } // Handle MacSa field if self.Match.MacSa != nil { if self.Match.MacSaMask != nil { macSaField := openflow13.NewEthSrcField(*self.Match.MacSa, self.Match.MacSaMask) ofMatch.AddField(*macSaField) } else { macSaField := openflow13.NewEthSrcField(*self.Match.MacSa, nil) ofMatch.AddField(*macSaField) } } // Handle ethertype if self.Match.Ethertype != 0 { etypeField := openflow13.NewEthTypeField(self.Match.Ethertype) ofMatch.AddField(*etypeField) } // Handle Vlan id if self.Match.VlanId != 0 { vidField := openflow13.NewVlanIdField(self.Match.VlanId) ofMatch.AddField(*vidField) } // Handle IP Dst if self.Match.IpDa != nil { if self.Match.IpDaMask != nil { ipDaField := openflow13.NewIpv4DstField(*self.Match.IpDa, self.Match.IpDaMask) ofMatch.AddField(*ipDaField) } else { ipDaField := openflow13.NewIpv4DstField(*self.Match.IpDa, nil) ofMatch.AddField(*ipDaField) } } // Handle IP Src if self.Match.IpSa != nil { if self.Match.IpSaMask != nil { ipSaField := openflow13.NewIpv4SrcField(*self.Match.IpSa, self.Match.IpSaMask) ofMatch.AddField(*ipSaField) } else { ipSaField := openflow13.NewIpv4SrcField(*self.Match.IpSa, nil) ofMatch.AddField(*ipSaField) } } // Handle IP protocol if self.Match.IpProto != 0 { protoField := openflow13.NewIpProtoField(self.Match.IpProto) ofMatch.AddField(*protoField) } // Handle port numbers if self.Match.IpProto == IP_PROTO_TCP && self.Match.TcpSrcPort != 0 { portField := openflow13.NewTcpSrcField(self.Match.TcpSrcPort) ofMatch.AddField(*portField) } if self.Match.IpProto == IP_PROTO_TCP && self.Match.TcpDstPort != 0 { portField := openflow13.NewTcpDstField(self.Match.TcpDstPort) ofMatch.AddField(*portField) } if self.Match.IpProto == IP_PROTO_UDP && self.Match.UdpSrcPort != 0 { portField := openflow13.NewUdpSrcField(self.Match.UdpSrcPort) ofMatch.AddField(*portField) } if self.Match.IpProto == IP_PROTO_UDP && self.Match.UdpDstPort != 0 { portField := openflow13.NewUdpDstField(self.Match.UdpDstPort) ofMatch.AddField(*portField) } // Handle metadata if self.Match.Metadata != nil { if self.Match.MetadataMask != nil { metadataField := openflow13.NewMetadataField(*self.Match.Metadata, self.Match.MetadataMask) ofMatch.AddField(*metadataField) } else { metadataField := openflow13.NewMetadataField(*self.Match.Metadata, nil) ofMatch.AddField(*metadataField) } } // Handle Vxlan tunnel id if self.Match.TunnelId != 0 { tunnelIdField := openflow13.NewTunnelIdField(self.Match.TunnelId) ofMatch.AddField(*tunnelIdField) } return *ofMatch }
// Translate our match fields into openflow 1.3 match fields func (self *Flow) xlateMatch() openflow13.Match { ofMatch := openflow13.NewMatch() // Handle input poty if self.Match.InputPort != 0 { inportField := openflow13.NewInPortField(self.Match.InputPort) ofMatch.AddField(*inportField) } // Handle mac DA field if self.Match.MacDa != nil { if self.Match.MacDaMask != nil { macDaField := openflow13.NewEthDstField(*self.Match.MacDa, self.Match.MacDaMask) ofMatch.AddField(*macDaField) } else { macDaField := openflow13.NewEthDstField(*self.Match.MacDa, nil) ofMatch.AddField(*macDaField) } } // Handle MacSa field if self.Match.MacSa != nil { if self.Match.MacSaMask != nil { macSaField := openflow13.NewEthSrcField(*self.Match.MacSa, self.Match.MacSaMask) ofMatch.AddField(*macSaField) } else { macSaField := openflow13.NewEthSrcField(*self.Match.MacSa, nil) ofMatch.AddField(*macSaField) } } // Handle ethertype if self.Match.Ethertype != 0 { etypeField := openflow13.NewEthTypeField(self.Match.Ethertype) ofMatch.AddField(*etypeField) } // Handle Vlan id if self.Match.VlanId != 0 { if self.Match.VlanIdMask != nil { vidField := openflow13.NewVlanIdField(self.Match.VlanId, self.Match.VlanIdMask) ofMatch.AddField(*vidField) } else { vidField := openflow13.NewVlanIdField(self.Match.VlanId, nil) ofMatch.AddField(*vidField) } } // Handle MPLS Label -SRTE if self.Match.MplsLabel != 0 { mplsLabelField := openflow13.NewMplsLabelField(self.Match.MplsLabel) ofMatch.AddField(*mplsLabelField) } // Handle MPLS Bos -SRTE if self.Match.MplsBos != 0 { mplsBosField := openflow13.NewMplsBosField(self.Match.MplsBos) ofMatch.AddField(*mplsBosField) } // Handle ARP Oper type if self.Match.ArpOper != 0 { arpOperField := openflow13.NewArpOperField(self.Match.ArpOper) ofMatch.AddField(*arpOperField) } // Handle IP Dst if self.Match.IpDa != nil { if self.Match.IpDaMask != nil { ipDaField := openflow13.NewIpv4DstField(*self.Match.IpDa, self.Match.IpDaMask) ofMatch.AddField(*ipDaField) } else { ipDaField := openflow13.NewIpv4DstField(*self.Match.IpDa, nil) ofMatch.AddField(*ipDaField) } } // Handle IP Src if self.Match.IpSa != nil { if self.Match.IpSaMask != nil { ipSaField := openflow13.NewIpv4SrcField(*self.Match.IpSa, self.Match.IpSaMask) ofMatch.AddField(*ipSaField) } else { ipSaField := openflow13.NewIpv4SrcField(*self.Match.IpSa, nil) ofMatch.AddField(*ipSaField) } } // Handle IPv6 Dst if self.Match.Ipv6Da != nil { if self.Match.Ipv6DaMask != nil { ipv6DaField := openflow13.NewIpv6DstField(*self.Match.Ipv6Da, self.Match.Ipv6DaMask) ofMatch.AddField(*ipv6DaField) } else { ipv6DaField := openflow13.NewIpv6DstField(*self.Match.Ipv6Da, nil) ofMatch.AddField(*ipv6DaField) } } // Handle IPv6 Src if self.Match.Ipv6Sa != nil { if self.Match.Ipv6SaMask != nil { ipv6SaField := openflow13.NewIpv6SrcField(*self.Match.Ipv6Sa, self.Match.Ipv6SaMask) ofMatch.AddField(*ipv6SaField) } else { ipv6SaField := openflow13.NewIpv6SrcField(*self.Match.Ipv6Sa, nil) ofMatch.AddField(*ipv6SaField) } } // Handle IP protocol if self.Match.IpProto != 0 { protoField := openflow13.NewIpProtoField(self.Match.IpProto) ofMatch.AddField(*protoField) } // Handle port numbers if self.Match.IpProto == IP_PROTO_TCP && self.Match.TcpSrcPort != 0 { portField := openflow13.NewTcpSrcField(self.Match.TcpSrcPort) ofMatch.AddField(*portField) } if self.Match.IpProto == IP_PROTO_TCP && self.Match.TcpDstPort != 0 { portField := openflow13.NewTcpDstField(self.Match.TcpDstPort) ofMatch.AddField(*portField) } if self.Match.IpProto == IP_PROTO_UDP && self.Match.UdpSrcPort != 0 { portField := openflow13.NewUdpSrcField(self.Match.UdpSrcPort) ofMatch.AddField(*portField) } if self.Match.IpProto == IP_PROTO_UDP && self.Match.UdpDstPort != 0 { portField := openflow13.NewUdpDstField(self.Match.UdpDstPort) ofMatch.AddField(*portField) } // Handle tcp flags if self.Match.IpProto == IP_PROTO_TCP && self.Match.TcpFlags != nil { tcpFlagField := openflow13.NewTcpFlagsField(*self.Match.TcpFlags, self.Match.TcpFlagsMask) ofMatch.AddField(*tcpFlagField) } // Handle metadata if self.Match.Metadata != nil { if self.Match.MetadataMask != nil { metadataField := openflow13.NewMetadataField(*self.Match.Metadata, self.Match.MetadataMask) ofMatch.AddField(*metadataField) } else { metadataField := openflow13.NewMetadataField(*self.Match.Metadata, nil) ofMatch.AddField(*metadataField) } } // Handle Vxlan tunnel id if self.Match.TunnelId != 0 { tunnelIdField := openflow13.NewTunnelIdField(self.Match.TunnelId) ofMatch.AddField(*tunnelIdField) } return *ofMatch }