示例#1
0
文件: fastdp.go 项目: thinkingo/weave
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
}
示例#2
0
文件: main.go 项目: awh/go-odp
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(&ethSrc, "eth-src", "", "key: ethernet source MAC")
	f.StringVar(&ethDst, "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
}