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