blob: f4c86dc03b2a5aced83b98056c7dd1f663ce6e09 [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
Ray Milkeybb23e0b2016-08-02 17:00:21 -0700227 * @param bgpFlowSpecNlri flow specification
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530228 */
229 public static void updateBufferIdenticalFlowTypes(ChannelBuffer cb, BgpFlowSpecNlri bgpFlowSpecNlri) {
230
231 List<BgpValueType> flowSpec = bgpFlowSpecNlri.flowSpecComponents();
232 ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
233
234 while (listIterator.hasNext()) {
235 ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
236 int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
237
238 BgpValueType tlv = listIterator.next();
239 writeFlowType(tlv, flowSpecTmpBuff);
240
241 /* RFC 5575: section 4, If the NLRI length value is smaller than 240 (0xf0 hex), the length
242 field can be encoded as a single octet. Otherwise, it is encoded as
243 an extended-length 2-octet values */
244 int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
245 if (len >= FLOW_SPEC_LEN) {
246 cb.writeShort(len);
247 } else {
248 cb.writeByte(len);
249 }
250 //Copy from bynamic buffer to channel buffer
251 cb.writeBytes(flowSpecTmpBuff);
252 }
253 return;
254 }
255
256 /**
257 * Update buffer with non-identical flow types.
258 *
259 * @param cb channel buffer
Ray Milkeybb23e0b2016-08-02 17:00:21 -0700260 * @param bgpFlowSpecNlri flow specification
Shashikanth VH26fd38a2016-04-26 18:11:37 +0530261 */
262 public static void updateBufferNonIdenticalFlowTypes(ChannelBuffer cb, BgpFlowSpecNlri bgpFlowSpecNlri) {
263 ChannelBuffer flowSpecTmpBuff = ChannelBuffers.dynamicBuffer();
264 List<BgpValueType> flowSpec = bgpFlowSpecNlri.flowSpecComponents();
265 ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
266 int tmpBuffStartIndx = flowSpecTmpBuff.writerIndex();
267
268 flowSpec = bgpFlowSpecNlri.flowSpecComponents();
269 listIterator = flowSpec.listIterator();
270
271 while (listIterator.hasNext()) {
272 BgpValueType tlv = listIterator.next();
273 writeFlowType(tlv, flowSpecTmpBuff);
274 }
275
276 /* RFC 5575: section 4, If the NLRI length value is smaller than 240 (0xf0 hex), the length
277 field can be encoded as a single octet. Otherwise, it is encoded as
278 an extended-length 2-octet values */
279 int len = flowSpecTmpBuff.writerIndex() - tmpBuffStartIndx;
280 if (len >= FLOW_SPEC_LEN) {
281 cb.writeShort(len);
282 } else {
283 cb.writeByte(len);
284 }
285 //Copy from bynamic buffer to channel buffer
286 cb.writeBytes(flowSpecTmpBuff);
287 }
288
289 @Override
290 public String toString() {
291 return MoreObjects.toStringHelper(getClass())
292 .add("flowSpecComponents", flowSpecComponents)
293 .toString();
294 }
295}