func (fastdp *FastDatapath) getVxlanVportID(udpPort int) (odp.VportID, error) { fastdp.lock.Lock() defer fastdp.lock.Unlock() if vxlanVportID, present := fastdp.vxlanVportIDs[udpPort]; present { return vxlanVportID, nil } vxlanVportID, err := fastdp.dp.CreateVport( odp.NewVxlanVportSpec(fmt.Sprintf("vxlan-%d", udpPort), uint16(udpPort))) if err != nil { return 0, err } fastdp.vxlanVportIDs[udpPort] = vxlanVportID fastdp.missHandlers[vxlanVportID] = func(fks odp.FlowKeys, lock *fastDatapathLock) FlowOp { tunnel := fks[odp.OVS_KEY_ATTR_TUNNEL].(odp.TunnelFlowKey) tunKey := tunnel.Key() lock.relock() consumer := fastdp.overlayConsumer if consumer == nil { return vetoFlowCreationFlowOp{} } srcPeer, dstPeer := fastdp.extractPeers(tunKey.TunnelId) if srcPeer == nil || dstPeer == nil { return vetoFlowCreationFlowOp{} } lock.unlock() pk := flowKeysToPacketKey(fks) var zeroMAC MAC if pk.SrcMAC == zeroMAC && pk.DstMAC == zeroMAC { return vxlanSpecialPacketFlowOp{ fastdp: fastdp, srcPeer: srcPeer, sender: &net.UDPAddr{ IP: net.IP(tunKey.Ipv4Src[:]), Port: udpPort, }, } } key := ForwardPacketKey{ SrcPeer: srcPeer, DstPeer: dstPeer, PacketKey: pk, } var tunnelFlowKey odp.TunnelFlowKey tunnelFlowKey.SetTunnelId(tunKey.TunnelId) tunnelFlowKey.SetIpv4Src(tunKey.Ipv4Src) tunnelFlowKey.SetIpv4Dst(tunKey.Ipv4Dst) return NewMultiFlowOp(false, odpFlowKey(tunnelFlowKey), consumer(key)) } return vxlanVportID, nil }
func printSetTunnelOptions(a odp.SetTunnelAction) { var fk odp.TunnelFlowKey if a.Present.TunnelId { fk.SetTunnelId(a.TunnelId) } if a.Present.Ipv4Src { fk.SetIpv4Src(a.Ipv4Src) } if a.Present.Ipv4Dst { fk.SetIpv4Dst(a.Ipv4Dst) } if a.Present.Tos { fk.SetTos(a.Tos) } if a.Present.Ttl { fk.SetTtl(a.Ttl) } if a.Present.Df { fk.SetDf(a.Df) } if a.Present.Csum { fk.SetCsum(a.Csum) } if a.Present.TpSrc { fk.SetTpSrc(a.TpSrc) } if a.Present.TpDst { fk.SetTpDst(a.TpDst) } printTunnelOptions(fk, "set-tunnel-") }
func parseTunnelFlags(tf *tunnelFlags) (odp.TunnelFlowKey, error) { var fk odp.TunnelFlowKey if tf.id != "" { tunnelId, err := parseTunnelId(tf.id) if err != nil { return fk, err } fk.SetTunnelId(tunnelId) } if tf.ipv4Src != "" { addr, err := parseIpv4(tf.ipv4Src) if err != nil { return fk, err } fk.SetIpv4Src(addr) } if tf.ipv4Dst != "" { addr, err := parseIpv4(tf.ipv4Dst) if err != nil { return fk, err } fk.SetIpv4Dst(addr) } if tf.tos >= 0 { fk.SetTos(uint8(tf.tos)) } if tf.ttl >= 0 { fk.SetTtl(uint8(tf.ttl)) } if tf.df != "" { df, err := parseBool(tf.df) if err != nil { return fk, err } fk.SetDf(df) } if tf.csum != "" { csum, err := parseBool(tf.csum) if err != nil { return fk, err } fk.SetCsum(csum) } return fk, nil }
func (fastdp *FastDatapath) getVxlanVportID(udpPort int) (odp.VportID, error) { fastdp.lock.Lock() defer fastdp.lock.Unlock() if vxlanVportID, present := fastdp.vxlanVportIDs[udpPort]; present { return vxlanVportID, nil } name := fmt.Sprintf("vxlan-%d", udpPort) vxlanVportID, err := fastdp.dp.CreateVport( odp.NewVxlanVportSpec(name, uint16(udpPort))) if err != nil { return 0, err } // If a netdev for the vxlan vport exists, we need to do an extra check // to bypass the kernel bug which makes the vxlan creation to complete // successfully regardless whether there were any errors when binding // to the given UDP port. if link, err := netlink.LinkByName(name); err == nil { if link.Attrs().Flags&net.FlagUp == 0 { // The netdev interface is down, so most likely bringing it up // has failed due to the UDP port being in use. if err := fastdp.dp.DeleteVport(vxlanVportID); err != nil { log.Warning("Unable to remove vxlan vport %d: %s", vxlanVportID, err) } return 0, odp.NetlinkError(syscall.EADDRINUSE) } } fastdp.vxlanVportIDs[udpPort] = vxlanVportID fastdp.missHandlers[vxlanVportID] = func(fks odp.FlowKeys, lock *fastDatapathLock) FlowOp { log.Debug("ODP miss: ", fks, " on port ", vxlanVportID) tunnel := fks[odp.OVS_KEY_ATTR_TUNNEL].(odp.TunnelFlowKey) tunKey := tunnel.Key() lock.relock() consumer := fastdp.overlayConsumer if consumer == nil { return vetoFlowCreationFlowOp{} } srcPeer, dstPeer := fastdp.extractPeers(tunKey.TunnelId) if srcPeer == nil || dstPeer == nil { return vetoFlowCreationFlowOp{} } lock.unlock() pk := flowKeysToPacketKey(fks) var zeroMAC MAC if pk.SrcMAC == zeroMAC && pk.DstMAC == zeroMAC { return vxlanSpecialPacketFlowOp{ fastdp: fastdp, srcPeer: srcPeer, sender: &net.UDPAddr{ IP: net.IP(tunKey.Ipv4Src[:]), Port: udpPort, }, } } key := ForwardPacketKey{ SrcPeer: srcPeer, DstPeer: dstPeer, PacketKey: pk, } var tunnelFlowKey odp.TunnelFlowKey tunnelFlowKey.SetTunnelId(tunKey.TunnelId) tunnelFlowKey.SetIpv4Src(tunKey.Ipv4Src) tunnelFlowKey.SetIpv4Dst(tunKey.Ipv4Dst) return NewMultiFlowOp(false, odpFlowKey(tunnelFlowKey), consumer(key)) } return vxlanVportID, nil }