Esempio n. 1
0
func confirmFlowEntryForPath(flow nom.FlowEntry, ctx bh.RcvContext) error {
	d := ctx.Dict(dictPath)

	v, err := d.Get(flow.ID)
	if err != nil {
		return fmt.Errorf("path: flow not found: %v", err)
	}

	pf := v.(pathAndFlows)

	for i := range pf.Flows {
		if pf.Flows[i].Flow.Equals(flow) {
			if pf.Flows[i].Installed {
				return fmt.Errorf("%v is already installed", flow)
			}
			pf.Flows[i].Installed = true
			pf.Installed++
			break
		}
	}

	if pf.Installed == len(pf.Flows) {
		ctx.SendToCell(nom.PathAdded{Path: pf.Path}, pf.Subscriber.App,
			pf.Subscriber.Cell())
	}
	return d.Put(flow.ID, pf)
}
Esempio n. 2
0
func (h addFlowHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	add := msg.Data().(nom.AddFlowEntry)
	var nf nodeFlows
	if v, err := ctx.Dict(flowsDict).Get(string(add.Flow.Node)); err == nil {
		nf = v.(nodeFlows)
	}
	added := nom.FlowEntryAdded{Flow: add.Flow}
	if nf.maybeAddFlow(add) {
		ctx.Emit(added)
		sendToMaster(add, add.Flow.Node, ctx)
	}
	if !add.Subscriber.IsNil() {
		ctx.SendToCell(added, add.Subscriber.App, add.Subscriber.Cell())
	}
	return ctx.Dict(flowsDict).Put(string(add.Flow.Node), nf)
}
Esempio n. 3
0
func (c Consolidator) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	res := msg.Data().(nom.FlowStatsQueryResult)
	var nf nodeFlows
	if v, err := ctx.Dict(flowsDict).Get(string(res.Node)); err == nil {
		nf = v.(nodeFlows)
	}
	var nt nodeTriggers
	if v, err := ctx.Dict(triggersDict).Get(string(res.Node)); err == nil {
		nt = v.(nodeTriggers)
	}
	found := false
	matchedFlows := make(map[int]struct{})
	for _, stat := range res.Stats {
		for i := range nf.Flows {
			if nf.Flows[i].FlowEntry.Match.Equals(stat.Match) {
				found = true
				matchedFlows[i] = struct{}{}
				nf.Flows[i].updateStats(stat)
			}
		}
		if !found {
			nf.Flows = append(nf.Flows, flow{
				FlowEntry: nom.FlowEntry{
					Match: stat.Match,
				},
				Duration: stat.Duration,
				Packets:  stat.Packets,
				Bytes:    stat.Bytes,
			})
			// TODO(soheil): emit flow entry here.
		}

		for _, t := range nt.Triggers {
			if t.Fired(stat) {
				triggered := newTriggered(t, stat.Duration, stat.BW())
				sub := t.Subscriber
				if !sub.IsNil() {
					ctx.SendToCell(triggered, sub.App, sub.Cell())
				}
			}
		}
	}

	count := 0
	for i, f := range nf.Flows {
		if _, ok := matchedFlows[i]; ok {
			continue
		}

		i -= count
		nf.Flows = append(nf.Flows[:i], nf.Flows[i+1:]...)
		count++
		del := nom.FlowEntryDeleted{
			Flow: f.FlowEntry,
		}
		ctx.Emit(del)
		for _, sub := range f.FlowSubscribers {
			if !sub.IsNil() {
				ctx.SendToCell(del, sub.App, sub.Cell())
			}
		}
	}

	return ctx.Dict(flowsDict).Put(string(res.Node), nf)
}