blob: 4abdbf749714b94f8b392bb2dffb37ed60ad80f1 [file] [log] [blame]
Pavlin Radoslavov80f3e182014-12-15 10:46:18 -08001/*
2 * Copyright 2014 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.sdnip.bgp;
17
18import org.jboss.netty.buffer.ChannelBuffer;
19import org.jboss.netty.buffer.ChannelBuffers;
20import org.jboss.netty.channel.ChannelHandlerContext;
21import org.onosproject.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
25/**
26 * A class for handling BGP NOTIFICATION messages.
27 */
28final class BgpNotification {
29 private static final Logger log =
30 LoggerFactory.getLogger(BgpNotification.class);
31
32 /**
33 * Default constructor.
34 * <p>
35 * The constructor is private to prevent creating an instance of
36 * this utility class.
37 */
38 private BgpNotification() {
39 }
40
41 /**
42 * Processes BGP NOTIFICATION message.
43 *
44 * @param bgpSession the BGP Session to use
45 * @param ctx the Channel Handler Context
46 * @param message the message to process
47 */
48 static void processBgpNotification(BgpSession bgpSession,
49 ChannelHandlerContext ctx,
50 ChannelBuffer message) {
51 int minLength =
52 BgpConstants.BGP_NOTIFICATION_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
53 if (message.readableBytes() < minLength) {
54 log.debug("BGP RX NOTIFICATION Error from {}: " +
55 "Message length {} too short. Must be at least {}",
56 bgpSession.getRemoteAddress(), message.readableBytes(),
57 minLength);
58 //
59 // ERROR: Bad Message Length
60 //
61 // NOTE: We do NOT send NOTIFICATION in response to a notification
62 return;
63 }
64
65 //
66 // Parse the NOTIFICATION message
67 //
68 int errorCode = message.readUnsignedByte();
69 int errorSubcode = message.readUnsignedByte();
70 int dataLength = message.readableBytes();
71
72 log.debug("BGP RX NOTIFICATION message from {}: Error Code {} " +
73 "Error Subcode {} Data Length {}",
74 bgpSession.getRemoteAddress(), errorCode, errorSubcode,
75 dataLength);
76
77 //
78 // NOTE: If the peer sent a NOTIFICATION, we leave it to the peer to
79 // close the connection.
80 //
81
82 // Start the Session Timeout timer
83 bgpSession.restartSessionTimeoutTimer(ctx);
84 }
85
86 /**
87 * Prepares BGP NOTIFICATION message.
88 *
89 * @param errorCode the BGP NOTIFICATION Error Code
90 * @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable,
91 * otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC
92 * @param data the BGP NOTIFICATION Data if applicable, otherwise null
93 * @return the message to transmit (BGP header included)
94 */
95 static ChannelBuffer prepareBgpNotification(int errorCode,
96 int errorSubcode,
97 ChannelBuffer data) {
98 ChannelBuffer message =
99 ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
100
101 //
102 // Prepare the NOTIFICATION message payload
103 //
104 message.writeByte(errorCode);
105 message.writeByte(errorSubcode);
106 if (data != null) {
107 message.writeBytes(data);
108 }
109 return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_NOTIFICATION,
110 message);
111 }
112
113 /**
114 * Prepares BGP NOTIFICATION message: Bad Message Length.
115 *
116 * @param length the erroneous Length field
117 * @return the message to transmit (BGP header included)
118 */
119 static ChannelBuffer prepareBgpNotificationBadMessageLength(int length) {
120 int errorCode = MessageHeaderError.ERROR_CODE;
121 int errorSubcode = MessageHeaderError.BAD_MESSAGE_LENGTH;
122 ChannelBuffer data = ChannelBuffers.buffer(2);
123 data.writeShort(length);
124
125 return prepareBgpNotification(errorCode, errorSubcode, data);
126 }
127}