blob: 2c172f96469d87b559127e05206df3d6a48d8f2f [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07003 *
4 * 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
7 *
8 * 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.
15 */
16package org.onosproject.pcepio.types;
17
18import java.util.Iterator;
19import java.util.LinkedList;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053020import java.util.List;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070021import java.util.ListIterator;
22import java.util.Objects;
23
24import org.jboss.netty.buffer.ChannelBuffer;
25import org.onosproject.pcepio.exceptions.PcepParseException;
26import org.onosproject.pcepio.protocol.PcepVersion;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import com.google.common.base.MoreObjects;
31
32/**
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053033 * Provides LinkAttributesTlv.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070034 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053035public class LinkAttributesTlv implements PcepValueType {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070036
37 /*
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053038 * Reference :draft-dhodylee-pce-pcep-ls-01, section 9.2.8.2.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070039 * 0 1 2 3
40 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
41 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 | Type=[TBD27] | Length |
43 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 | |
45 // Link Attributes Sub-TLVs (variable) //
46 | |
47 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 */
49
Ray Milkey9c9cde42018-01-12 14:22:06 -080050 private static final Logger log = LoggerFactory.getLogger(LinkAttributesTlv.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070051
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053052 public static final short TYPE = (short) 65286;
Ray Milkeye4afdb52017-04-05 09:42:04 -070053 short hLength;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070054
55 public static final int TLV_HEADER_LENGTH = 4;
56
57 // LinkDescriptors Sub-TLVs (variable)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053058 private List<PcepValueType> llLinkAttributesSubTLVs;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070059
60 /**
61 * Constructor to initialize Link Attributes Sub TLVs.
62 *
63 * @param llLinkAttributesSubTLVs linked list of PcepValueType
64 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053065 public LinkAttributesTlv(List<PcepValueType> llLinkAttributesSubTLVs) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070066 this.llLinkAttributesSubTLVs = llLinkAttributesSubTLVs;
67 }
68
69 /**
70 * Returns object of TE Link Attributes TLV.
71 *
72 * @param llLinkAttributesSubTLVs linked list of Link Attribute of Sub TLV
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053073 * @return object of LinkAttributesTlv
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070074 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053075 public static LinkAttributesTlv of(final List<PcepValueType> llLinkAttributesSubTLVs) {
76 return new LinkAttributesTlv(llLinkAttributesSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070077 }
78
79 /**
80 * Returns linked list of Link Attribute of Sub TLV.
81 *
82 * @return llLinkAttributesSubTLVs linked list of Link Attribute of Sub TLV
83 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053084 public List<PcepValueType> getllLinkAttributesSubTLVs() {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070085 return llLinkAttributesSubTLVs;
86 }
87
88 @Override
89 public PcepVersion getVersion() {
90 return PcepVersion.PCEP_1;
91 }
92
93 @Override
94 public short getType() {
95 return TYPE;
96 }
97
98 @Override
99 public short getLength() {
100 return hLength;
101 }
102
103 @Override
104 public int hashCode() {
105 return Objects.hash(llLinkAttributesSubTLVs.hashCode());
106 }
107
108 @Override
109 public boolean equals(Object obj) {
110 if (this == obj) {
111 return true;
112 }
113 /*
114 * Here we have a list of Tlv so to compare each sub tlv between the object
115 * we have to take a list iterator so one by one we can get each sub tlv object
116 * and can compare them.
117 * it may be possible that the size of 2 lists is not equal so we have to first check
118 * the size, if both are same then we should check for the subtlv objects otherwise
119 * we should return false.
120 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530121 if (obj instanceof LinkAttributesTlv) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700122 int countObjSubTlv = 0;
123 int countOtherSubTlv = 0;
124 boolean isCommonSubTlv = true;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530125 LinkAttributesTlv other = (LinkAttributesTlv) obj;
126 Iterator<PcepValueType> objListIterator = ((LinkAttributesTlv) obj).llLinkAttributesSubTLVs.iterator();
127 countObjSubTlv = ((LinkAttributesTlv) obj).llLinkAttributesSubTLVs.size();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700128 countOtherSubTlv = other.llLinkAttributesSubTLVs.size();
129 if (countObjSubTlv != countOtherSubTlv) {
130 return false;
131 } else {
132 while (objListIterator.hasNext() && isCommonSubTlv) {
133 PcepValueType subTlv = objListIterator.next();
134 isCommonSubTlv = Objects.equals(llLinkAttributesSubTLVs.contains(subTlv),
135 other.llLinkAttributesSubTLVs.contains(subTlv));
136 }
137 return isCommonSubTlv;
138 }
139 }
140 return false;
141 }
142
143 @Override
144 public int write(ChannelBuffer c) {
145 int tlvStartIndex = c.writerIndex();
146 c.writeShort(TYPE);
147 int tlvLenIndex = c.writerIndex();
148 hLength = 0;
149 c.writeShort(hLength);
150
151 ListIterator<PcepValueType> listIterator = llLinkAttributesSubTLVs.listIterator();
152
153 while (listIterator.hasNext()) {
154 PcepValueType tlv = listIterator.next();
155
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700156 if (tlv == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700157 log.debug("TLV is null from subTlv list");
158 continue;
159 }
160 tlv.write(c);
161
162 // need to take care of padding
163 int pad = tlv.getLength() % 4;
164
165 if (0 != pad) {
166 pad = 4 - pad;
167 for (int i = 0; i < pad; ++i) {
168 c.writeByte((byte) 0);
169 }
170 }
171 }
172
173 hLength = (short) (c.writerIndex() - tlvStartIndex);
174 c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
175
176 return c.writerIndex() - tlvStartIndex;
177 }
178
179 /**
180 * Reads channel buffer and returns object of TE Link Attributes TLV.
181 *
182 * @param c input channel buffer
183 * @param hLength length
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530184 * @return object of LinkAttributesTlv
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700185 * @throws PcepParseException if mandatory fields are missing
186 */
187 public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
188
189 // Node Descriptor Sub-TLVs (variable)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530190 List<PcepValueType> llLinkAttributesSubTLVs = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700191
192 ChannelBuffer tempCb = c.readBytes(hLength);
193
194 while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
195
196 PcepValueType tlv;
197 short hType = tempCb.readShort();
198 int iValue = 0;
199 short length = tempCb.readShort();
200 switch (hType) {
201
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530202 case IPv4RouterIdOfLocalNodeSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700203 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530204 tlv = new IPv4RouterIdOfLocalNodeSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700205 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530206 case IPv6RouterIdofLocalNodeSubTlv.TYPE:
207 byte[] ipv6LValue = new byte[IPv6RouterIdofLocalNodeSubTlv.VALUE_LENGTH];
208 tempCb.readBytes(ipv6LValue, 0, IPv6RouterIdofLocalNodeSubTlv.VALUE_LENGTH);
209 tlv = new IPv6RouterIdofLocalNodeSubTlv(ipv6LValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700210 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530211 case IPv4RouterIdOfRemoteNodeSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700212 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530213 tlv = new IPv4RouterIdOfRemoteNodeSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700214 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530215 case IPv6RouterIdofRemoteNodeSubTlv.TYPE:
216 byte[] ipv6RValue = new byte[IPv6RouterIdofRemoteNodeSubTlv.VALUE_LENGTH];
217 tempCb.readBytes(ipv6RValue, 0, IPv6RouterIdofRemoteNodeSubTlv.VALUE_LENGTH);
218 tlv = new IPv6RouterIdofRemoteNodeSubTlv(ipv6RValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700219 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530220 case LinkLocalRemoteIdentifiersSubTlv.TYPE:
221 tlv = LinkLocalRemoteIdentifiersSubTlv.read(tempCb);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700222 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530223 case AdministrativeGroupSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700224 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530225 tlv = new AdministrativeGroupSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700226 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530227 case MaximumLinkBandwidthSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700228 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530229 tlv = new MaximumLinkBandwidthSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700230 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530231 case MaximumReservableLinkBandwidthSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700232 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530233 tlv = new MaximumReservableLinkBandwidthSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700234 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530235 case UnreservedBandwidthSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700236 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530237 tlv = new UnreservedBandwidthSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700238 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530239 case TEDefaultMetricSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700240 iValue = tempCb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530241 tlv = new TEDefaultMetricSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700242 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530243 case LinkProtectionTypeSubTlv.TYPE:
244 tlv = LinkProtectionTypeSubTlv.read(tempCb);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700245 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530246 case MplsProtocolMaskSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700247 byte cValue = tempCb.readByte();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530248 tlv = new MplsProtocolMaskSubTlv(cValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700249 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530250 case IgpMetricSubTlv.TYPE:
251 tlv = IgpMetricSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700252 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530253 case SharedRiskLinkGroupSubTlv.TYPE:
254 tlv = SharedRiskLinkGroupSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700255 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530256 case OpaqueLinkAttributeSubTlv.TYPE:
257 tlv = OpaqueLinkAttributeSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700258 break;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530259 case LinkNameAttributeSubTlv.TYPE:
260 tlv = LinkNameAttributeSubTlv.read(tempCb, length);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700261 break;
262 default:
263 throw new PcepParseException("Unsupported Sub TLV type :" + hType);
264 }
265
266 // Check for the padding
267 int pad = length % 4;
268 if (0 < pad) {
269 pad = 4 - pad;
270 if (pad <= tempCb.readableBytes()) {
271 tempCb.skipBytes(pad);
272 }
273 }
274 llLinkAttributesSubTLVs.add(tlv);
275 }
276
277 if (0 < tempCb.readableBytes()) {
278
279 throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
280 }
281
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530282 return new LinkAttributesTlv(llLinkAttributesSubTLVs);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700283 }
284
285 @Override
286 public String toString() {
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700287 return MoreObjects.toStringHelper(getClass())
288 .add("Type", TYPE)
289 .add("Length", hLength)
290 .add("LinkAttributesSubTLVs", llLinkAttributesSubTLVs)
291 .toString();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700292 }
293}