func (fastdp *FastDatapath) Miss(packet []byte, fks odp.FlowKeys) error { ingress := fks[odp.OVS_KEY_ATTR_IN_PORT].(odp.InPortFlowKey).VportID() log.Debug("ODP miss ", fks, " on port ", ingress) lock := fastdp.startLock() defer lock.unlock() handler := fastdp.getMissHandler(ingress) if handler == nil { return nil } // Always include the ingress vport in the flow key. While // this is not strictly necessary in some cases (e.g. for // delivery to a local netdev based on the dest MAC), // including the ingress in every flow makes things simpler // in touchFlow. mfop := NewMultiFlowOp(false, handler(fks, &lock), odpFlowKey(odp.NewInPortFlowKey(ingress))) fastdp.send(mfop, packet, &lock) return nil }
func flagsToFlowSpec(f Flags, dpif *odp.Dpif) (dp odp.DatapathHandle, flow odp.FlowSpec, ok bool) { flow = odp.NewFlowSpec() var inPort string f.StringVar(&inPort, "in-port", "", "key: incoming vport") var ethSrc, ethDst string f.StringVar(ðSrc, "eth-src", "", "key: ethernet source MAC") f.StringVar(ðDst, "eth-dst", "", "key: ethernet destination MAC") var tun tunnelFlags addTunnelFlags(f, &tun, "tunnel-", "tunnel ") var setTun tunnelFlags addTunnelFlags(f, &setTun, "set-tunnel-", "action: set tunnel ") var output string f.StringVar(&output, "output", "", "action: output to vports") args := f.Parse(1, 1) dpp, _ := lookupDatapath(dpif, args[0]) if dpp == nil { return } if inPort != "" { vport, err := dpp.LookupVportByName(inPort) if err != nil { printErr("%s", err) return } flow.AddKey(odp.NewInPortFlowKey(vport.ID)) } // The ethernet flow key is mandatory err := handleEthernetFlowKeyOptions(flow, ethSrc, ethDst) if err != nil { printErr("%s", err) return } flowKey, err := parseTunnelFlags(&tun) if err != nil { printErr("%s", err) return } if !flowKey.Ignored() { flow.AddKey(flowKey) } // Actions are ordered, but flags aren't. As a temporary // hack, we already put SET actions before an OUTPUT action. setTunAttrs, err := parseSetTunnelFlags(&setTun) if err != nil { printErr("%s", err) return } if setTunAttrs != nil { flow.AddAction(*setTunAttrs) } if output != "" { for _, vpname := range strings.Split(output, ",") { vport, err := dpp.LookupVportByName(vpname) if err != nil { printErr("%s", err) return } flow.AddAction(odp.NewOutputAction(vport.ID)) } } return *dpp, flow, true }