blob: cba9f04e5ee8ac5d734183b12757f5915c40e957 [file] [log] [blame]
senthil806c8582024-03-22 18:04:51 +05301/*
2 * Copyright 2024-present Open Networking Foundation
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 */
16
17 /*
18 0 1 2 3
19 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
20 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21 | Local Address (16 bytes) |
22 ~ ~
23 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 | Local Port | Remote Port |
25 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26 | Sent OPEN Message |
27 ~ ~
28 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 | Received OPEN Message |
30 ~ ~
31 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 | Information (variable) |
33 ~ ~
34 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 */
36package org.onosproject.bgpmonitoring.type;
37
38import org.jboss.netty.buffer.ChannelBuffers;
39import com.google.common.base.MoreObjects;
40import org.onlab.packet.Deserializer;
41import org.onosproject.bgpio.exceptions.BgpParseException;
42import org.onosproject.bgpio.protocol.BgpMessage;
43import org.onosproject.bgpio.protocol.ver4.BgpMessageVer4;
44import org.onosproject.bgpio.types.BgpHeader;
45import org.onosproject.bgpmonitoring.PeerUpNotificationMessage;
46import org.onosproject.bgpmonitoring.BmpParseException;
47import org.onosproject.bgpmonitoring.PerPeer;
48
49import java.net.InetAddress;
50import java.util.Arrays;
51import java.util.Objects;
52import java.util.function.BiPredicate;
53import java.nio.ByteBuffer;
54
55import org.slf4j.Logger;
56import org.slf4j.LoggerFactory;
57
58import static com.google.common.base.Preconditions.checkState;
59
60/**
61 * A message sent to indicate that a peering
62 * session has come up. The message includes information regarding
63 * the data exchanged between the peers in their OPEN messages, as
64 * well as information about the peering TCP session itself. In
65 * addition to being sent whenever a peer transitions to the
66 * Established state, a Peer Up Notification is sent for each peer in
67 * the Established state when the BMP session itself comes up.
68 * <p>
69 * Local Address: The local IP address associated with the peering
70 * TCP session. It is 4 bytes long if an IPv4 address is carried in
71 * this field, as determined by the V flag (with the 12 most
72 * significant bytes zero-filled) and 16 bytes long if an IPv6
73 * address is carried in this field.
74 * <p>
75 * Local Port: The local port number associated with the peering TCP
76 * session, or 0 if no TCP session actually exists (see Section 8.2).
77 * <p>
78 * Remote Port: The remote port number associated with the peering
79 * TCP session, or 0 if no TCP session actually exists.
80 * <p>
81 * Sent OPEN Message: The full OPEN message transmitted by the
82 * monitored router to its peer.
83 * <p>
84 * Received OPEN Message: The full OPEN message received by the
85 * monitored router from its peer.
86 * Information: Information about the peer, using the Information TLV
87 * format. Only the string type is defined in this
88 * context; it may be repeated. Inclusion of the Information field
89 * is OPTIONAL. Its presence or absence can be inferred by
90 * inspection of the Message Length in the common header.
91 */
92public final class BmpPeerUpNotification extends PeerUpNotificationMessage {
93
94 private static final Logger log = LoggerFactory.getLogger(BmpPeerUpNotification.class);
95
96 private PerPeer perPeer;
97
98 private InetAddress localAddress;
99
100 private int localPort;
101
102 private int remotePort;
103
104 private BgpMessage sentOpenMsg;
105
106 private BgpMessage receivedOpenMsg;
107
108 private byte[] information;
109
110
111 private BmpPeerUpNotification(Builder builder) {
112 this.perPeer = builder.perPeer;
113 this.localAddress = builder.localAddress;
114 this.localPort = builder.localPort;
115 this.remotePort = builder.remotePort;
116 this.sentOpenMsg = builder.sentOpenMsg;
117 this.receivedOpenMsg = builder.receivedOpenMsg;
118 this.information = builder.information;
119
120
121 }
122
123 /**
124 * Returns BMP Peer Header of BMP Message.
125 *
126 * @return BMP Peer Header of BMP Message
127 */
128 @Override
129 public PerPeer getPerPeer() {
130 return perPeer;
131 }
132
133 /**
134 * Returns local ip address.
135 *
136 * @return local ip address
137 */
138 public InetAddress getLocalAddress() {
139 return localAddress;
140 }
141
142 /**
143 * Returns local port number.
144 *
145 * @return local port number
146 */
147 public int getLocalPort() {
148 return localPort;
149 }
150
151 /**
152 * Returns remote port number.
153 *
154 * @return remote port number
155 */
156 public int getRemotePort() {
157 return remotePort;
158 }
159
160 /**
161 * Returns Bgp sent open message.
162 *
163 * @return Bgp sent open message
164 */
165 public BgpMessage getSentOpenMsg() {
166 return sentOpenMsg;
167 }
168
169 /**
170 * Returns Bgp received open message.
171 *
172 * @return Bgp received open message
173 */
174 public BgpMessage getReceivedOpenMsg() {
175 return receivedOpenMsg;
176 }
177
178 /**
179 * Returns BMP peer information.
180 *
181 * @return BMP peer information
182 */
183 public byte[] getInformation() {
184 return information;
185 }
186
187
188 @Override
189 public boolean equals(Object o) {
190 if (this == o) {
191 return true;
192 }
193 if (o == null || getClass() != o.getClass()) {
194 return false;
195 }
196 BmpPeerUpNotification that = (BmpPeerUpNotification) o;
197 return localPort == that.localPort &&
198 remotePort == that.remotePort &&
199 Objects.equals(localAddress, that.localAddress) &&
200 Objects.equals(sentOpenMsg, that.sentOpenMsg) &&
201 Objects.equals(receivedOpenMsg, that.receivedOpenMsg) &&
202 Arrays.equals(information, that.information) &&
203 Objects.equals(perPeer, that.perPeer);
204 }
205
206 @Override
207 public int hashCode() {
208 int result = Objects.hash(localAddress, localPort, remotePort, sentOpenMsg,
209 receivedOpenMsg, perPeer);
210 result = 31 * result + Arrays.hashCode(information);
211 return result;
212 }
213
214 @Override
215 public String toString() {
216 return MoreObjects.toStringHelper(getClass())
217 .add("perPeer", perPeer)
218 .add("localAddress", localAddress)
219 .add("localPort", localPort)
220 .add("remotePort", remotePort)
221 .add("sentOpenMsg", sentOpenMsg)
222 .add("receivedOpenMsg", receivedOpenMsg)
223 .add("information", Arrays.toString(information))
224 .toString();
225 }
226
227 /**
228 * Data deserializer function for BMP peer up notification message.
229 *
230 * @return data deserializer function
231 */
232 public static Deserializer<BmpPeerUpNotification> deserializer() {
233 return (data, offset, length) -> {
234 BiPredicate<ByteBuffer, Integer> isValidBuffer = (b, l)
235 -> b.hasRemaining() && b.remaining() >= l;
236
237 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
238 if (!isValidBuffer.test(bb, PEERUP_NOTIFICATION_HEADER_MIN_LENGTH +
239 PerPeerPacket.PEER_HEADER_MIN_LENGTH)) {
240 throw new BmpParseException("Invalid bmp peer up notification message buffer size.");
241 }
242 byte[] perPeerBytes = new byte[PerPeerPacket.PEER_HEADER_MIN_LENGTH];
243 bb.get(perPeerBytes);
244
245 Builder builder = new Builder()
246 .perPeer(PerPeerPacket.deserializer().deserialize(perPeerBytes,
247 0, PerPeerPacket.PEER_HEADER_MIN_LENGTH));
248
249
250 if (builder.perPeer.isIpv6()) {
251 builder.localAddress(PerPeerPacket.toInetAddress(IPV6_ADDRS, bb));
252 } else {
253 bb.position(bb.position() + (IPV6_ADDRS - IPV4_ADDRS));
254 builder.localAddress(PerPeerPacket.toInetAddress(IPV4_ADDRS, bb));
255 }
256
257 builder.localPort(bb.getShort())
258 .remotePort(bb.getShort());
259
260
261 if (bb.remaining() < (PADDING_BYTES + BGP_LENGTH_FIELD)) {
262 throw new BmpParseException("Invalid bmp peer up notification message buffer size.");
263 }
264
265 bb.position(bb.position() + PADDING_BYTES);
266 int msgLength = bb.getShort();
267 bb.position(bb.position() - (PADDING_BYTES + BGP_LENGTH_FIELD));
268
269 if (bb.remaining() < msgLength) {
270 throw new BmpParseException("Not enough readable bytes");
271 }
272 byte[] routeBytes = new byte[msgLength];
273 bb.get(routeBytes);
274 try {
275 builder.sentOpenMsg(BgpMessageVer4.READER.readFrom(ChannelBuffers.wrappedBuffer(routeBytes),
276 new BgpHeader()));
277 } catch (BgpParseException ex) {
278 throw new BmpParseException(ex);
279 }
280
281 if (bb.remaining() < (PADDING_BYTES + BGP_LENGTH_FIELD)) {
282 throw new BmpParseException("Not enough readable bytes");
283 }
284
285 bb.position(bb.position() + PADDING_BYTES);
286 msgLength = bb.getShort();
287 bb.position(bb.position() - (PADDING_BYTES + BGP_LENGTH_FIELD));
288
289 if (bb.remaining() < msgLength) {
290 throw new BmpParseException("Not enough readable bytes");
291 }
292 routeBytes = new byte[msgLength];
293 bb.get(routeBytes);
294 try {
295 builder.receivedOpenMsg(BgpMessageVer4.READER.readFrom(ChannelBuffers.wrappedBuffer(routeBytes),
296 new BgpHeader()));
297 } catch (BgpParseException ex) {
298 throw new BmpParseException(ex);
299 }
300
301 if (bb.remaining() > 0) {
302 byte[] information = new byte[bb.remaining()];
303 bb.get(information);
304 builder.information(information);
305
306 }
307
308 return builder.build();
309
310 };
311 }
312
313
314 /**
315 * Builder for BMP peer up notification message.
316 */
317 private static class Builder {
318
319
320 private PerPeer perPeer;
321
322 private InetAddress localAddress;
323
324 private int localPort;
325
326 private int remotePort;
327
328 private BgpMessage sentOpenMsg;
329
330 private BgpMessage receivedOpenMsg;
331
332 private byte[] information;
333
334 /**
335 * Setter bmp per peer header.
336 *
337 * @param perPeer bmp per peer header.
338 * @return this class builder.
339 */
340 public Builder perPeer(PerPeer perPeer) {
341 this.perPeer = perPeer;
342 return this;
343 }
344
345 /**
346 * Setter bgp local address.
347 *
348 * @param localAddress bgp local address.
349 * @return this class builder.
350 */
351 public Builder localAddress(InetAddress localAddress) {
352 this.localAddress = localAddress;
353 return this;
354 }
355
356
357 /**
358 * Setter bgp local port.
359 *
360 * @param localPort bgp local port.
361 * @return this class builder.
362 */
363 public Builder localPort(int localPort) {
364 this.localPort = localPort;
365 return this;
366 }
367
368 /**
369 * Setter bgp remote port.
370 *
371 * @param remotePort bgp remote port.
372 * @return this class builder.
373 */
374 public Builder remotePort(int remotePort) {
375 this.remotePort = remotePort;
376 return this;
377 }
378
379 /**
380 * Setter bgp send open message.
381 *
382 * @param sentOpenMsg bgp send open message.
383 * @return this class builder.
384 */
385 public Builder sentOpenMsg(BgpMessage sentOpenMsg) {
386 this.sentOpenMsg = sentOpenMsg;
387 return this;
388 }
389
390 /**
391 * Setter bgp receive open message.
392 *
393 * @param receivedOpenMsg bgp receive open message.
394 * @return this class builder.
395 */
396 public Builder receivedOpenMsg(BgpMessage receivedOpenMsg) {
397 this.receivedOpenMsg = receivedOpenMsg;
398 return this;
399 }
400
401 /**
402 * Setter bgp information message.
403 *
404 * @param information bgp information message.
405 * @return this class builder.
406 */
407 public Builder information(byte[] information) {
408 this.information = information;
409 return this;
410 }
411
412 /**
413 * Checks arguments for bmp peer up notification.
414 */
415 private void checkArguments() {
416 checkState(perPeer != null, "Invalid bmp per peer in peer up notification message.");
417 checkState(sentOpenMsg != null, "Invalid bgp send open message.");
418 checkState(receivedOpenMsg != null, "Invalid bgp receive open message.");
419 }
420
421 /**
422 * Builds BMP peer up notification message.
423 *
424 * @return BMP peer up notification message.
425 */
426 public BmpPeerUpNotification build() {
427 checkArguments();
428 return new BmpPeerUpNotification(this);
429 }
430 }
431}