blob: f03cddaa6c3f4d0d64e43d658928d45081fd98ae [file] [log] [blame]
Priyanka B965d2692015-10-14 15:25:31 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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;
Shashikanth VHb58cfd52016-04-21 16:45:50 +053039import org.onosproject.bgpio.types.attr.WideCommunity;
Priyanka B965d2692015-10-14 15:25:31 +053040import org.slf4j.Logger;
41import org.slf4j.LoggerFactory;
42
43import com.google.common.base.MoreObjects;
44
45/**
46 * Provides Implementation of BGP Path Attribute.
47 */
48public class BgpPathAttributes {
49
50 /* Path attribute:
51 <attribute type, attribute length, attribute value>
52
53 0 1
54 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
55 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 | Attr. Flags |Attr. Type Code|
57 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 REFERENCE : RFC 4271
59 */
Ray Milkey9c9cde42018-01-12 14:22:06 -080060 private static final Logger log = LoggerFactory.getLogger(BgpPathAttributes.class);
Priyanka B965d2692015-10-14 15:25:31 +053061
Priyanka B0ab34b92015-12-03 21:13:52 +053062 public static final int LINK_STATE_ATTRIBUTE_TYPE = 29;
Priyanka B965d2692015-10-14 15:25:31 +053063 public static final int MPREACHNLRI_TYPE = 14;
64 public static final int MPUNREACHNLRI_TYPE = 15;
Shashikanth VH9bd644a2016-02-11 17:23:49 +053065 public static final int EXTENDED_COMMUNITY_TYPE = 16;
Priyanka B965d2692015-10-14 15:25:31 +053066
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053067 private final List<BgpValueType> pathAttribute;
Priyanka B965d2692015-10-14 15:25:31 +053068
69 /**
70 * Initialize parameter.
71 */
72 public BgpPathAttributes() {
73 this.pathAttribute = null;
74 }
75
76 /**
77 * Constructor to initialize parameters for BGP path attributes.
78 *
79 * @param pathAttribute list of path attributes
80 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053081 public BgpPathAttributes(List<BgpValueType> pathAttribute) {
Priyanka B965d2692015-10-14 15:25:31 +053082 this.pathAttribute = pathAttribute;
83 }
84
85 /**
86 * Returns list of path attributes.
87 *
88 * @return list of path attributes
89 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053090 public List<BgpValueType> pathAttributes() {
Priyanka B965d2692015-10-14 15:25:31 +053091 return this.pathAttribute;
92 }
93
94 /**
95 * Reads from channelBuffer and parses BGP path attributes.
96 *
97 * @param cb channelBuffer
98 * @return object of BgpPathAttributes
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053099 * @throws BgpParseException while parsing BGP path attributes
Priyanka B965d2692015-10-14 15:25:31 +0530100 */
101 public static BgpPathAttributes read(ChannelBuffer cb)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530102 throws BgpParseException {
Priyanka B965d2692015-10-14 15:25:31 +0530103
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530104 BgpValueType pathAttribute = null;
105 List<BgpValueType> pathAttributeList = new LinkedList<>();
Priyanka B965d2692015-10-14 15:25:31 +0530106 boolean isOrigin = false;
107 boolean isAsPath = false;
108 boolean isNextHop = false;
109 boolean isMpReach = false;
110 boolean isMpUnReach = false;
111 while (cb.readableBytes() > 0) {
112 cb.markReaderIndex();
113 byte flags = cb.readByte();
114 byte typeCode = cb.readByte();
115 cb.resetReaderIndex();
116 switch (typeCode) {
117 case Origin.ORIGIN_TYPE:
118 pathAttribute = Origin.read(cb);
119 isOrigin = ((Origin) pathAttribute).isOriginSet();
120 break;
121 case AsPath.ASPATH_TYPE:
122 pathAttribute = AsPath.read(cb);
123 isAsPath = ((AsPath) pathAttribute).isaspathSet();
124 break;
125 case As4Path.AS4PATH_TYPE:
126 pathAttribute = As4Path.read(cb);
127 break;
128 case NextHop.NEXTHOP_TYPE:
129 pathAttribute = NextHop.read(cb);
130 isNextHop = ((NextHop) pathAttribute).isNextHopSet();
131 break;
132 case Med.MED_TYPE:
133 pathAttribute = Med.read(cb);
134 break;
135 case LocalPref.LOCAL_PREF_TYPE:
136 pathAttribute = LocalPref.read(cb);
137 break;
Priyanka B24cce0a2015-11-21 18:30:34 +0530138 case MpReachNlri.MPREACHNLRI_TYPE:
139 pathAttribute = MpReachNlri.read(cb);
140 isMpReach = ((MpReachNlri) pathAttribute).isMpReachNlriSet();
Priyanka B965d2692015-10-14 15:25:31 +0530141 break;
Priyanka B24cce0a2015-11-21 18:30:34 +0530142 case MpUnReachNlri.MPUNREACHNLRI_TYPE:
143 pathAttribute = MpUnReachNlri.read(cb);
144 isMpUnReach = ((MpUnReachNlri) pathAttribute)
145 .isMpUnReachNlriSet();
Priyanka B965d2692015-10-14 15:25:31 +0530146 break;
147 case LINK_STATE_ATTRIBUTE_TYPE:
Priyanka B0ab34b92015-12-03 21:13:52 +0530148 pathAttribute = LinkStateAttributes.read(cb);
Priyanka B965d2692015-10-14 15:25:31 +0530149 break;
Shashikanth VH9bd644a2016-02-11 17:23:49 +0530150 case EXTENDED_COMMUNITY_TYPE:
151 pathAttribute = BgpExtendedCommunity.read(cb);
152 break;
Shashikanth VHb58cfd52016-04-21 16:45:50 +0530153 case WideCommunity.TYPE:
154 pathAttribute = WideCommunity.read(cb);
155 break;
Priyanka B965d2692015-10-14 15:25:31 +0530156 default:
mohamedrahil00f6f262016-11-24 20:20:41 +0530157 log.debug("Skip bytes for unsupported attribute types");
Priyanka B965d2692015-10-14 15:25:31 +0530158 UnSupportedAttribute.read(cb);
159 }
160 pathAttributeList.add(pathAttribute);
161 }
162
163 checkMandatoryAttr(isOrigin, isAsPath, isNextHop, isMpReach, isMpUnReach);
164 //TODO:if mp_reach or mp_unreach not present ignore the packet
165 return new BgpPathAttributes(pathAttributeList);
166 }
167
168 /**
Shashikanth VH9bd644a2016-02-11 17:23:49 +0530169 * Write path attributes to channelBuffer.
170 *
171 * @param cb channelBuffer
172 * @return object of BgpPathAttributes
173 * @throws BgpParseException while parsing BGP path attributes
174 */
175 public int write(ChannelBuffer cb)
176 throws BgpParseException {
177
178 if (pathAttribute == null) {
179 return 0;
180 }
181 int iLenStartIndex = cb.writerIndex();
182
183 ListIterator<BgpValueType> iterator = pathAttribute.listIterator();
184
185 int pathAttributeIndx = cb.writerIndex();
186 cb.writeShort(0);
187
188 while (iterator.hasNext()) {
189
190 BgpValueType attr = iterator.next();
191
192 switch (attr.getType()) {
193 case Origin.ORIGIN_TYPE:
194 Origin origin = (Origin) attr;
195 origin.write(cb);
196 break;
197 case AsPath.ASPATH_TYPE:
198 AsPath asPath = (AsPath) attr;
199 asPath.write(cb);
200 break;
201 case As4Path.AS4PATH_TYPE:
202 As4Path as4Path = (As4Path) attr;
203 as4Path.write(cb);
204 break;
205 case NextHop.NEXTHOP_TYPE:
206 NextHop nextHop = (NextHop) attr;
207 nextHop.write(cb);
208 break;
209 case Med.MED_TYPE:
210 Med med = (Med) attr;
211 med.write(cb);
212 break;
213 case LocalPref.LOCAL_PREF_TYPE:
214 LocalPref localPref = (LocalPref) attr;
215 localPref.write(cb);
216 break;
217 case Constants.BGP_EXTENDED_COMMUNITY:
218 BgpExtendedCommunity extendedCommunity = (BgpExtendedCommunity) attr;
219 extendedCommunity.write(cb);
220 break;
Shashikanth VHb58cfd52016-04-21 16:45:50 +0530221 case WideCommunity.TYPE:
222 WideCommunity wideCommunity = (WideCommunity) attr;
223 wideCommunity.write(cb);
224 break;
Shashikanth VH9bd644a2016-02-11 17:23:49 +0530225 case MpReachNlri.MPREACHNLRI_TYPE:
226 MpReachNlri mpReach = (MpReachNlri) attr;
227 mpReach.write(cb);
228 break;
229 case MpUnReachNlri.MPUNREACHNLRI_TYPE:
230 MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
231 mpUnReach.write(cb);
232 break;
233 case LINK_STATE_ATTRIBUTE_TYPE:
234 LinkStateAttributes linkState = (LinkStateAttributes) attr;
235 linkState.write(cb);
236 break;
237 default:
238 return cb.writerIndex() - iLenStartIndex;
239 }
240 }
241
242 int pathAttrLen = cb.writerIndex() - pathAttributeIndx;
243 cb.setShort(pathAttributeIndx, (short) (pathAttrLen - 2));
244 return cb.writerIndex() - iLenStartIndex;
245 }
246
247 /**
Priyanka B965d2692015-10-14 15:25:31 +0530248 * Checks mandatory attributes are presents, if not present throws exception.
249 *
250 * @param isOrigin say whether origin attribute is present
251 * @param isAsPath say whether aspath attribute is present
252 * @param isNextHop say whether nexthop attribute is present
253 * @param isMpReach say whether mpreach attribute is present
254 * @param isMpUnReach say whether mpunreach attribute is present
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530255 * @throws BgpParseException if mandatory path attribute is not present
Priyanka B965d2692015-10-14 15:25:31 +0530256 */
257 public static void checkMandatoryAttr(boolean isOrigin, boolean isAsPath,
258 boolean isNextHop, boolean isMpReach, boolean isMpUnReach)
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530259 throws BgpParseException {
Shashikanth VH1ecbe7b2015-12-02 22:54:23 +0530260 // Mandatory attributes validation not required for MP_UNREACH
261 if (isMpUnReach) {
262 return;
263 }
264
Priyanka B965d2692015-10-14 15:25:31 +0530265 if (!isOrigin) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530266 log.debug("Mandatory attributes not Present");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530267 Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
268 BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
Priyanka B965d2692015-10-14 15:25:31 +0530269 Origin.ORIGIN_TYPE);
270 }
271 if (!isAsPath) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530272 log.debug("Mandatory attributes not Present");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530273 Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
274 BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
Priyanka B965d2692015-10-14 15:25:31 +0530275 AsPath.ASPATH_TYPE);
276 }
Ray Milkeyfe0e0852018-01-18 11:14:05 -0800277 if (!isMpReach && !isNextHop) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530278 log.debug("Mandatory attributes not Present");
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530279 Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
280 BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
Priyanka B965d2692015-10-14 15:25:31 +0530281 NextHop.NEXTHOP_TYPE);
282 }
283 }
284
285 @Override
286 public String toString() {
287 return MoreObjects.toStringHelper(getClass())
288 .add("pathAttribute", pathAttribute)
289 .toString();
290 }
291}