blob: fa4014938d5b4d109ff156f29d316baad7c7eb17 [file] [log] [blame]
Shashikanth VH26fd38a2016-04-26 18:11:37 +05301/*
2 * Copyright 2016-present 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 */
16package org.onosproject.bgpio.protocol.flowspec;
17
18import java.util.Iterator;
19import java.util.List;
20import java.util.ListIterator;
21import java.util.Objects;
22
23import org.jboss.netty.buffer.ChannelBuffer;
24import org.jboss.netty.buffer.ChannelBuffers;
25import org.onosproject.bgpio.types.BgpFsDestinationPortNum;
26import org.onosproject.bgpio.types.BgpFsDestinationPrefix;
27import org.onosproject.bgpio.types.BgpFsDscpValue;
28import org.onosproject.bgpio.types.BgpFsFragment;
29import org.onosproject.bgpio.types.BgpFsIcmpCode;
30import org.onosproject.bgpio.types.BgpFsIcmpType;
31import org.onosproject.bgpio.types.BgpFsIpProtocol;
32import org.onosproject.bgpio.types.BgpFsPacketLength;
33import org.onosproject.bgpio.types.BgpFsPortNum;
34import org.onosproject.bgpio.types.BgpFsSourcePortNum;
35import org.onosproject.bgpio.types.BgpFsSourcePrefix;
36import org.onosproject.bgpio.types.BgpFsTcpFlags;
37import org.onosproject.bgpio.types.BgpValueType;
38import org.onosproject.bgpio.types.RouteDistinguisher;
39import org.onosproject.bgpio.util.Constants;
40
41import com.google.common.base.MoreObjects;
42
43/**
44 * This Class stores flow specification components and action.
45 */
46public class BgpFlowSpecNlri {
47 private List<BgpValueType> flowSpecComponents;
48 private List<BgpValueType> fsActionTlv;
49 private RouteDistinguisher routeDistinguisher;
50 public static final short FLOW_SPEC_LEN = 240;
51
52 /**
53 * Flow specification details object constructor with the parameter.
54 *
55 * @param flowSpecComponents flow specification components
56 */
57 public BgpFlowSpecNlri(List<BgpValueType> flowSpecComponents) {
58 this.flowSpecComponents = flowSpecComponents;
59 }
60
61 /**
62 * Flow specification details object constructor.
63 *
64 */
65 public BgpFlowSpecNlri() {
66
67 }
68
69 /**
70 * Returns flow specification action tlv.
71 *
72 * @return flow specification action tlv
73 */
74 public List<BgpValueType> fsActionTlv() {
75 return this.fsActionTlv;
76 }
77
78 /**
79 * Set flow specification action tlv.
80 *
81 * @param fsActionTlv flow specification action tlv
82 */
83 public void setFsActionTlv(List<BgpValueType> fsActionTlv) {
84 this.fsActionTlv = fsActionTlv;
85 }
86
87 /**
88 * Returns route distinguisher for the flow specification components.
89 *
90 * @return route distinguisher for the flow specification components
91 */
92 public RouteDistinguisher routeDistinguisher() {
93 return this.routeDistinguisher;
94 }
95
96 /**
97 * Set route distinguisher for flow specification component.
98 *
99 * @param routeDistinguisher route distinguisher
100 */
101 public void setRouteDistinguiher(RouteDistinguisher routeDistinguisher) {
102 this.routeDistinguisher = routeDistinguisher;
103 }
104
105 /**
106 * Returns flow specification components.
107 *
108 * @return flow specification components
109 */
110 public List<BgpValueType> flowSpecComponents() {
111 return this.flowSpecComponents;
112 }
113
114 /**
115 * Sets flow specification components.
116 *
117 * @param flowSpecComponents flow specification components
118 */
119 public void setFlowSpecComponents(List<BgpValueType> flowSpecComponents) {
120 this.flowSpecComponents = flowSpecComponents;
121 }
122
123 @Override
124 public int hashCode() {
125 return Objects.hash(flowSpecComponents);
126 }
127
128 @Override
129 public boolean equals(Object obj) {
130 if (this == obj) {
131 return true;
132 }
133
134 if (obj instanceof BgpFlowSpecNlri) {
135 int countObjSubTlv = 0;
136 int countOtherSubTlv = 0;
137 boolean isCommonSubTlv = true;
138 BgpFlowSpecNlri other = (BgpFlowSpecNlri) obj;
139 Iterator<BgpValueType> objListIterator = other.flowSpecComponents.iterator();
140 countOtherSubTlv = other.flowSpecComponents.size();
141 countObjSubTlv = flowSpecComponents.size();
142 if (countObjSubTlv != countOtherSubTlv) {
143 return false;
144 } else {
145 while (objListIterator.hasNext() && isCommonSubTlv) {
146 BgpValueType subTlv = objListIterator.next();
147 if (flowSpecComponents.contains(subTlv) && other.flowSpecComponents.contains(subTlv)) {
148 isCommonSubTlv = Objects.equals(flowSpecComponents.get(flowSpecComponents.indexOf(subTlv)),
149 other.flowSpecComponents.get(other.flowSpecComponents.indexOf(subTlv)));
150 } else {
151 isCommonSubTlv = false;
152 }
153 }
154 return isCommonSubTlv;
155 }
156 }
157 return false;
158 }
159
160 /**
161 * Write flow type to channel buffer.
162 *
163 * @param tlv flow type
164 * @param cb channel buffer
165 */
166 public static void writeFlowType(BgpValueType tlv, ChannelBuffer cb) {
167
168 switch (tlv.getType()) {
169 case Constants.BGP_FLOWSPEC_DST_PREFIX:
170 BgpFsDestinationPrefix fsDstPrefix = (BgpFsDestinationPrefix) tlv;
171 fsDstPrefix.write(cb);
172 break;
173 case Constants.BGP_FLOWSPEC_SRC_PREFIX:
174 BgpFsSourcePrefix fsSrcPrefix = (BgpFsSourcePrefix) tlv;
175 fsSrcPrefix.write(cb);
176 break;
177 case Constants.BGP_FLOWSPEC_IP_PROTO:
178 BgpFsIpProtocol fsIpProtocol = (BgpFsIpProtocol) tlv;
179 fsIpProtocol.write(cb);
180 break;
181 case Constants.BGP_FLOWSPEC_PORT:
182 BgpFsPortNum fsPortNum = (BgpFsPortNum) tlv;
183 fsPortNum.write(cb);
184 break;
185 case Constants.BGP_FLOWSPEC_DST_PORT:
186 BgpFsDestinationPortNum fsDstPortNum = (BgpFsDestinationPortNum) tlv;
187 fsDstPortNum.write(cb);
188 break;
189 case Constants.BGP_FLOWSPEC_SRC_PORT:
190 BgpFsSourcePortNum fsSrcPortNum = (BgpFsSourcePortNum) tlv;
191 fsSrcPortNum.write(cb);
192 break;
193 case Constants.BGP_FLOWSPEC_ICMP_TP:
194 BgpFsIcmpType fsIcmpType = (BgpFsIcmpType) tlv;
195 fsIcmpType.write(cb);
196 break;
197 case Constants.BGP_FLOWSPEC_ICMP_CD:
198 BgpFsIcmpCode fsIcmpCode = (BgpFsIcmpCode) tlv;
199 fsIcmpCode.write(cb);
200 break;
201 case Constants.BGP_FLOWSPEC_TCP_FLAGS:
202 BgpFsTcpFlags fsTcpFlags = (BgpFsTcpFlags) tlv;
203 fsTcpFlags.write(cb);
204 break;
205 case Constants.BGP_FLOWSPEC_PCK_LEN:
206 BgpFsPacketLength fsPacketLen = (BgpFsPacketLength) tlv;
207 fsPacketLen.write(cb);
208 break;
209 case Constants.BGP_FLOWSPEC_DSCP:
210 BgpFsDscpValue fsDscpVal = (BgpFsDscpValue) tlv;
211 fsDscpVal.write(cb);
212 break;
213 case Constants.BGP_FLOWSPEC_FRAGMENT:
214 BgpFsFragment fsFragment = (BgpFsFragment) tlv;
215 fsFragment.write(cb);
216 break;
217 default:
218 break;
219 }
220 return;
221 }
222
223 /**
224 * Update buffer with identical flow types.
225 *
226 * @param cb channel buffer
227 */
228 public static void updateBufferIdenticalFlowTypes(ChannelBuffer cb, BgpFlowSpecNlri bgpFlowSpecNlri) {
229
230 List<BgpValueType> flowSpec = bgpFlowSpecNlri.flowSpecComponents();
231 ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
232
233 while (listIterator.hasNext()) {
234 ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
235 int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
236
237 BgpValueType tlv = listIterator.next();
238 writeFlowType(tlv, flowSpecTmpBuff);
239
240 /* RFC 5575: section 4, If the NLRI length value is smaller than 240 (0xf0 hex), the length
241 field can be encoded as a single octet. Otherwise, it is encoded as
242 an extended-length 2-octet values */
243 int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
244 if (len >= FLOW_SPEC_LEN) {
245 cb.writeShort(len);
246 } else {
247 cb.writeByte(len);
248 }
249 //Copy from bynamic buffer to channel buffer
250 cb.writeBytes(flowSpecTmpBuff);
251 }
252 return;
253 }
254
255 /**
256 * Update buffer with non-identical flow types.
257 *
258 * @param cb channel buffer
259 */
260 public static void updateBufferNonIdenticalFlowTypes(ChannelBuffer cb, BgpFlowSpecNlri bgpFlowSpecNlri) {
261 ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
262 List<BgpValueType> flowSpec = bgpFlowSpecNlri.flowSpecComponents();
263 ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
264 int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
265
266 flowSpec = bgpFlowSpecNlri.flowSpecComponents();
267 listIterator = flowSpec.listIterator();
268
269 while (listIterator.hasNext()) {
270 BgpValueType tlv = listIterator.next();
271 writeFlowType(tlv, flowSpecTmpBuff);
272 }
273
274 /* RFC 5575: section 4, If the NLRI length value is smaller than 240 (0xf0 hex), the length
275 field can be encoded as a single octet. Otherwise, it is encoded as
276 an extended-length 2-octet values */
277 int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
278 if (len >= FLOW_SPEC_LEN) {
279 cb.writeShort(len);
280 } else {
281 cb.writeByte(len);
282 }
283 //Copy from bynamic buffer to channel buffer
284 cb.writeBytes(flowSpecTmpBuff);
285 }
286
287 @Override
288 public String toString() {
289 return MoreObjects.toStringHelper(getClass())
290 .add("flowSpecComponents", flowSpecComponents)
291 .toString();
292 }
293}