func (h EnQHandler) Rcv(msg beehive.Msg, ctx beehive.RcvContext) error { enq := msg.Data().(Enque) dict := ctx.Dict(active) next := TaskID(1) if v, err := dict.Get("_next_"); err == nil { next = v.(TaskID) } key := next.String() task := Task{ Queue: enq.Queue, ID: next, Body: enq.Body, } if err := dict.Put(key, task); err != nil { return err } if err := dict.Put("_next_", next+1); err != nil { return err } enqued := Enqued{ ID: enq.ID, Queue: enq.Queue, TaskID: next, } return ctx.Reply(msg, enqued) }
// Rcv maps Discovery based on its destination node and Advertisement messages // based on their source node. func (m RouterM) Map(msg bh.Msg, ctx bh.MapContext) bh.MappedCells { switch dm := msg.Data().(type) { case InterAreaQuery: return bh.MappedCells{{"__D__", "__0__"}} case InterAreaLink: return bh.MappedCells{{"__D__", "__0__"}} case area_setup: return bh.MappedCells{{"__D__", "__0__"}} case setupM: areaMsg := msg.Data().(setupM) return bh.MappedCells{{"area", areaMsg.area}} case nom.LinkAdded: link := nom.Link(dm) nf, _ := nom.ParsePortUID(link.From) k := string(nf) nt, _ := nom.ParsePortUID(link.To) k2 := string(nt) nf_area := FindAreaId(k) nt_area := FindAreaId(k2) if nt_area != nf_area { return bh.MappedCells{{"__D__", "__0__"}} } else { return bh.MappedCells{{"area", nf_area}} } case nom.PacketIn: ni := msg.Data().(nom.PacketIn) k := string(ni.Node) return bh.MappedCells{{"area", FindAreaId(k)}} } return bh.MappedCells{{"__D__", "__0__"}} }
func (c *Calculator) Rcv(msg bh.Msg, ctx bh.RcvContext) error { op := msg.Data().(Op) res := c.calc(op) fmt.Printf("%d %s %d = %d\n", op.Lhs, op.OpT, op.Rhs, res) ctx.Reply(msg, res) return nil }
func (h *intentHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { hrq := msg.Data().(http.HTTPRequest) if hrq.AppName == "intent" && hrq.Verb == "build" { spd := shortestPathData{} err := json.Unmarshal(hrq.Data, &spd) if err != nil { glog.Errorf("Host list JSON unmarshaling: %v", err) return err } fmt.Println(spd) fmt.Println(discovery.ShortestPathCentralized(spd.From, spd.To, ctx)) hrs := http.HTTPResponse{ AppName: "host", Data: []byte{'A'}, } err = ctx.Reply(msg, hrs) if err != nil { glog.Errorf("Replay error: %v", err) return err } } return nil }
func (h AckHandler) Rcv(msg beehive.Msg, ctx beehive.RcvContext) error { ack := msg.Data().(Ack) acked := Acked{ ID: ack.ID, Queue: ack.Queue, TaskID: ack.TaskID, } key := ack.TaskID.String() ddict := ctx.Dict(dequed) if err := ddict.Del(key); err == nil { ctx.Reply(msg, acked) return nil } // The task might have been moved from dequed to out of order, because of a // timeout. So, we need to search the active dictionary as well. odict := ctx.Dict(ooo) if err := odict.Del(key); err == nil { ctx.Reply(msg, acked) return nil } return ErrNoSuchTask }
// The bee hander func BeeHandler( beehiveMessage beehive.Msg, beeContext beehive.RcvContext) error { // beehiveMessage is an envelope around the Hello message. // You can retrieve the Hello, using msg.Data() and then // you need to assert that its a MessageToBee. message := beehiveMessage.Data().(MessageToBee) // Using ctx.Dict you can get (or create) a dictionary. dict := beeContext.Dict("beehive-app-dict") value, err := dict.Get(message.DestinationBee) logger.Trace.Printf("[BeeHandler] Message sent to bee with id (%s) \n", message.DestinationBee) count := 0 if err == nil { // No error mean there is already an item with given key count = value.(int) } count++ logger.Trace.Printf("[BeeHandler] Count = %d\n", count) logger.Trace.Printf("[BeeHandler] Calculate fib number %d\n", message.FibNumber) Fib(message.FibNumber) beeContext.Reply(beehiveMessage, count) return dict.Put(message.DestinationBee, count) }
// Rcvf receives the message and the context. func Rcvf(msg beehive.Msg, ctx beehive.RcvContext) error { // msg is an envelope around the Hello message. // You can retrieve the Hello, using msg.Data() and then // you need to assert that its a Hello. hello := msg.Data().(Hello) // Using ctx.Dict you can get (or create) a dictionary. dict := ctx.Dict("hello_dict") // Using Get(), you can get the value associated with // a key in the dictionary. Keys are always string // and values are generic interface{}'s. v, err := dict.Get(hello.Name) // If there is an error, the entry is not in the // dictionary. Otherwise, we set cnt based on // the value we already have in the dictionary // for that name. cnt := 0 if err == nil { cnt = v.(int) } // Now we increment the count. cnt++ // And then we print the hello message. ctx.Printf("hello %s (%d)!\n", hello.Name, cnt) // Finally we update the count stored in the dictionary. return dict.Put(hello.Name, cnt) }
func (h HealthChecker) Rcv(msg bh.Msg, ctx bh.RcvContext) error { db := msg.From() dict := ctx.Dict(driversDict) dict.ForEach(func(k string, v interface{}) { nd := v.(nodeDrivers) updated := false for i := range nd.Drivers { if nd.Drivers[i].BeeID == db { nd.Drivers[i].LastSeen = time.Now() // TODO(soheil): Maybe if outpings was more than MaxPings we // should emit a connected message. nd.Drivers[i].OutPings-- updated = true } } if !updated { return } if err := dict.Put(k, nd); err != nil { glog.Warningf("error in encoding drivers: %v", err) } }) return nil }
func (b GraphBuilderCentralized) Rcv(msg bh.Msg, ctx bh.RcvContext) error { dict := ctx.Dict(GraphDict) var link nom.Link switch dm := msg.Data().(type) { case nom.LinkAdded: link = nom.Link(dm) case nom.LinkDeleted: link = nom.Link(dm) default: return fmt.Errorf("GraphBuilderCentralized: unsupported message type %v", msg.Type()) } nf, _ := nom.ParsePortUID(link.From) nt, _ := nom.ParsePortUID(link.To) if nf == nt { return fmt.Errorf("%v is a loop", link) } k := string(nf) links := make(map[nom.UID][]nom.Link) if v, err := dict.Get(k); err == nil { links = v.(map[nom.UID][]nom.Link) } links[nt.UID()] = append(links[nt.UID()], link) return dict.Put(k, links) }
func (h *arpPktInHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { pin := msg.Data().(nom.PacketIn) p := gopacket.NewPacket([]byte(pin.Packet), layers.LayerTypeEthernet, gopacket.Default) etherlayer := p.Layer(layers.LayerTypeEthernet) if etherlayer == nil { return nil } e, _ := etherlayer.(*layers.Ethernet) if e.EthernetType != layers.EthernetTypeARP { return nil } host, _, err := decodeARP([]byte(pin.Packet)) host.Node = pin.Node if err != nil { glog.Errorf("ARP decoding error: %v", err) return err } glog.V(2).Infof("Host detected: %v", host) ctx.Emit(nom.HostConnected(host)) return nil }
func (h *newLinkHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { l := nom.Link(msg.Data().(NewLink)) n, _ := nom.ParsePortUID(l.From) d := ctx.Dict(nodeDict) k := string(n) v, err := d.Get(k) if err != nil { return nil } np := v.(nodePortsAndLinks) if oldl, ok := np.linkFrom(l.From); ok { if oldl.UID() == l.UID() { return nil } np.removeLink(oldl) ctx.Emit(nom.LinkDeleted(oldl)) } glog.V(2).Infof("Link detected %v", l) ctx.Emit(nom.LinkAdded(l)) np.L = append(np.L, l) return d.Put(k, np) }
func (h *hostConnectedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { host := msg.Data().(nom.HostConnected) dict := ctx.Dict(hostDict) _, err := dict.Get(host.MACAddr.String()) if err == nil { return nil } v, err := dict.Get("hsts") hsts := []nom.Host{} if err == nil { hsts = v.([]nom.Host) } hsts = append(hsts, nom.Host(host)) err = dict.Put(host.MACAddr.String(), host) if err != nil { glog.Errorf("Put %v in %s: %v", host, host.MACAddr.String(), err) return err } err = dict.Put("hsts", hsts) if err != nil { glog.Errorf("Put %v in hsts: %v", hsts, err) return err } ctx.Emit(nom.HostJoined(host)) return nil }
func (h *httpHostListHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { hrq := msg.Data().(http.HTTPRequest) if hrq.AppName == "host" && hrq.Verb == "list" { dict := ctx.Dict(hostDict) v, err := dict.Get("hsts") hsts := []nom.Host{} if err == nil { hsts = v.([]nom.Host) } data, err := json.Marshal(hsts) if err != nil { glog.Errorf("Host list JSON marshaling: %v", err) return err } fmt.Println(hsts) hrs := http.HTTPResponse{ AppName: "host", Data: data, } err = ctx.Reply(msg, hrs) if err != nil { glog.Errorf("Replay error: %v", err) return err } } return nil }
func (d *Driver) Rcv(m beehive.Msg, ctx beehive.RcvContext) error { if m.NoReply() { return nil } q, ok := m.Data().(StatQuery) if !ok { return nil } s, ok := d.switches[q.Switch] if !ok { return fmt.Errorf("No switch stored in the driver: %+v", s) } for i, f := range s.Flows { f.Bytes += uint64(rand.Intn(maxSpike)) s.Flows[i] = f glog.V(2).Infof("Emitting stat result for %+v", f) ctx.Emit(StatResult{q, f.Flow, f.Bytes}) } d.switches[q.Switch] = s return nil }
func (h *ConnHandler) Rcv(msg beehive.Msg, ctx beehive.RcvContext) error { res := msg.Data().(writerTo) if err := res.writeTo(h.w); err != nil { return err } return h.w.Flush() }
func (h AckHandler) Map(msg beehive.Msg, ctx beehive.MapContext) beehive.MappedCells { // Send the Ack message to the bee that owns queues/q. q := string(msg.Data().(Ack).Queue) return beehive.MappedCells{{queues, q}} }
func (c *Collector) Rcv(m beehive.Msg, ctx beehive.RcvContext) error { res := m.Data().(StatResult) glog.V(2).Infof("Stat results: %+v", res) matrix := ctx.Dict(matrixDict) key := res.Switch.Key() v, err := matrix.Get(key) if err != nil { return fmt.Errorf("No such switch in matrix: %+v", res) } c.poller.query <- StatQuery{res.Switch} sw := v.(SwitchStats) stat, ok := sw[res.Flow] sw[res.Flow] = res.Bytes glog.V(2).Infof("Previous stats: %+v, Now: %+v", stat, res.Bytes) if !ok || res.Bytes-stat > c.delta { glog.Infof("Found an elephent flow: %+v, %+v, %+v", res, stat, ctx.Hive().ID()) ctx.Emit(MatrixUpdate(res)) } matrix.Put(key, sw) return nil }
func (h portStatusHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { // FIXME(soheil): This implementation is very naive and cannot tolerate // faults. We need to first check if the driver is the mater, and then apply // the change. Otherwise, we need to enque this message for that driver and // make sure we apply the log to the port status data := msg.Data().(nom.PortStatusChanged) dict := ctx.Dict(driversDict) k := string(data.Port.Node) v, err := dict.Get(k) if err != nil { return fmt.Errorf("NOMController: node %v not found", data.Port.Node) } n := v.(nodeDrivers) if !n.isMaster(data.Driver) { glog.Warningf("NOMController: %v ignored, %v is not master, master is %v", data.Port, data.Driver, n.master()) return nil } if p, ok := n.Ports.GetPort(data.Port.UID()); ok { if p == data.Port { return fmt.Errorf("NOMController: duplicate port status change for %v", data.Port) } n.Ports.DelPort(p) } n.Ports.AddPort(data.Port) ctx.Emit(nom.PortUpdated(data.Port)) return nil }
func (h addHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { add := msg.Data().(nom.AddPath) if len(add.Path.Pathlets) == 0 { return errors.New("path: path has no pathlets") } flows := make([]nom.FlowEntry, 0, len(add.Path.Pathlets)) // TODO(soheil): maybe detect loops in pathlets? var outports []nom.UID var newflows []nom.FlowEntry var err error for _, p := range add.Path.Pathlets { if len(outports) == 0 { newflows, outports, err = genFlowsForPathlet(p, nom.Nil, add.Path.Priority, ctx) if err != nil { return err } flows = append(flows, newflows...) continue } inps := inPortsFromOutPorts(outports, ctx) outports = outports[0:0] for _, inp := range inps { newflows, newoutports, err := genFlowsForPathlet(p, inp, add.Path.Priority, ctx) if err != nil { return err } outports = append(outports, newoutports...) flows = append(flows, newflows...) } } uniqueFlows := make([]nom.FlowEntry, 0, len(flows)) nextFlow: for i, fi := range flows { for j, fj := range flows { if i == j { continue } if fj.Subsumes(fi) { continue nextFlow } // TODO(soheil): check for subsumption and merge flows if possible. if j < i && fj.Equals(fi) { continue nextFlow } } uniqueFlows = append(uniqueFlows, fi) } addFlowEntriesForPath(add.Subscriber, add.Path, uniqueFlows, ctx) return nil }
func (h flowHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { switch data := msg.Data().(type) { case nom.FlowEntryAdded: return confirmFlowEntryForPath(nom.FlowEntry(data.Flow), ctx) case nom.FlowEntryDeleted: return delFlowEntryFromPath(nom.FlowEntry(data.Flow), ctx) } return fmt.Errorf("flowHandler: unsupported message %v", msg.Type()) }
func (h addTriggerHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { add := msg.Data().(nom.AddTrigger) dict := ctx.Dict(triggersDict) var nt nodeTriggers if v, err := dict.Get(string(add.Node)); err == nil { nt = v.(nodeTriggers) } nt.maybeAddTrigger(nom.Trigger(add)) return dict.Put(string(add.Node), nt) }
func (h *UpdateHandler) Rcv(m beehive.Msg, ctx beehive.RcvContext) error { if m.NoReply() { return nil } u := m.Data().(MatrixUpdate) glog.Infof("Received matrix update: %+v", u) ctx.Emit(FlowMod{Switch: u.Switch}) return nil }
func (h delTriggerHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { del := msg.Data().(nom.DelTrigger) var nt nodeTriggers dict := ctx.Dict(triggersDict) if v, err := dict.Get(string(del.Node)); err == nil { nt = v.(nodeTriggers) } nt.delTrigger(nom.Trigger(del)) return dict.Put(string(del.Node), nt) }
func (h *nodeLeftHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { n := nom.Node(msg.Data().(nom.NodeLeft)) d := ctx.Dict(nodeDict) k := string(n.UID()) if _, err := d.Get(k); err != nil { return fmt.Errorf("%v is not joined", n) } d.Del(k) return nil }
// doDequeTask adds a task to the dequed dictionary and replys to the message. func doDequeTask(msg beehive.Msg, ctx beehive.RcvContext, t Task) error { ctx.Reply(msg, Dequed{ ID: msg.Data().(Deque).ID, Task: t, }) ddict := ctx.Dict(dequed) return ddict.Put(t.ID.String(), dqTask{ Task: t, DequeTime: time.Now(), }) }
func (h Hub) Rcv(msg bh.Msg, ctx bh.RcvContext) error { in := msg.Data().(nom.PacketIn) out := nom.PacketOut{ Node: in.Node, InPort: in.InPort, BufferID: in.BufferID, Packet: in.Packet, Actions: []nom.Action{nom.ActionFlood{}}, } ctx.ReplyTo(msg, out) return nil }
func rcvf(msg bh.Msg, ctx bh.RcvContext) error { name := msg.Data().(string) cnt := 0 if v, err := ctx.Dict(helloDict).Get(name); err == nil { cnt = v.(int) } cnt++ ctx.Printf("hello %s (%d)!\n", name, cnt) ctx.Dict(helloDict).Put(name, cnt) return nil }
func (h *nodeJoinedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { joined := msg.Data().(nom.NodeJoined) d := ctx.Dict(nodeDict) n := nom.Node(joined) k := string(n.UID()) var np nodePortsAndLinks if v, err := d.Get(k); err != nil { glog.Warningf("%v rejoins", n) } else { np = v.(nodePortsAndLinks) } np.N = n // TODO(soheil): Add a flow entry to forward lldp packets to the controller. return d.Put(k, np) }
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 (h nodeConnectedHandler) Rcv(msg bh.Msg, ctx bh.RcvContext) error { nc := msg.Data().(nom.NodeConnected) ddict := ctx.Dict(driversDict) k := string(nc.Node.ID) n := nodeDrivers{ Node: nc.Node, } if v, err := ddict.Get(k); err == nil { n = v.(nodeDrivers) } if _, ok := n.driver(nc.Driver); ok { return fmt.Errorf("driver %v reconnects to %v", nc.Driver, n.Node) } gdict := ctx.Dict(genDict) gen := uint64(0) if v, err := gdict.Get("gen"); err == nil { gen = v.(uint64) } gen++ db := nc.Driver.BeeID if len(n.Drivers) == 0 { nc.Driver.Role = nom.DriverRoleMaster ctx.Emit(nom.NodeJoined(nc.Node)) glog.V(2).Infof("%v connected to master controller", nc.Node) } else { nc.Driver.Role = nom.DriverRoleSlave glog.V(2).Infof("%v connected to slave controller", nc.Node) } n.Drivers = append(n.Drivers, driverInfo{ Driver: nc.Driver, LastSeen: time.Now(), }) ctx.SendToBee(nom.ChangeDriverRole{ Node: nc.Node.UID(), Role: nc.Driver.Role, Generation: gen, }, db) gdict.Put("gen", gen) return ddict.Put(k, n) }