blob: 0b33c45210e196292c34f869c94d08a3ae26325c [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
alshabib7911a052014-10-16 17:49:37 -070016package org.onlab.packet;
17
18import com.google.common.collect.Lists;
19import org.apache.commons.lang.ArrayUtils;
20
21import java.nio.ByteBuffer;
22
23/**
24 * ONOS LLDP containing organizational TLV for ONOS device dicovery.
25 */
26public class ONOSLLDP extends LLDP {
27
28 public static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05};
29 public static final String DEFAULT_DEVICE = "INVALID";
30 public static final String DEFAULT_NAME = "ONOS Discovery";
31
32 public static final byte[] LLDP_NICIRA = {0x01, 0x23, 0x20, 0x00, 0x00,
33 0x01};
34 public static final byte[] LLDP_MULTICAST = {0x01, (byte) 0x80,
35 (byte) 0xc2, 0x00, 0x00, 0x0e};
36 public static final byte[] BDDP_MULTICAST = {(byte) 0xff, (byte) 0xff,
37 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
38
39 private static final byte NAME_SUBTYPE = 1;
40 private static final byte DEVICE_SUBTYPE = 2;
41 private static final short NAME_LENGTH = 4; //1 for subtype + 3 for OUI
42 private static final short DEVICE_LENGTH = 4; //1 for subtype + 3 for OUI
43 private final LLDPOrganizationalTLV nameTLV = new LLDPOrganizationalTLV();
44 private final LLDPOrganizationalTLV deviceTLV = new LLDPOrganizationalTLV();
45
46 // TLV constants: type, size and subtype
47 // Organizationally specific TLV also have packet offset and contents of TLV
48 // header
49 private static final byte CHASSIS_TLV_TYPE = 1;
50 private static final byte CHASSIS_TLV_SIZE = 7;
51 private static final byte CHASSIS_TLV_SUBTYPE = 4;
52
53 private static final byte PORT_TLV_TYPE = 2;
54 private static final byte PORT_TLV_SIZE = 5;
55 private static final byte PORT_TLV_SUBTYPE = 2;
56
57 private static final byte TTL_TLV_TYPE = 3;
58
59
60 private final byte[] ttlValue = new byte[] {0, 0x78};
61
62 public ONOSLLDP() {
63 super();
64 setName(DEFAULT_NAME);
65 setDevice(DEFAULT_DEVICE);
66 setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV));
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -080067 setTtl(new LLDPTLV().setType(TTL_TLV_TYPE)
alshabib7911a052014-10-16 17:49:37 -070068 .setLength((short) ttlValue.length)
69 .setValue(ttlValue));
70
71 }
72
73 private ONOSLLDP(LLDP lldp) {
74 this.portId = lldp.getPortId();
75 this.chassisId = lldp.getChassisId();
76 this.ttl = lldp.getTtl();
77 this.optionalTLVList = lldp.getOptionalTLVList();
78 }
79
80 public void setName(String name) {
81 nameTLV.setLength((short) (name.length() + NAME_LENGTH));
82 nameTLV.setInfoString(name);
83 nameTLV.setSubType(NAME_SUBTYPE);
84 nameTLV.setOUI(ONLAB_OUI);
85 }
86
87 public void setDevice(String device) {
88 deviceTLV.setInfoString(device);
89 deviceTLV.setLength((short) (device.length() + DEVICE_LENGTH));
90 deviceTLV.setSubType(DEVICE_SUBTYPE);
91 deviceTLV.setOUI(ONLAB_OUI);
92 }
93
94 public void setChassisId(final ChassisId chassisId) {
95 MacAddress chassisMac = MacAddress.valueOf(chassisId.value());
96 byte[] chassis = ArrayUtils.addAll(new byte[] {CHASSIS_TLV_SUBTYPE},
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -080097 chassisMac.toBytes());
alshabib7911a052014-10-16 17:49:37 -070098
99 LLDPTLV chassisTLV = new LLDPTLV();
100 chassisTLV.setLength(CHASSIS_TLV_SIZE);
101 chassisTLV.setType(CHASSIS_TLV_TYPE);
102 chassisTLV.setValue(chassis);
103 this.setChassisId(chassisTLV);
104 }
105
106 public void setPortId(final int portNumber) {
107 byte[] port = ArrayUtils.addAll(new byte[] {PORT_TLV_SUBTYPE},
108 ByteBuffer.allocate(4).putInt(portNumber).array());
109
110 LLDPTLV portTLV = new LLDPTLV();
111 portTLV.setLength(PORT_TLV_SIZE);
112 portTLV.setType(PORT_TLV_TYPE);
113 portTLV.setValue(port);
114 this.setPortId(portTLV);
115 }
116
117 public LLDPOrganizationalTLV getNameTLV() {
118 for (LLDPTLV tlv : this.getOptionalTLVList()) {
119 if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
120 LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv;
121 if (orgTLV.getSubType() == NAME_SUBTYPE) {
122 return orgTLV;
123 }
124 }
125 }
126 return null;
127 }
128
129 public LLDPOrganizationalTLV getDeviceTLV() {
130 for (LLDPTLV tlv : this.getOptionalTLVList()) {
131 if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) {
132 LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv;
133 if (orgTLV.getSubType() == DEVICE_SUBTYPE) {
134 return orgTLV;
135 }
136 }
137 }
138 return null;
139 }
140
141 public String getNameString() {
142 LLDPOrganizationalTLV tlv = getNameTLV();
143 if (tlv != null) {
144 return new String(tlv.getInfoString());
145 }
146 return null;
147 }
148
149 public String getDeviceString() {
150 LLDPOrganizationalTLV tlv = getDeviceTLV();
151 if (tlv != null) {
152 return new String(tlv.getInfoString());
153 }
154 return null;
155 }
156
157 public Integer getPort() {
158 ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue());
159 portBB.position(1);
160 return portBB.getInt();
161 }
162
163 /**
164 * Given an ethernet packet, determines if this is an LLDP from
165 * ONOS and returns the device the LLDP came from.
166 * @param eth an ethernet packet
167 * @return a the lldp packet or null
168 */
169 public static ONOSLLDP parseONOSLLDP(Ethernet eth) {
170 if (eth.getEtherType() == Ethernet.TYPE_LLDP ||
171 eth.getEtherType() == Ethernet.TYPE_BSN) {
172 ONOSLLDP onosLldp = new ONOSLLDP((LLDP) eth.getPayload()); //(ONOSLLDP) eth.getPayload();
173 if (ONOSLLDP.DEFAULT_NAME.equals(onosLldp.getNameString())) {
174 return onosLldp;
175 }
176 }
177 return null;
178 }
179
180
181
182
183
184}