标签:floodlight controlle lldp tlv
前面已经知道了Floodlight Controller是通过从SW发送LLDP帧来获得链路信息的,链路层发现协议(L2)是通过在本地网络中广播LLDP报文来通告自己的设备信息,从而服务于拓扑计算,(wikipedia:LLDP information is sent by devices from each of their interfaces at a fixed interval,
in the form of an Ethernet frame. Each frame contains one LLDP Data Unit (LLDPDU). Each LLDPDU is a sequence of type-length-value (TLV) structures.)报文格式如下:
type-length-value 的设计很常见(比如netlink中attribute也是这种格式),这里的TLV结构是:
此时再看代码就很容易理解:
public class LLDPTLV
{
protected byte type ;
protected short length ;
protected byte[] value ;
public byte getType()
{
return type ;
}
public LLDPTLV
setType( byte type) {
this.type =
type;
return this ;
}
public short getLength()
{
return length ;
}
public LLDPTLV
setLength( short length) {
this.length =
length;
return this ;
}
public byte[]
getValue() {
return value ;
}
public LLDPTLV
setValue( byte[] value) {
this.value =
value;
return this ;
}
// serialization
- Turn data into a stream of bytes
public byte[]
serialize() {
//
type = 7 bits
//
info string length 9 bits, each value == byte
//
info string
short scratch
= (short) (((0x7f & this. type)
<< 9) | (0x1ff & this .length ));
//
7+9 = 2B
byte[]
data = new byte[2
+ this.length ];
ByteBuffer bb = ByteBuffer. wrap(data);
bb.putShort(scratch);
if (this .value != null)
bb.put( this.value );
return data;
}
// deserialization
- Turn a stream of bytes back into a copy of the original
// object.
public LLDPTLV
deserialize(ByteBuffer bb) {
short sscratch;
sscratch = bb.getShort();
this.type =
(byte) ((sscratch >> 9) & 0x7f);
this.length =
(short) (sscratch & 0x1ff);
if (this .length >
0) {
this.value = new byte[ this.length ];
//
if there is an underrun just toss the TLV
if (bb.remaining()
< this.length)
return null ;
bb.get( this.value );
}
return this ;
}
}
public class LLDP extends BasePacket
{
protected LLDPTLV chassisId;
protected LLDPTLV portId;
protected LLDPTLV ttl;
protected List<LLDPTLV> optionalTLVList;
protected short ethType ;
//上述几个字段都是LLDP协议规定的
public LLDP()
{
this.optionalTLVList = new ArrayList<LLDPTLV>();
this.ethType =
Ethernet.TYPE_LLDP; //
0x88cc
}
public LLDPTLV
getChassisId() {
return chassisId ;
}
public LLDP
setChassisId(LLDPTLV chassisId) {
this.chassisId =
chassisId;
return this ;
}
public LLDPTLV
getPortId() {
return portId ;
}
public LLDP
setPortId(LLDPTLV portId) {
this.portId =
portId;
return this ;
}
public LLDPTLV
getTtl() {
return ttl ;
}
public LLDP
setTtl(LLDPTLV ttl) {
this.ttl =
ttl;
return this ;
}
public List<LLDPTLV>
getOptionalTLVList() {
return optionalTLVList ;
}
public LLDP
setOptionalTLVList(List<LLDPTLV> optionalTLVList) {
this.optionalTLVList =
optionalTLVList;
return this ;
}
@Override
public byte[]
serialize() {
int length
= 2 + this.chassisId.getLength()
+ 2
+ this.portId .getLength()
+ 2 + this.ttl .getLength()
+ 2;
for (LLDPTLV
tlv : this.optionalTLVList)
{
length += 2 + tlv.getLength();
}
byte[]
data = new byte[length];
ByteBuffer bb = ByteBuffer. wrap(data);
bb.put( this.chassisId .serialize());
bb.put( this.portId .serialize());
bb.put( this.ttl .serialize());
for (LLDPTLV
tlv : this.optionalTLVList)
{
bb.put(tlv.serialize());
}
bb.putShort(( short)
0); // End of LLDPDU
if (this .parent != null && this. parent instanceof Ethernet)
((Ethernet) this.parent ).setEtherType(ethType);
return data;
}
@Override
public IPacket
deserialize( byte[] data, int offset, int length)
{
ByteBuffer bb = ByteBuffer. wrap(data, offset, length);
LLDPTLV tlv;
do {
tlv = new LLDPTLV().deserialize(bb);
// if there was a failure to deserialize
stop processing TLVs
if (tlv
== null )
break;
switch (tlv.getType())
{
case 0x0:
// can throw this one away, its
just an end delimiter
break;
case 0x1:
this.chassisId =
tlv;
break;
case 0x2:
this.portId =
tlv;
break;
case 0x3:
this.ttl =
tlv;
break;
default:
this.optionalTLVList .add(tlv);
break;
}
} while (tlv.getType()
!= 0 && bb.hasRemaining());
return this ;
}
}
LLDP报文格式
标签:floodlight controlle lldp tlv
原文地址:http://blog.csdn.net/vonzhoufz/article/details/38061131