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