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) }
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) }
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) }