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