blob: 41ab3da060bb4aaeeb13d6d313210753304bcc7b [file] [log] [blame]
Dhruv Dhody43f3ce62016-02-16 22:44:21 +05301/*
2 * Copyright 2016 Open Networking Laboratory
3 *
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.ospfpacket.types;
17
18import com.google.common.base.MoreObjects;
19import com.google.common.primitives.Bytes;
20import org.jboss.netty.buffer.ChannelBuffer;
21import org.onosproject.ospf.controller.OspfLsa;
22import org.onosproject.ospf.exceptions.OspfErrorType;
23import org.onosproject.ospf.exceptions.OspfParseException;
24import org.onosproject.ospf.protocol.lsa.LsaHeader;
25import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
26import org.onosproject.ospf.protocol.lsa.types.AsbrSummaryLsa;
27import org.onosproject.ospf.protocol.lsa.types.ExternalLsa;
28import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
29import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
30import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa11;
31import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa9;
32import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
33import org.onosproject.ospf.protocol.lsa.types.SummaryLsa;
34import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
35import org.onosproject.ospf.protocol.util.OspfPacketType;
36import org.onosproject.ospf.protocol.util.OspfParameters;
37import org.onosproject.ospf.protocol.util.OspfUtil;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41import java.util.ArrayList;
42import java.util.LinkedList;
43import java.util.List;
44
45/**
46 * Representation of an OSPF Link State Update packet.
47 * Link State Update packets are OSPF packet type 4. These packets
48 * implement the flooding of LSAs. Each Link State Update packet
49 * carries a collection of LSAs one hop further from their origin.
50 * Several LSAs may be included in a single packet.
51 */
52public class LsUpdate extends OspfPacketHeader {
53 /*
54 0 1 2 3
55 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
56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 | Version # | 4 | Packet length |
58 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 | Router ID |
60 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 | Area ID |
62 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 | Checksum | AuType |
64 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65 | Authentication |
66 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 | Authentication |
68 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 | # LSAs |
70 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71 | |
72 +- +-+
73 | LSAs |
74 +- +-+
75 | ... |
76 */
77 private static final Logger log = LoggerFactory.getLogger(LsUpdate.class);
78 private int numberOfLsa;
79 private List<OspfLsa> lsaList = new LinkedList<>();
80
81 /**
82 * Creates an instance of Link State Update packet.
83 */
84 public LsUpdate() {
85 }
86
87 /**
88 * Creates an instance of Link State Update packet.
89 *
90 * @param ospfHeader ospf header instance.
91 */
92 public LsUpdate(OspfPacketHeader ospfHeader) {
93 populateHeader(ospfHeader);
94 }
95
96 /**
97 * Gets the LSA list.
98 *
99 * @return list of LSA
100 */
101 public List getLsaList() {
102 return lsaList;
103 }
104
105 /**
106 * Adds the LSA to list.
107 *
108 * @param lsa LSA
109 */
110 public void addLsa(OspfLsa lsa) {
111 if (!lsaList.contains(lsa)) {
112 lsaList.add(lsa);
113 }
114 }
115
116 /**
117 * Gets the number of LSA.
118 *
119 * @return number of LSA
120 */
121 public int noLsa() {
122 return numberOfLsa;
123 }
124
125 /**
126 * Sets number of LSA.
127 *
128 * @param numberOfLsa number of LSA
129 */
130 public void setNumberOfLsa(int numberOfLsa) {
131 this.numberOfLsa = numberOfLsa;
132 }
133
134
135 @Override
136 public OspfPacketType ospfMessageType() {
137 return OspfPacketType.LSUPDATE;
138 }
139
140 @Override
141 public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {
142 try {
143 //From header 4 bytes is number of lsa's
144 this.setNumberOfLsa(channelBuffer.readInt());
145 //get the remaining bytes represents Number of LSA's present. Add all the LSA's
146 while (channelBuffer.readableBytes() > OspfUtil.LSA_HEADER_LENGTH) {
147
148 LsaHeader header = OspfUtil.readLsaHeader(channelBuffer.readBytes(OspfUtil.LSA_HEADER_LENGTH));
149 int lsaLength = header.lsPacketLen();
150 int lsType = header.lsType();
151
152 switch (lsType) {
153 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
154 OpaqueLsa9 opaqueLsa9 = new OpaqueLsa9((OpaqueLsaHeader) header);
155 opaqueLsa9.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
156 addLsa(opaqueLsa9);
157 break;
158 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
159 OpaqueLsa10 opaqueLsa10 = new OpaqueLsa10((OpaqueLsaHeader) header);
160 opaqueLsa10.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
161 addLsa(opaqueLsa10);
162 break;
163 case OspfParameters.AS_OPAQUE_LSA:
164 OpaqueLsa11 opaqueLsa11 = new OpaqueLsa11((OpaqueLsaHeader) header);
165 opaqueLsa11.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
166 addLsa(opaqueLsa11);
167 break;
168 case OspfParameters.ROUTER:
169 RouterLsa routerLsa = new RouterLsa(header);
170 routerLsa.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
171 addLsa(routerLsa);
172 break;
173 case OspfParameters.NETWORK:
174 NetworkLsa networkLsa = new NetworkLsa(header);
175 networkLsa.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
176 addLsa(networkLsa);
177 break;
178 case OspfParameters.ASBR_SUMMARY:
179 AsbrSummaryLsa asbrSummaryLsa = new AsbrSummaryLsa(header);
180 asbrSummaryLsa.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
181 addLsa(asbrSummaryLsa);
182 break;
183 case OspfParameters.SUMMARY:
sunish vkaa48da82016-03-02 23:17:06 +0530184 SummaryLsa summaryLsa = new SummaryLsa(header);
185 summaryLsa.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
186 addLsa(summaryLsa);
Dhruv Dhody43f3ce62016-02-16 22:44:21 +0530187 break;
188 case OspfParameters.EXTERNAL_LSA:
189 ExternalLsa externalLsa = new ExternalLsa(header);
190 externalLsa.readFrom(channelBuffer.readBytes(lsaLength - OspfUtil.LSA_HEADER_LENGTH));
191 addLsa(externalLsa);
192 break;
193 default:
194 log.debug("LSUpdate::readLsUpdateBody::UnKnown LS Type: {}", lsType);
195 break;
196 }
197 }
198 } catch (Exception e) {
199 log.debug("Error::LsUpdate:: {}", e.getMessage());
200 throw new OspfParseException(OspfErrorType.MESSAGE_HEADER_ERROR, OspfErrorType.BAD_MESSAGE_LENGTH);
201 }
202 }
203
204 @Override
205 public byte[] asBytes() {
206 byte[] lsuMessage = null;
207
208 byte[] ospfHeader = getLsuHeaderAsByteArray();
209 byte[] lsuBody = getLsuBodyAsByteArray();
210 lsuMessage = Bytes.concat(ospfHeader, lsuBody);
211
212 return lsuMessage;
213 }
214
215 /**
216 * Gets lsu header.
217 *
218 * @return lsu header as byte array
219 */
220 public byte[] getLsuHeaderAsByteArray() {
221 List<Byte> headerLst = new ArrayList<>();
222 try {
223 headerLst.add((byte) this.ospfVersion());
224 headerLst.add((byte) this.ospfType());
225 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.ospfPacLength())));
226 headerLst.addAll(Bytes.asList(this.routerId().toOctets()));
227 headerLst.addAll(Bytes.asList(this.areaId().toOctets()));
228 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.checksum())));
229 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.authType())));
230 //Authentication is 0 always. Total 8 bytes consist of zero
231 byte[] auth = new byte[OspfUtil.EIGHT_BYTES];
232 headerLst.addAll(Bytes.asList(auth));
233 } catch (Exception e) {
234 log.debug("Error::LSUpdate::getLsuHeaderAsByteArray:: {}", e.getMessage());
235 return Bytes.toArray(headerLst);
236 }
237
238 return Bytes.toArray(headerLst);
239 }
240
241 /**
242 * Get lsu body as byte array.
243 *
244 * @return lsu body as byte array
245 */
246 public byte[] getLsuBodyAsByteArray() {
247 List<Byte> bodyLst = new ArrayList<>();
248
249 try {
250 //add number of LSA's
251 bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(this.noLsa())));
252 //for each type of LSA's from the list get lsa bytes
253 for (OspfLsa ospfLsa : lsaList) {
254 //Check the type of lsa and build bytes accordingly
255 switch (ospfLsa.getOspfLsaType().value()) {
256 case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
257 OpaqueLsa9 opaqueLsa9 = (OpaqueLsa9) ospfLsa;
258 bodyLst.addAll(Bytes.asList(opaqueLsa9.asBytes()));
259 break;
260 case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
261 OpaqueLsa10 opaqueLsa10 = (OpaqueLsa10) ospfLsa;
262 bodyLst.addAll(Bytes.asList(opaqueLsa10.asBytes()));
263 break;
264 case OspfParameters.AS_OPAQUE_LSA:
265 OpaqueLsa11 opaqueLsa11 = (OpaqueLsa11) ospfLsa;
266 bodyLst.addAll(Bytes.asList(opaqueLsa11.asBytes()));
267 break;
268 case OspfParameters.ROUTER:
269 RouterLsa routerLsa = (RouterLsa) ospfLsa;
270 bodyLst.addAll(Bytes.asList(routerLsa.asBytes()));
271 break;
272 case OspfParameters.NETWORK:
273 NetworkLsa networkLsa = (NetworkLsa) ospfLsa;
274 bodyLst.addAll(Bytes.asList(networkLsa.asBytes()));
275 break;
276 case OspfParameters.ASBR_SUMMARY:
277 AsbrSummaryLsa asbrSummaryLsa = (AsbrSummaryLsa) ospfLsa;
278 bodyLst.addAll(Bytes.asList(asbrSummaryLsa.asBytes()));
279 break;
280 case OspfParameters.SUMMARY:
281 SummaryLsa summaryLsa = (SummaryLsa) ospfLsa;
282 bodyLst.addAll(Bytes.asList(summaryLsa.asBytes()));
283 break;
284 case OspfParameters.EXTERNAL_LSA:
285 ExternalLsa externalLsa = (ExternalLsa) ospfLsa;
286 bodyLst.addAll(Bytes.asList(externalLsa.asBytes()));
287 break;
288 default:
289 log.debug("LSUpdate::getLsuBodyAsByteArray::UnKnown ospfLsa: {}", ospfLsa);
290 break;
291 }
292 }
293
294 } catch (Exception e) {
295 log.debug("Error::getLsuBodyAsByteArray {}", e.getMessage());
296 return Bytes.toArray(bodyLst);
297 }
298
299 return Bytes.toArray(bodyLst);
300 }
301
302 @Override
303 public String toString() {
304 return MoreObjects.toStringHelper(getClass())
305 .omitNullValues()
306 .add("noLsa", numberOfLsa)
307 .add("lsaList", lsaList)
308 .toString();
309 }
310}