blob: 3de74e4411cd083730d1697b0d34ae2ba2ab5ec2 [file] [log] [blame]
Manicdb26412016-02-16 19:44:34 +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.exceptions.OspfErrorType;
22import org.onosproject.ospf.exceptions.OspfParseException;
23import org.onosproject.ospf.protocol.lsa.LsaHeader;
24import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
25import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
26import org.onosproject.ospf.protocol.util.OspfPacketType;
27import org.onosproject.ospf.protocol.util.OspfParameters;
28import org.onosproject.ospf.protocol.util.OspfUtil;
29import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import java.util.ArrayList;
33import java.util.List;
34
35/**
36 * Representation of an OSPF Link State Acknowledgment Message.
37 * Link State Acknowledgment Packets are OSPF packet type 5.
38 * To make the flooding of LSAs reliable, flooded LSAs are explicitly
39 * acknowledged. This acknowledgment is accomplished through the
40 * sending and receiving of Link State Acknowledgment packets.
41 * Multiple LSAs can be acknowledged in a single Link State Acknowledgment packet.
42 */
43public class LsAcknowledge extends OspfPacketHeader {
44 /*
45 0 1 2 3
46 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
47 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 | Version # | 5 | Packet length |
49 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 | Router ID |
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | Area ID |
53 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 | Checksum | AuType |
55 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 | Authentication |
57 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 | Authentication |
59 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 | |
61 +- -+
62 | |
63 +- An LSA Header -+
64 | |
65 +- -+
66 | |
67 +- -+
68 | |
69 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 | ... |
71 */
72 private static final Logger log = LoggerFactory.getLogger(LsAcknowledge.class);
73 private List<LsaHeader> linkStateHeaders = new ArrayList<>();
74
75 /**
76 * Creates an instance of Link State Acknowledgment instance.
77 */
78 public LsAcknowledge() {
79 }
80
81 /**
82 * Creates an instance of Link State Acknowledgment instance.
83 *
84 * @param ospfHeader OSPF header instance.
85 */
86 public LsAcknowledge(OspfPacketHeader ospfHeader) {
87 populateHeader(ospfHeader);
88 }
89
90 /**
91 * Gets ls headers.
92 *
93 * @return ls headers
94 */
95 public List<LsaHeader> getLinkStateHeaders() {
96 return linkStateHeaders;
97 }
98
99 /**
100 * Adds link state header to list.
101 *
102 * @param lsaHeader LSA header
103 */
104 public void addLinkStateHeader(LsaHeader lsaHeader) {
105 if (!linkStateHeaders.contains(lsaHeader)) {
106 linkStateHeaders.add(lsaHeader);
107 }
108 }
109
110 @Override
111 public OspfPacketType ospfMessageType() {
112 return OspfPacketType.LSAACK;
113 }
114
115 @Override
116 public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {
117 try {
118 //add all the LSA Headers - one header is of 20 bytes
119 while (channelBuffer.readableBytes() >= OspfUtil.LSA_HEADER_LENGTH) {
120 LsaHeader header = OspfUtil.readLsaHeader(channelBuffer);
121 //add the LSAHeader to acknowledge
122 addLinkStateHeader(header);
123 }
124
125 } catch (Exception e) {
126 log.debug("Error::LsAckPacket:: {}", e.getMessage());
127 throw new OspfParseException(OspfErrorType.MESSAGE_HEADER_ERROR, OspfErrorType.BAD_MESSAGE_LENGTH);
128 }
129 }
130
131 @Override
132 public byte[] asBytes() {
133 byte[] lsAckMessage = null;
134
135 byte[] lsAckHeader = getLsAckAsByteArray();
136 byte[] lsAckBody = getLsAckBodyAsByteArray();
137 lsAckMessage = Bytes.concat(lsAckHeader, lsAckBody);
138
139 return lsAckMessage;
140 }
141
142 /**
143 * Gets LSAcknowledge as byte array.
144 *
145 * @return byte array
146 */
147 public byte[] getLsAckAsByteArray() {
148 List<Byte> headerLst = new ArrayList<>();
149 try {
150 headerLst.add((byte) this.ospfVersion());
151 headerLst.add((byte) this.ospfType());
152 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.ospfPacLength())));
153 headerLst.addAll(Bytes.asList(this.routerId().toOctets()));
154 headerLst.addAll(Bytes.asList(this.areaId().toOctets()));
155 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.checksum())));
156 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.authType())));
157 //Authentication is 0 always. Total 8 bytes consist of zero
158 byte[] auth = new byte[OspfUtil.EIGHT_BYTES];
159 headerLst.addAll(Bytes.asList(auth));
160 } catch (Exception e) {
161 log.debug("Error::LsAckPacket:: {}", e.getMessage());
162 return Bytes.toArray(headerLst);
163 }
164
165 return Bytes.toArray(headerLst);
166 }
167
168 /**
169 * Gets LsAck body as byte array.
170 *
171 * @return byte array
172 */
173 public byte[] getLsAckBodyAsByteArray() {
174 List<Byte> bodyLst = new ArrayList<>();
175
176 try {
177 for (LsaHeader lsaHeader : linkStateHeaders) {
178 if (lsaHeader.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
179 lsaHeader.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
180 lsaHeader.lsType() == OspfParameters.AS_OPAQUE_LSA) {
181 OpaqueLsaHeader header = (OpaqueLsaHeader) lsaHeader;
182 bodyLst.addAll(Bytes.asList(header.getOpaqueLsaHeaderAsByteArray()));
183 } else {
184 bodyLst.addAll(Bytes.asList(lsaHeader.getLsaHeaderAsByteArray()));
185 }
186 }
187 } catch (Exception e) {
188 log.debug("Error::getLsAckBodyAsByteArray {}", e.getMessage());
189 return Bytes.toArray(bodyLst);
190 }
191
192 return Bytes.toArray(bodyLst);
193 }
194
195 @Override
196 public String toString() {
197 return MoreObjects.toStringHelper(getClass())
198 .omitNullValues()
199 .add("linkStateHeaders", linkStateHeaders)
200 .toString();
201 }
202}