blob: ec35de8efb15a97bff5e66ccb9b2b955885974c7 [file] [log] [blame]
alshabib7911a052014-10-16 17:49:37 -07001package org.onlab.packet;
2
3import com.google.common.collect.Lists;
4import org.apache.commons.lang.ArrayUtils;
5
6import java.nio.ByteBuffer;
7
8/**
9 * ONOS LLDP containing organizational TLV for ONOS device dicovery.
10 */
11public class ONOSLLDP extends LLDP {
12
13 public static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05};
14 public static final String DEFAULT_DEVICE = "INVALID";
15 public static final String DEFAULT_NAME = "ONOS Discovery";
16
17 public static final byte[] LLDP_NICIRA = {0x01, 0x23, 0x20, 0x00, 0x00,
18 0x01};
19 public static final byte[] LLDP_MULTICAST = {0x01, (byte) 0x80,
20 (byte) 0xc2, 0x00, 0x00, 0x0e};
21 public static final byte[] BDDP_MULTICAST = {(byte) 0xff, (byte) 0xff,
22 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
23
24 private static final byte NAME_SUBTYPE = 1;
25 private static final byte DEVICE_SUBTYPE = 2;
26 private static final short NAME_LENGTH = 4; //1 for subtype + 3 for OUI
27 private static final short DEVICE_LENGTH = 4; //1 for subtype + 3 for OUI
28 private final LLDPOrganizationalTLV nameTLV = new LLDPOrganizationalTLV();
29 private final LLDPOrganizationalTLV deviceTLV = new LLDPOrganizationalTLV();
30
31 // TLV constants: type, size and subtype
32 // Organizationally specific TLV also have packet offset and contents of TLV
33 // header
34 private static final byte CHASSIS_TLV_TYPE = 1;
35 private static final byte CHASSIS_TLV_SIZE = 7;
36 private static final byte CHASSIS_TLV_SUBTYPE = 4;
37
38 private static final byte PORT_TLV_TYPE = 2;
39 private static final byte PORT_TLV_SIZE = 5;
40 private static final byte PORT_TLV_SUBTYPE = 2;
41
42 private static final byte TTL_TLV_TYPE = 3;
43
44
45 private final byte[] ttlValue = new byte[] {0, 0x78};
46
47 public ONOSLLDP() {
48 super();
49 setName(DEFAULT_NAME);
50 setDevice(DEFAULT_DEVICE);
51 setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV));
52 setTtl(new LLDPTLV().setType((byte) TTL_TLV_TYPE)
53 .setLength((short) ttlValue.length)
54 .setValue(ttlValue));
55
56 }
57
58 private ONOSLLDP(LLDP lldp) {
59 this.portId = lldp.getPortId();
60 this.chassisId = lldp.getChassisId();
61 this.ttl = lldp.getTtl();
62 this.optionalTLVList = lldp.getOptionalTLVList();
63 }
64
65 public void setName(String name) {
66 nameTLV.setLength((short) (name.length() + NAME_LENGTH));
67 nameTLV.setInfoString(name);
68 nameTLV.setSubType(NAME_SUBTYPE);
69 nameTLV.setOUI(ONLAB_OUI);
70 }
71
72 public void setDevice(String device) {
73 deviceTLV.setInfoString(device);
74 deviceTLV.setLength((short) (device.length() + DEVICE_LENGTH));
75 deviceTLV.setSubType(DEVICE_SUBTYPE);
76 deviceTLV.setOUI(ONLAB_OUI);
77 }
78
79 public void setChassisId(final ChassisId chassisId) {
80 MacAddress chassisMac = MacAddress.valueOf(chassisId.value());
81 byte[] chassis = ArrayUtils.addAll(new byte[] {CHASSIS_TLV_SUBTYPE},
82 chassisMac.getAddress());
83
84 LLDPTLV chassisTLV = new LLDPTLV();
85 chassisTLV.setLength(CHASSIS_TLV_SIZE);
86 chassisTLV.setType(CHASSIS_TLV_TYPE);
87 chassisTLV.setValue(chassis);
88 this.setChassisId(chassisTLV);
89 }
90
91 public void setPortId(final int portNumber) {
92 byte[] port = ArrayUtils.addAll(new byte[] {PORT_TLV_SUBTYPE},
93 ByteBuffer.allocate(4).putInt(portNumber).array());
94
95 LLDPTLV portTLV = new LLDPTLV();
96 portTLV.setLength(PORT_TLV_SIZE);
97 portTLV.setType(PORT_TLV_TYPE);
98 portTLV.setValue(port);
99 this.setPortId(portTLV);
100 }
101
102 public LLDPOrganizationalTLV getNameTLV() {
103 for (LLDPTLV tlv : this.getOptionalTLVList()) {
104 if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
105 LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv;
106 if (orgTLV.getSubType() == NAME_SUBTYPE) {
107 return orgTLV;
108 }
109 }
110 }
111 return null;
112 }
113
114 public LLDPOrganizationalTLV getDeviceTLV() {
115 for (LLDPTLV tlv : this.getOptionalTLVList()) {
116 if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
117 LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv;
118 if (orgTLV.getSubType() == DEVICE_SUBTYPE) {
119 return orgTLV;
120 }
121 }
122 }
123 return null;
124 }
125
126 public String getNameString() {
127 LLDPOrganizationalTLV tlv = getNameTLV();
128 if (tlv != null) {
129 return new String(tlv.getInfoString());
130 }
131 return null;
132 }
133
134 public String getDeviceString() {
135 LLDPOrganizationalTLV tlv = getDeviceTLV();
136 if (tlv != null) {
137 return new String(tlv.getInfoString());
138 }
139 return null;
140 }
141
142 public Integer getPort() {
143 ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue());
144 portBB.position(1);
145 return portBB.getInt();
146 }
147
148 /**
149 * Given an ethernet packet, determines if this is an LLDP from
150 * ONOS and returns the device the LLDP came from.
151 * @param eth an ethernet packet
152 * @return a the lldp packet or null
153 */
154 public static ONOSLLDP parseONOSLLDP(Ethernet eth) {
155 if (eth.getEtherType() == Ethernet.TYPE_LLDP ||
156 eth.getEtherType() == Ethernet.TYPE_BSN) {
157 ONOSLLDP onosLldp = new ONOSLLDP((LLDP) eth.getPayload()); //(ONOSLLDP) eth.getPayload();
158 if (ONOSLLDP.DEFAULT_NAME.equals(onosLldp.getNameString())) {
159 return onosLldp;
160 }
161 }
162 return null;
163 }
164
165
166
167
168
169}