blob: 3efed95c4d99070b01f414eacc79c7e71ba02170 [file] [log] [blame]
Priyanka B3b695542015-10-14 17:16:27 +05301/*
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
17package org.onosproject.bgpio.types;
18
19import java.util.LinkedList;
20import java.util.List;
21
22import org.jboss.netty.buffer.ChannelBuffer;
23import org.onosproject.bgpio.exceptions.BGPParseException;
24import org.onosproject.bgpio.protocol.BGPLSNlri;
25import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4;
26import org.onosproject.bgpio.protocol.linkstate.BGPPrefixIPv4LSNlriVer4;
27import org.onosproject.bgpio.util.Constants;
28import org.onosproject.bgpio.util.Validation;
29import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import com.google.common.base.MoreObjects;
33
34/**
35 * Provides Implementation of MpUnReach Nlri BGP Path Attribute.
36 */
37public class MpUnReachNlri implements BGPValueType {
38
39 protected static final Logger log = LoggerFactory.getLogger(MpUnReachNlri.class);
40
41 public static final byte MPUNREACHNLRI_TYPE = 15;
42 public static final byte LINK_NLRITYPE = 2;
43 private boolean isMpUnReachNlri = false;
44 private final short afi;
45 private final byte safi;
46 private final List<BGPLSNlri> mpUnReachNlri;
47 private final int length;
48
49 /**
50 * Constructor to initialize parameters.
51 *
52 * @param mpUnReachNlri MpUnReach Nlri attribute
53 * @param afi address family identifier
54 * @param safi subsequent address family identifier
55 * @param length of MpUnReachNlri
56 */
57 public MpUnReachNlri(List<BGPLSNlri> mpUnReachNlri, short afi, byte safi,
58 int length) {
59 this.mpUnReachNlri = mpUnReachNlri;
60 this.isMpUnReachNlri = true;
61 this.afi = afi;
62 this.safi = safi;
63 this.length = length;
64 }
65
66 /**
67 * Reads from ChannelBuffer and parses MpUnReachNlri.
68 *
69 * @param cb ChannelBuffer
70 * @return object of MpUnReachNlri
71 * @throws BGPParseException while parsing MpUnReachNlri
72 */
73 public static MpUnReachNlri read(ChannelBuffer cb) throws BGPParseException {
74 ChannelBuffer tempBuf = cb.copy();
75 Validation parseFlags = Validation.parseAttributeHeader(cb);
76 int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT
77 : parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_BYTE;
78 ChannelBuffer data = tempBuf.readBytes(len);
79
80 if (!parseFlags.getFirstBit() && parseFlags.getSecondBit()
81 && parseFlags.getThirdBit()) {
82 throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR,
83 BGPErrorType.ATTRIBUTE_FLAGS_ERROR, data);
84 }
85
86 if (cb.readableBytes() < parseFlags.getLength()) {
87 Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
88 BGPErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength());
89 }
90
91 LinkedList<BGPLSNlri> mpUnReachNlri = new LinkedList<>();
92 BGPLSNlri bgpLSNlri = null;
93 short afi = 0;
94 byte safi = 0;
95 ChannelBuffer tempCb = cb.readBytes(parseFlags.getLength());
96 while (tempCb.readableBytes() > 0) {
97 afi = tempCb.readShort();
98 safi = tempCb.readByte();
99
100 //Supporting only for AFI 16388 / SAFI 71
101 if ((afi == Constants.AFI_VALUE) && (safi == Constants.SAFI_VALUE)
102 || (afi == Constants.AFI_VALUE) && (safi == Constants.VPN_SAFI_VALUE)) {
103 while (tempCb.readableBytes() > 0) {
104 short nlriType = tempCb.readShort();
105 short totNlriLen = tempCb.readShort();
106 if (tempCb.readableBytes() < totNlriLen) {
107 Validation.validateLen(
108 BGPErrorType.UPDATE_MESSAGE_ERROR,
109 BGPErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
110 }
111 tempBuf = tempCb.readBytes(totNlriLen);
112 switch (nlriType) {
113 case BGPNodeLSNlriVer4.NODE_NLRITYPE:
114 bgpLSNlri = BGPNodeLSNlriVer4.read(tempBuf, afi, safi);
115 break;
116 case LINK_NLRITYPE:
117 //TODO: to be merged later
118 break;
119 case BGPPrefixIPv4LSNlriVer4.PREFIX_IPV4_NLRITYPE:
120 bgpLSNlri = BGPPrefixIPv4LSNlriVer4.read(tempBuf, afi,
121 safi);
122 break;
123 default:
124 log.debug("nlriType not supported" + nlriType);
125 }
126 mpUnReachNlri.add(bgpLSNlri);
127 }
128 } else {
129 //TODO: check with the values got from capability
130 throw new BGPParseException("Not Supporting afi " + afi
131 + "safi " + safi);
132 }
133 }
134 return new MpUnReachNlri(mpUnReachNlri, afi, safi,
135 parseFlags.getLength());
136 }
137
138 @Override
139 public short getType() {
140 return MPUNREACHNLRI_TYPE;
141 }
142
143 /**
144 * Returns SAFI.
145 *
146 * @return SAFI
147 */
148 public byte safi() {
149 return this.safi;
150 }
151
152 /**
153 * Returns AFI.
154 *
155 * @return AFI
156 */
157 public short afi() {
158 return this.afi;
159 }
160
161 /**
162 * Returns list of MpUnReach Nlri.
163 *
164 * @return list of MpUnReach Nlri
165 */
166 public List<BGPLSNlri> mpUnReachNlri() {
167 return this.mpUnReachNlri;
168 }
169
170 /**
171 * Returns whether MpReachNlri is present.
172 *
173 * @return whether MpReachNlri is present
174 */
175 public boolean isMpUnReachNlriSet() {
176 return this.isMpUnReachNlri;
177 }
178
179 /**
180 * Returns length of MpUnReach.
181 *
182 * @return length of MpUnReach
183 */
184 public int mpUnReachNlriLen() {
185 return this.length;
186 }
187
188 @Override
189 public int write(ChannelBuffer cb) {
190 //Not to be Implemented as of now
191 return 0;
192 }
193
194 @Override
195 public String toString() {
196 return MoreObjects.toStringHelper(getClass())
197 .add("mpReachNlri", mpUnReachNlri)
198 .add("afi", afi)
199 .add("safi", safi)
200 .add("length", length)
201 .toString();
202 }
203}