9ffddf68090510c45d2199fdd6f28e7a4c34b52f
[onosfw.git] /
1 /*
2  * Copyright 2015 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  */
16 package org.onosproject.bgpio.protocol.ver4;
17
18 import java.util.LinkedList;
19 import java.util.List;
20
21 import org.jboss.netty.buffer.ChannelBuffer;
22 import org.onosproject.bgpio.exceptions.BgpParseException;
23 import org.onosproject.bgpio.types.As4Path;
24 import org.onosproject.bgpio.types.AsPath;
25 import org.onosproject.bgpio.types.BgpErrorType;
26 import org.onosproject.bgpio.types.BgpValueType;
27 import org.onosproject.bgpio.types.LocalPref;
28 import org.onosproject.bgpio.types.Med;
29 import org.onosproject.bgpio.types.NextHop;
30 import org.onosproject.bgpio.types.Origin;
31 import org.onosproject.bgpio.types.MpReachNlri;
32 import org.onosproject.bgpio.types.MpUnReachNlri;
33 import org.onosproject.bgpio.util.UnSupportedAttribute;
34 import org.onosproject.bgpio.util.Validation;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import com.google.common.base.MoreObjects;
39
40 /**
41  * Provides Implementation of BGP Path Attribute.
42  */
43 public class BgpPathAttributes {
44
45     /* Path attribute:
46            <attribute type, attribute length, attribute value>
47
48            0                   1
49            0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
50            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51            |  Attr. Flags  |Attr. Type Code|
52            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53            REFERENCE : RFC 4271
54     */
55     protected static final Logger log = LoggerFactory.getLogger(BgpPathAttributes.class);
56
57     public static final int LINK_STATE_ATTRIBUTE_TYPE = 50;
58     public static final int MPREACHNLRI_TYPE = 14;
59     public static final int MPUNREACHNLRI_TYPE = 15;
60
61     private final List<BgpValueType> pathAttribute;
62
63     /**
64      * Initialize parameter.
65      */
66     public BgpPathAttributes() {
67         this.pathAttribute = null;
68     }
69
70     /**
71      * Constructor to initialize parameters for BGP path attributes.
72      *
73      * @param pathAttribute list of path attributes
74      */
75     public BgpPathAttributes(List<BgpValueType> pathAttribute) {
76         this.pathAttribute = pathAttribute;
77     }
78
79     /**
80      * Returns list of path attributes.
81      *
82      * @return list of path attributes
83      */
84     public List<BgpValueType> pathAttributes() {
85         return this.pathAttribute;
86     }
87
88     /**
89      * Reads from channelBuffer and parses BGP path attributes.
90      *
91      * @param cb channelBuffer
92      * @return object of BgpPathAttributes
93      * @throws BgpParseException while parsing BGP path attributes
94      */
95     public static BgpPathAttributes read(ChannelBuffer cb)
96             throws BgpParseException {
97
98         BgpValueType pathAttribute = null;
99         List<BgpValueType> pathAttributeList = new LinkedList<>();
100         boolean isOrigin = false;
101         boolean isAsPath = false;
102         boolean isNextHop = false;
103         boolean isMpReach = false;
104         boolean isMpUnReach = false;
105         while (cb.readableBytes() > 0) {
106             cb.markReaderIndex();
107             byte flags = cb.readByte();
108             byte typeCode = cb.readByte();
109             cb.resetReaderIndex();
110             switch (typeCode) {
111             case Origin.ORIGIN_TYPE:
112                 pathAttribute = Origin.read(cb);
113                 isOrigin = ((Origin) pathAttribute).isOriginSet();
114                 break;
115             case AsPath.ASPATH_TYPE:
116                 pathAttribute = AsPath.read(cb);
117                 isAsPath = ((AsPath) pathAttribute).isaspathSet();
118                 break;
119             case As4Path.AS4PATH_TYPE:
120                 pathAttribute = As4Path.read(cb);
121                 break;
122             case NextHop.NEXTHOP_TYPE:
123                 pathAttribute = NextHop.read(cb);
124                 isNextHop = ((NextHop) pathAttribute).isNextHopSet();
125                 break;
126             case Med.MED_TYPE:
127                 pathAttribute = Med.read(cb);
128                 break;
129             case LocalPref.LOCAL_PREF_TYPE:
130                 pathAttribute = LocalPref.read(cb);
131                 break;
132             case MpReachNlri.MPREACHNLRI_TYPE:
133                 pathAttribute = MpReachNlri.read(cb);
134                 isMpReach = ((MpReachNlri) pathAttribute).isMpReachNlriSet();
135                 break;
136             case MpUnReachNlri.MPUNREACHNLRI_TYPE:
137                 pathAttribute = MpUnReachNlri.read(cb);
138                 isMpUnReach = ((MpUnReachNlri) pathAttribute)
139                         .isMpUnReachNlriSet();
140                 break;
141             case LINK_STATE_ATTRIBUTE_TYPE:
142                 //TODO: To be merged later
143                 break;
144             default:
145                 //skip bytes for unsupported attribute types
146                 UnSupportedAttribute.read(cb);
147             }
148             pathAttributeList.add(pathAttribute);
149         }
150
151         checkMandatoryAttr(isOrigin, isAsPath, isNextHop, isMpReach, isMpUnReach);
152         //TODO:if mp_reach or mp_unreach not present ignore the packet
153         return new BgpPathAttributes(pathAttributeList);
154     }
155
156     /**
157      * Checks mandatory attributes are presents, if not present throws exception.
158      *
159      * @param isOrigin say whether origin attribute is present
160      * @param isAsPath say whether aspath attribute is present
161      * @param isNextHop say whether nexthop attribute is present
162      * @param isMpReach say whether mpreach attribute is present
163      * @param isMpUnReach say whether mpunreach attribute is present
164      * @throws BgpParseException if mandatory path attribute is not present
165      */
166     public static void checkMandatoryAttr(boolean isOrigin, boolean isAsPath,
167             boolean isNextHop, boolean isMpReach, boolean isMpUnReach)
168             throws BgpParseException {
169         if (!isOrigin) {
170             log.debug("Mandatory Attributes not Present");
171             Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
172                     BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
173                     Origin.ORIGIN_TYPE);
174         }
175         if (!isAsPath) {
176             log.debug("Mandatory Attributes not Present");
177             Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
178                     BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
179                     AsPath.ASPATH_TYPE);
180         }
181         if (!isMpUnReach && !isMpReach && !isNextHop) {
182             log.debug("Mandatory Attributes not Present");
183             Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
184                     BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
185                     NextHop.NEXTHOP_TYPE);
186         }
187     }
188
189     @Override
190     public String toString() {
191         return MoreObjects.toStringHelper(getClass())
192                 .add("pathAttribute", pathAttribute)
193                 .toString();
194     }
195 }