blob: b0fd4b684192366fecb95d04131f9b3b31a9364a [file] [log] [blame]
Dhruv Dhody43f3ce62016-02-16 22:44:21 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Dhruv Dhody43f3ce62016-02-16 22:44:21 +05303 *
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.ospf.protocol.lsa.types;
17
18import com.google.common.base.MoreObjects;
19import com.google.common.base.Objects;
20import com.google.common.primitives.Bytes;
21import org.jboss.netty.buffer.ChannelBuffer;
22import org.onosproject.ospf.controller.OspfLsaType;
23import org.onosproject.ospf.exceptions.OspfErrorType;
24import org.onosproject.ospf.exceptions.OspfParseException;
25import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
26import org.onosproject.ospf.protocol.lsa.TlvHeader;
27import org.onosproject.ospf.protocol.lsa.tlvtypes.LinkTlv;
28import org.onosproject.ospf.protocol.lsa.tlvtypes.OpaqueTopLevelTlvTypes;
29import org.onosproject.ospf.protocol.lsa.tlvtypes.RouterTlv;
30import org.onosproject.ospf.protocol.util.OspfParameters;
31
32import java.util.ArrayList;
kdarapue4da4a02017-01-04 15:00:14 +053033import java.util.Arrays;
Dhruv Dhody43f3ce62016-02-16 22:44:21 +053034import java.util.List;
35
36/**
37 * Representation of an Opaque LSA of type area local (10).
38 */
39public class OpaqueLsa10 extends OpaqueLsaHeader {
40 /*
41 0 1 2 3
42 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
43 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 | LS age | Options | 9, 10 or 11 |
45 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 | Opaque Type | Opaque ID |
47 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 | Advertising Router |
49 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 | LS Sequence Number |
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | LS checksum | Length |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 | |
55 + +
56 | Opaque Information |
57 + +
58 | ... |
59
60 Opaque LSA format
61 REFERENCE : RFC 5250
62 */
63 private List<TopLevelTlv> topLevelValues = new ArrayList<>();
64 private byte[] opaqueInfo = null;
65
66 /**
67 * Creates an instance of Opaque type 10 LSA.
68 *
69 * @param lsaHeader LSA header instance
70 */
71 public OpaqueLsa10(OpaqueLsaHeader lsaHeader) {
72 populateHeader(lsaHeader);
73 }
74
75 /**
76 * Returns the list of top level TLVs.
77 *
78 * @return list of top level TLVs
79 */
80 public List<TopLevelTlv> topLevelValues() {
81 return topLevelValues;
82 }
83
84 /**
85 * Adds TLV value.
86 *
87 * @param value TLV value
88 */
89 public void addValue(TopLevelTlv value) {
90 topLevelValues.add(value);
91 }
92
93 /**
94 * Reads from channel buffer and populate instance.
95 *
96 * @param channelBuffer channelBuffer instance
97 * @throws OspfParseException might throws exception while parsing buffer
98 */
99 public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {
100
101 try {
102 if (this.opaqueId() == OspfParameters.TRAFFIC_ENGINEERING) {
103 while (channelBuffer.readableBytes() > 0) {
104 TlvHeader tlvHeader = new TlvHeader();
105 tlvHeader.setTlvType(channelBuffer.readUnsignedShort());
106 tlvHeader.setTlvLength(channelBuffer.readUnsignedShort());
107 if (tlvHeader.tlvType() == OpaqueTopLevelTlvTypes.ROUTER.value()) {
108 RouterTlv routerTlv = new RouterTlv(tlvHeader);
109 routerTlv.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
110 this.addValue(routerTlv);
111 } else if (tlvHeader.tlvType() == OpaqueTopLevelTlvTypes.LINK.value()) {
112 LinkTlv linkTlv = new LinkTlv(tlvHeader);
113 linkTlv.readFrom(channelBuffer.readBytes(tlvHeader.tlvLength()));
114 this.addValue(linkTlv);
115 }
116 }
117 } else {
118 int length = channelBuffer.readableBytes();
119 opaqueInfo = new byte[length];
120 channelBuffer.readBytes(opaqueInfo, 0, length);
121 }
122
123 } catch (Exception e) {
124 log.debug("Error::OpaqueLsa10:: {}", e.getMessage());
125 throw new OspfParseException(OspfErrorType.OSPF_MESSAGE_ERROR,
126 OspfErrorType.BAD_MESSAGE);
127 }
128 }
129
130 /**
131 * Returns instance as bytes.
132 *
133 * @return instance as bytes
Ray Milkey019fba42018-01-31 14:07:47 -0800134 * @throws OspfParseException might throws exception while parsing packet
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530135 */
Ray Milkey019fba42018-01-31 14:07:47 -0800136 public byte[] asBytes() throws OspfParseException {
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530137
138 byte[] lsaMessage = null;
139 byte[] lsaHeader = getOpaqueLsaHeaderAsByteArray();
140 byte[] lsaBody = getLsaBodyAsByteArray();
141 lsaMessage = Bytes.concat(lsaHeader, lsaBody);
142 return lsaMessage;
143
144 }
145
146 /**
147 * Gets the LSA body as byte array.
148 *
149 * @return the lsa body as byte array
Ray Milkey019fba42018-01-31 14:07:47 -0800150 * @throws OspfParseException might throws exception while parsing packet
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530151 */
Ray Milkey019fba42018-01-31 14:07:47 -0800152 public byte[] getLsaBodyAsByteArray() throws OspfParseException {
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530153 List<Byte> bodyLst = new ArrayList<>();
154 if (this.opaqueId() == 1) {
155 for (TopLevelTlv tlv : this.topLevelValues) {
156 //Check the sub type of lsa and build bytes accordingly
157 if (tlv instanceof RouterTlv) {
158 RouterTlv routerTlv = (RouterTlv) tlv;
159 bodyLst.addAll(Bytes.asList(routerTlv.asBytes()));
160 } else if (tlv instanceof LinkTlv) {
161 LinkTlv linkTlv = (LinkTlv) tlv;
162 bodyLst.addAll(Bytes.asList(linkTlv.asBytes()));
163 }
164 }
165 } else {
166 return opaqueInfo;
167 }
168
169 return Bytes.toArray(bodyLst);
170 }
171
172 @Override
173 public OspfLsaType getOspfLsaType() {
174 return OspfLsaType.AREA_LOCAL_OPAQUE_LSA;
175 }
176
177 @Override
178 public String toString() {
179 return MoreObjects.toStringHelper(getClass())
180 .omitNullValues()
181 .add("topLevelValues", topLevelValues)
182 .add("opaqueInfo", opaqueInfo)
183 .toString();
184 }
185
186 @Override
187 public boolean equals(Object o) {
188 if (this == o) {
189 return true;
190 }
191 if (o == null || getClass() != o.getClass()) {
192 return false;
193 }
194 OpaqueLsa10 that = (OpaqueLsa10) o;
195 return Objects.equal(topLevelValues, that.topLevelValues) &&
kdarapue4da4a02017-01-04 15:00:14 +0530196 Arrays.equals(opaqueInfo, that.opaqueInfo);
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530197 }
198
199 @Override
200 public int hashCode() {
kdarapuf0da43d2017-01-04 16:31:45 +0530201 return Objects.hashCode(Arrays.hashCode(opaqueInfo), topLevelValues);
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530202 }
203}