blob: d60adceefb17a170d1a5c935c6172649b5ac33f7 [file] [log] [blame]
Priyanka B965d2692015-10-14 15:25:31 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Priyanka B965d2692015-10-14 15:25:31 +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.bgpio.protocol.ver4;
17
18import java.util.LinkedList;
19import java.util.List;
Shashikanth VH9bd644a2016-02-11 17:23:49 +053020import java.util.ListIterator;
Priyanka B965d2692015-10-14 15:25:31 +053021
22import org.jboss.netty.buffer.ChannelBuffer;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053023import org.onosproject.bgpio.exceptions.BgpParseException;
Priyanka B965d2692015-10-14 15:25:31 +053024import org.onosproject.bgpio.types.As4Path;
25import org.onosproject.bgpio.types.AsPath;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053026import org.onosproject.bgpio.types.BgpErrorType;
Shashikanth VH9bd644a2016-02-11 17:23:49 +053027import org.onosproject.bgpio.types.BgpExtendedCommunity;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053028import org.onosproject.bgpio.types.BgpValueType;
Priyanka B0ab34b92015-12-03 21:13:52 +053029import org.onosproject.bgpio.types.LinkStateAttributes;
Priyanka B965d2692015-10-14 15:25:31 +053030import org.onosproject.bgpio.types.LocalPref;
31import org.onosproject.bgpio.types.Med;
32import org.onosproject.bgpio.types.NextHop;
33import org.onosproject.bgpio.types.Origin;
Priyanka B24cce0a2015-11-21 18:30:34 +053034import org.onosproject.bgpio.types.MpReachNlri;
35import org.onosproject.bgpio.types.MpUnReachNlri;
Priyanka B965d2692015-10-14 15:25:31 +053036import org.onosproject.bgpio.util.UnSupportedAttribute;
37import org.onosproject.bgpio.util.Validation;
Shashikanth VH9bd644a2016-02-11 17:23:49 +053038import org.onosproject.bgpio.util.Constants;
Priyanka B965d2692015-10-14 15:25:31 +053039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42import com.google.common.base.MoreObjects;
43
44/**
45 * Provides Implementation of BGP Path Attribute.
46 */
47public class BgpPathAttributes {
48
49 /* Path attribute:
50 <attribute type, attribute length, attribute value>
51
52 0 1
53 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
54 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 | Attr. Flags |Attr. Type Code|
56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 REFERENCE : RFC 4271
58 */
59 protected static final Logger log = LoggerFactory.getLogger(BgpPathAttributes.class);
60
Priyanka B0ab34b92015-12-03 21:13:52 +053061 public static final int LINK_STATE_ATTRIBUTE_TYPE = 29;
Priyanka B965d2692015-10-14 15:25:31 +053062 public static final int MPREACHNLRI_TYPE = 14;
63 public static final int MPUNREACHNLRI_TYPE = 15;
Shashikanth VH9bd644a2016-02-11 17:23:49 +053064 public static final int EXTENDED_COMMUNITY_TYPE = 16;
Priyanka B965d2692015-10-14 15:25:31 +053065
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053066 private final List<BgpValueType> pathAttribute;
Priyanka B965d2692015-10-14 15:25:31 +053067
68 /**
69 * Initialize parameter.
70 */
71 public BgpPathAttributes() {
72 this.pathAttribute = null;
73 }
74
75 /**
76 * Constructor to initialize parameters for BGP path attributes.
77 *
78 * @param pathAttribute list of path attributes
79 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053080 public BgpPathAttributes(List<BgpValueType> pathAttribute) {
Priyanka B965d2692015-10-14 15:25:31 +053081 this.pathAttribute = pathAttribute;
82 }
83
84 /**
85 * Returns list of path attributes.
86 *
87 * @return list of path attributes
88 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053089 public List<BgpValueType> pathAttributes() {
Priyanka B965d2692015-10-14 15:25:31 +053090 return this.pathAttribute;
91 }
92
93 /**
94 * Reads from channelBuffer and parses BGP path attributes.
95 *
96 * @param cb channelBuffer
97 * @return object of BgpPathAttributes
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053098 * @throws BgpParseException while parsing BGP path attributes
Priyanka B965d2692015-10-14 15:25:31 +053099 */
100 public static BgpPathAttributes read(ChannelBuffer cb)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530101 throws BgpParseException {
Priyanka B965d2692015-10-14 15:25:31 +0530102
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530103 BgpValueType pathAttribute = null;
104 List<BgpValueType> pathAttributeList = new LinkedList<>();
Priyanka B965d2692015-10-14 15:25:31 +0530105 boolean isOrigin = false;
106 boolean isAsPath = false;
107 boolean isNextHop = false;
108 boolean isMpReach = false;
109 boolean isMpUnReach = false;
110 while (cb.readableBytes() > 0) {
111 cb.markReaderIndex();
112 byte flags = cb.readByte();
113 byte typeCode = cb.readByte();
114 cb.resetReaderIndex();
115 switch (typeCode) {
116 case Origin.ORIGIN_TYPE:
117 pathAttribute = Origin.read(cb);
118 isOrigin = ((Origin) pathAttribute).isOriginSet();
119 break;
120 case AsPath.ASPATH_TYPE:
121 pathAttribute = AsPath.read(cb);
122 isAsPath = ((AsPath) pathAttribute).isaspathSet();
123 break;
124 case As4Path.AS4PATH_TYPE:
125 pathAttribute = As4Path.read(cb);
126 break;
127 case NextHop.NEXTHOP_TYPE:
128 pathAttribute = NextHop.read(cb);
129 isNextHop = ((NextHop) pathAttribute).isNextHopSet();
130 break;
131 case Med.MED_TYPE:
132 pathAttribute = Med.read(cb);
133 break;
134 case LocalPref.LOCAL_PREF_TYPE:
135 pathAttribute = LocalPref.read(cb);
136 break;
Priyanka B24cce0a2015-11-21 18:30:34 +0530137 case MpReachNlri.MPREACHNLRI_TYPE:
138 pathAttribute = MpReachNlri.read(cb);
139 isMpReach = ((MpReachNlri) pathAttribute).isMpReachNlriSet();
Priyanka B965d2692015-10-14 15:25:31 +0530140 break;
Priyanka B24cce0a2015-11-21 18:30:34 +0530141 case MpUnReachNlri.MPUNREACHNLRI_TYPE:
142 pathAttribute = MpUnReachNlri.read(cb);
143 isMpUnReach = ((MpUnReachNlri) pathAttribute)
144 .isMpUnReachNlriSet();
Priyanka B965d2692015-10-14 15:25:31 +0530145 break;
146 case LINK_STATE_ATTRIBUTE_TYPE:
Priyanka B0ab34b92015-12-03 21:13:52 +0530147 pathAttribute = LinkStateAttributes.read(cb);
Priyanka B965d2692015-10-14 15:25:31 +0530148 break;
Shashikanth VH9bd644a2016-02-11 17:23:49 +0530149 case EXTENDED_COMMUNITY_TYPE:
150 pathAttribute = BgpExtendedCommunity.read(cb);
151 break;
Priyanka B965d2692015-10-14 15:25:31 +0530152 default:
153 //skip bytes for unsupported attribute types
154 UnSupportedAttribute.read(cb);
155 }
156 pathAttributeList.add(pathAttribute);
157 }
158
159 checkMandatoryAttr(isOrigin, isAsPath, isNextHop, isMpReach, isMpUnReach);
160 //TODO:if mp_reach or mp_unreach not present ignore the packet
161 return new BgpPathAttributes(pathAttributeList);
162 }
163
164 /**
Shashikanth VH9bd644a2016-02-11 17:23:49 +0530165 * Write path attributes to channelBuffer.
166 *
167 * @param cb channelBuffer
168 * @return object of BgpPathAttributes
169 * @throws BgpParseException while parsing BGP path attributes
170 */
171 public int write(ChannelBuffer cb)
172 throws BgpParseException {
173
174 if (pathAttribute == null) {
175 return 0;
176 }
177 int iLenStartIndex = cb.writerIndex();
178
179 ListIterator<BgpValueType> iterator = pathAttribute.listIterator();
180
181 int pathAttributeIndx = cb.writerIndex();
182 cb.writeShort(0);
183
184 while (iterator.hasNext()) {
185
186 BgpValueType attr = iterator.next();
187
188 switch (attr.getType()) {
189 case Origin.ORIGIN_TYPE:
190 Origin origin = (Origin) attr;
191 origin.write(cb);
192 break;
193 case AsPath.ASPATH_TYPE:
194 AsPath asPath = (AsPath) attr;
195 asPath.write(cb);
196 break;
197 case As4Path.AS4PATH_TYPE:
198 As4Path as4Path = (As4Path) attr;
199 as4Path.write(cb);
200 break;
201 case NextHop.NEXTHOP_TYPE:
202 NextHop nextHop = (NextHop) attr;
203 nextHop.write(cb);
204 break;
205 case Med.MED_TYPE:
206 Med med = (Med) attr;
207 med.write(cb);
208 break;
209 case LocalPref.LOCAL_PREF_TYPE:
210 LocalPref localPref = (LocalPref) attr;
211 localPref.write(cb);
212 break;
213 case Constants.BGP_EXTENDED_COMMUNITY:
214 BgpExtendedCommunity extendedCommunity = (BgpExtendedCommunity) attr;
215 extendedCommunity.write(cb);
216 break;
217 case MpReachNlri.MPREACHNLRI_TYPE:
218 MpReachNlri mpReach = (MpReachNlri) attr;
219 mpReach.write(cb);
220 break;
221 case MpUnReachNlri.MPUNREACHNLRI_TYPE:
222 MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
223 mpUnReach.write(cb);
224 break;
225 case LINK_STATE_ATTRIBUTE_TYPE:
226 LinkStateAttributes linkState = (LinkStateAttributes) attr;
227 linkState.write(cb);
228 break;
229 default:
230 return cb.writerIndex() - iLenStartIndex;
231 }
232 }
233
234 int pathAttrLen = cb.writerIndex() - pathAttributeIndx;
235 cb.setShort(pathAttributeIndx, (short) (pathAttrLen - 2));
236 return cb.writerIndex() - iLenStartIndex;
237 }
238
239 /**
Priyanka B965d2692015-10-14 15:25:31 +0530240 * Checks mandatory attributes are presents, if not present throws exception.
241 *
242 * @param isOrigin say whether origin attribute is present
243 * @param isAsPath say whether aspath attribute is present
244 * @param isNextHop say whether nexthop attribute is present
245 * @param isMpReach say whether mpreach attribute is present
246 * @param isMpUnReach say whether mpunreach attribute is present
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530247 * @throws BgpParseException if mandatory path attribute is not present
Priyanka B965d2692015-10-14 15:25:31 +0530248 */
249 public static void checkMandatoryAttr(boolean isOrigin, boolean isAsPath,
250 boolean isNextHop, boolean isMpReach, boolean isMpUnReach)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530251 throws BgpParseException {
Shashikanth VH1ecbe7b2015-12-02 22:54:23 +0530252 // Mandatory attributes validation not required for MP_UNREACH
253 if (isMpUnReach) {
254 return;
255 }
256
Priyanka B965d2692015-10-14 15:25:31 +0530257 if (!isOrigin) {
258 log.debug("Mandatory Attributes not Present");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530259 Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
260 BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
Priyanka B965d2692015-10-14 15:25:31 +0530261 Origin.ORIGIN_TYPE);
262 }
263 if (!isAsPath) {
264 log.debug("Mandatory Attributes not Present");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530265 Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
266 BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
Priyanka B965d2692015-10-14 15:25:31 +0530267 AsPath.ASPATH_TYPE);
268 }
269 if (!isMpUnReach && !isMpReach && !isNextHop) {
270 log.debug("Mandatory Attributes not Present");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530271 Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
272 BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
Priyanka B965d2692015-10-14 15:25:31 +0530273 NextHop.NEXTHOP_TYPE);
274 }
275 }
276
277 @Override
278 public String toString() {
279 return MoreObjects.toStringHelper(getClass())
280 .add("pathAttribute", pathAttribute)
281 .toString();
282 }
283}