Ejemplo n.º 1
0
func sendLLDPPacket(n nom.Node, p nom.Port, ctx bh.RcvContext) {
	pkt := nom.PacketOut{
		Node:     n.UID(),
		Packet:   nom.Packet(encodeLLDP(n, p)),
		BufferID: 0xFFFFFFFF,
		Actions: []nom.Action{
			nom.ActionForward{
				Ports: []nom.UID{p.UID()},
			},
		},
	}
	ctx.Emit(pkt)
}
Ejemplo n.º 2
0
func encodeLLDP(n nom.Node, p nom.Port) []byte {
	b := make([]byte, 256)
	h := lldp.NewLinkDiscoveryProtocolWithBuf(b)
	h.Init()
	h.SetSrcMac(n.MACAddr)
	h.SetDstMac([6]byte{0x01, 0x80, 0xC2, 0x00, 0x00, 0x0E})
	size := h.Size()

	tlvb := b[size:]
	chTLV := lldp.NewChassisMacTLVWithBuf(tlvb)
	chTLV.Init()
	chTLV.SetMacAddr(n.MACAddr)
	size += chTLV.Size()

	tlvb = b[size:]
	pTLV := lldp.NewLinkDiscoveryTLVWithBuf(tlvb)
	pTLV.Init()
	pTLV.SetType(uint8(lldp.TLV_PORT_ID))

	pTLV.AddValue(byte(lldp.PORT_TLV_IFACE_NAME))
	for _, v := range []byte(p.UID()) {
		pTLV.AddValue(v)
	}
	size += pTLV.Size()

	tlvb = b[size:]
	ttlTLV := lldp.NewLinkDiscoveryTLVWithBuf(tlvb)
	ttlTLV.Init()
	ttlTLV.SetType(uint8(lldp.TLV_TTL))
	ttlTLV.AddValue(0)
	ttlTLV.AddValue(0xFF)

	size += ttlTLV.Size()

	// TODO(soheil): Maybe add a few custom fields?
	return b[:size]
}
Ejemplo n.º 3
0
func (d *of10Driver) handshake(c *ofConn) error {
	freq := of10.NewFeaturesRequest()
	if err := c.WriteHeader(freq.Header); err != nil {
		return err
	}

	c.Flush()

	glog.V(2).Info("%v sent features request to the switch", c.ctx)

	hdr, err := c.ReadHeader()
	if err != nil {
		return err
	}

	v10, err := of10.ToHeader10(hdr)
	if err != nil {
		return err
	}

	frep, err := of10.ToFeaturesReply(v10)
	if err != nil {
		return err
	}

	glog.Infof("%v completes handshaking with switch %016x", c.ctx,
		frep.DatapathId())
	glog.Infof("%v disables packet buffers in switch %016x", c.ctx,
		frep.DatapathId())
	cfg := of10.NewSwitchSetConfig()
	cfg.SetMissSendLen(0xFFFF)
	c.WriteHeader(cfg.Header)

	nodeID := datapathIDToNodeID(frep.DatapathId())
	c.node = nom.Node{
		ID:           nodeID,
		MACAddr:      datapathIDToMACAddr(frep.DatapathId()),
		Capabilities: nil,
	}
	glog.Infof("%v is connected to %v", c.ctx, c.node)

	nomDriver := nom.Driver{
		BeeID: c.ctx.ID(),
		Role:  nom.DriverRoleDefault,
	}

	c.ctx.Emit(nom.NodeConnected{
		Node:   c.node,
		Driver: nomDriver,
	})

	d.ofPorts = make(map[uint16]*nom.Port)
	d.nomPorts = make(map[nom.UID]uint16)
	for _, p := range frep.Ports() {
		name := p.Name()
		port := nom.Port{
			ID:      portNoToPortID(uint32(p.PortNo())),
			Name:    string(name[:]),
			MACAddr: p.HwAddr(),
			Node:    c.NodeUID(),
		}
		d.ofPorts[p.PortNo()] = &port
		d.nomPorts[port.UID()] = p.PortNo()
		glog.Infof("%v added", port)
		if p.PortNo() <= uint16(of10.PP_MAX) {
			c.ctx.Emit(nom.PortStatusChanged{
				Port:   port,
				Driver: nomDriver,
			})
		}
	}
	return nil
}
Ejemplo n.º 4
0
func (d *of12Driver) handshake(c *ofConn) error {
	freq := of12.NewFeaturesRequest()
	if err := c.WriteHeader(freq.Header); err != nil {
		return err
	}
	c.Flush()

	glog.V(2).Info("Sent features request to the switch")

	hdr, err := c.ReadHeader()
	if err != nil {
		return err
	}

	v12, err := of12.ToHeader12(hdr)
	if err != nil {
		return err
	}

	frep, err := of12.ToFeaturesReply(v12)
	if err != nil {
		return err
	}

	glog.Infof("Handshake completed for switch %016x", frep.DatapathId())

	glog.Infof("Disabling packet buffers in the switch.")
	cfg := of12.NewSwitchSetConfig()
	cfg.SetMissSendLen(0xFFFF)
	c.WriteHeader(cfg.Header)

	nodeID := datapathIDToNodeID(frep.DatapathId())
	c.node = nom.Node{
		ID:      nodeID,
		MACAddr: datapathIDToMACAddr(frep.DatapathId()),
		Capabilities: []nom.NodeCapability{
			nom.CapDriverRole,
		},
	}

	nomDriver := nom.Driver{
		BeeID: c.ctx.ID(),
		Role:  nom.DriverRoleDefault,
	}
	c.ctx.Emit(nom.NodeConnected{
		Node:   c.node,
		Driver: nomDriver,
	})

	d.ofPorts = make(map[uint32]*nom.Port)
	d.nomPorts = make(map[nom.UID]uint32)
	for _, p := range frep.Ports() {
		if p.PortNo() > uint32(of12.PP_MAX) {
			continue
		}
		name := p.Name()
		port := nom.Port{
			ID:      portNoToPortID(p.PortNo()),
			Name:    string(name[:]),
			MACAddr: p.HwAddr(),
			Node:    c.NodeUID(),
		}
		d.ofPorts[p.PortNo()] = &port
		d.nomPorts[port.UID()] = p.PortNo()
		glog.Infof("%v added", port)
		c.ctx.Emit(nom.PortStatusChanged{
			Port:   port,
			Driver: nomDriver,
		})
	}

	return nil
}