Ejemplo n.º 1
0
// 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__"}}
}
Ejemplo n.º 2
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
// 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)
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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

}
Ejemplo n.º 7
0
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()
}
Ejemplo n.º 8
0
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
}
Ejemplo n.º 9
0
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}}
}
Ejemplo n.º 10
0
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
}
Ejemplo n.º 11
0
// 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)
}
Ejemplo n.º 12
0
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)
}
Ejemplo n.º 13
0
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
}
Ejemplo n.º 14
0
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
}
Ejemplo n.º 15
0
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
}
Ejemplo n.º 16
0
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)
}
Ejemplo n.º 17
0
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
}
Ejemplo n.º 18
0
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)
}
Ejemplo n.º 19
0
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)
}
Ejemplo n.º 20
0
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
}
Ejemplo n.º 21
0
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
}
Ejemplo n.º 22
0
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
}
Ejemplo n.º 23
0
// 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(),
	})
}
Ejemplo n.º 24
0
func (p *pinger) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	dict := ctx.Dict(PingPongDict)
	data := msg.Data()
	switch data := data.(type) {
	case ping:
		fmt.Printf("Rx Ping %d %v->%v\n", data.Seq, msg.From(), ctx.ID())
		time.Sleep(300 * time.Millisecond)

		v, err := dict.Get("ping")
		var p ping
		if err == nil {
			p = v.(ping)
		}

		if data != p {
			return fmt.Errorf("Invalid ping: ping=%d, want=%d", data.Seq, p.Seq)
		}

		p.Seq += 1
		dict.Put("ping", p)

		fmt.Printf("Ping stored to %v\n", p.Seq)

		if !msg.NoReply() {
			fmt.Printf("Tx Pong %d @ %v\n", data.pong().Seq, ctx.ID())
			ctx.Emit(data.pong())
		}

	case pong:
		fmt.Printf("Rx Pong %d %v->%v\n", data.Seq, msg.From(), ctx.ID())

		time.Sleep(300 * time.Millisecond)

		dict := ctx.Dict(PingPongDict)
		v, err := dict.Get("pong")
		var p pong
		if err == nil {
			p = v.(pong)
		}

		if data != p {
			return fmt.Errorf("Invalid pong: pong=%d, want=%d", data.Seq, p.Seq)
		}

		p.Seq += 1
		dict.Put("pong", p)
		fmt.Printf("Pong stored to %v\n", p.Seq)

		fmt.Printf("Tx Ping %d @ %v\n", data.ping().Seq, ctx.ID())
		ctx.Emit(data.ping())
	}
	return nil
}
Ejemplo n.º 25
0
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
}
Ejemplo n.º 26
0
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)
}
Ejemplo n.º 27
0
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)
}
Ejemplo n.º 28
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)
}
Ejemplo n.º 29
0
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)
}
Ejemplo n.º 30
0
func (d Detector) Rcv(msg bh.Msg, ctx bh.RcvContext) error {
	res := msg.Data().(nom.FlowStatsQueryResult)

	var flows []flow
	if v, err := ctx.Dict("Switches").Get(string(res.Node)); err == nil {
		flows = v.([]flow)
	}

	for _, s1 := range res.Stats {
		// Find the previous stats.
		index := -1
		for i := range flows {
			if !s1.Match.Equals(flows[i].Stats.Match) {
				continue
			}

			if s1.Duration < flows[i].Stats.Duration {
				// The stat is newer than what we've seen so far.
				flows[i].Notified = false
			}

			flows[i].Stats = s1
			index = i
			break
		}

		if index < 0 {
			index = len(flows)
			flows = append(flows, flow{Stats: s1})
		}

		// Notify the router if it is an elephant flow, and make sure you do it
		// once.
		if !flows[index].Notified &&
			flows[index].Stats.Bytes > d.ElephantThreshold {

			flows[index].Notified = true
			ctx.Emit(ElephantDetected{
				Match: flows[index].Stats.Match,
			})
		}
	}

	return ctx.Dict("Switches").Put(string(res.Node), flows)
}