blob: 7330a3ac9baae1926fdfd7fe7e94ece5ef9fd7bc [file] [log] [blame]
Priyanka B9bee0802016-04-27 22:06:02 +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.provider.bgpcep.flow.impl;
17
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053018import java.util.ArrayList;
19import java.util.Collection;
20import java.util.Collections;
Priyanka Bbd455ca2016-05-05 22:13:25 +053021import java.util.LinkedList;
22import java.util.List;
23
Priyanka B9bee0802016-04-27 22:06:02 +053024import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
Priyanka Bbd455ca2016-05-05 22:13:25 +053029import org.onlab.packet.Ip4Address;
30import org.onlab.packet.IpAddress;
31import org.onlab.packet.IpPrefix;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053032import org.onlab.packet.MplsLabel;
Priyanka B9bee0802016-04-27 22:06:02 +053033import org.onosproject.bgp.controller.BgpController;
Priyanka B9bee0802016-04-27 22:06:02 +053034import org.onosproject.core.ApplicationId;
Priyanka Bbd455ca2016-05-05 22:13:25 +053035import org.onosproject.incubator.net.resource.label.LabelResourceId;
36import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
37import org.onosproject.incubator.net.tunnel.Tunnel;
38import org.onosproject.incubator.net.tunnel.TunnelId;
39import org.onosproject.incubator.net.tunnel.TunnelService;
40import org.onosproject.net.ConnectPoint;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053041import org.onosproject.net.Device;
Priyanka Bbd455ca2016-05-05 22:13:25 +053042import org.onosproject.net.DeviceId;
43import org.onosproject.net.Link;
44import org.onosproject.net.Path;
45import org.onosproject.net.PortNumber;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053046import org.onosproject.net.device.DeviceService;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053047import org.onosproject.net.flow.CompletedBatchOperation;
48import org.onosproject.net.flow.DefaultFlowEntry;
49import org.onosproject.net.flow.FlowEntry;
Priyanka B9bee0802016-04-27 22:06:02 +053050import org.onosproject.net.flow.FlowRule;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053051import org.onosproject.net.flow.FlowRuleBatchEntry;
Priyanka B9bee0802016-04-27 22:06:02 +053052import org.onosproject.net.flow.FlowRuleBatchOperation;
53import org.onosproject.net.flow.FlowRuleProvider;
54import org.onosproject.net.flow.FlowRuleProviderRegistry;
55import org.onosproject.net.flow.FlowRuleProviderService;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053056import org.onosproject.net.flow.TrafficSelector;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053057import org.onosproject.net.flow.FlowEntry.FlowEntryState;
Priyanka B9bee0802016-04-27 22:06:02 +053058import org.onosproject.net.flow.criteria.Criterion;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053059import org.onosproject.net.flow.criteria.IPCriterion;
60import org.onosproject.net.flow.criteria.MetadataCriterion;
61import org.onosproject.net.flow.criteria.MplsBosCriterion;
62import org.onosproject.net.flow.criteria.MplsCriterion;
63import org.onosproject.net.flow.criteria.PortCriterion;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053064import org.onosproject.net.flow.criteria.TunnelIdCriterion;
Priyanka B9bee0802016-04-27 22:06:02 +053065import org.onosproject.net.provider.AbstractProvider;
66import org.onosproject.net.provider.ProviderId;
67import org.onosproject.net.resource.ResourceService;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +053068import org.onosproject.pcep.controller.PccId;
Priyanka B9bee0802016-04-27 22:06:02 +053069import org.onosproject.pcep.controller.PcepClient;
70import org.onosproject.pcep.controller.PcepClientController;
Priyanka Bbd455ca2016-05-05 22:13:25 +053071import org.onosproject.pcepio.exceptions.PcepParseException;
72import org.onosproject.pcepio.protocol.PcepEroObject;
73import org.onosproject.pcepio.protocol.PcepFecObjectIPv4;
74import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency;
75import org.onosproject.pcepio.protocol.PcepLabelObject;
76import org.onosproject.pcepio.protocol.PcepLabelUpdate;
77import org.onosproject.pcepio.protocol.PcepLabelUpdateMsg;
78import org.onosproject.pcepio.protocol.PcepLspObject;
79import org.onosproject.pcepio.protocol.PcepMsgPath;
80import org.onosproject.pcepio.protocol.PcepSrpObject;
81import org.onosproject.pcepio.protocol.PcepUpdateMsg;
82import org.onosproject.pcepio.protocol.PcepUpdateRequest;
83import org.onosproject.pcepio.types.IPv4SubObject;
84import org.onosproject.pcepio.types.NexthopIPv4addressTlv;
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +053085import org.onosproject.pcepio.types.PathSetupTypeTlv;
Priyanka Bbd455ca2016-05-05 22:13:25 +053086import org.onosproject.pcepio.types.PcepLabelDownload;
87import org.onosproject.pcepio.types.PcepLabelMap;
88import org.onosproject.pcepio.types.PcepValueType;
89import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +053090import org.onosproject.pcepio.types.SymbolicPathNameTlv;
91import org.onosproject.pcep.controller.LspType;
Priyanka Bc1e4e4c2016-07-01 14:57:19 +053092import org.onosproject.pcepio.protocol.PcepAttribute;
93import org.onosproject.pcepio.protocol.PcepBandwidthObject;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053094import org.onosproject.pcep.controller.SrpIdGenerators;
95import org.onosproject.pcep.controller.PcepAnnotationKeys;
Priyanka B9bee0802016-04-27 22:06:02 +053096import org.osgi.service.component.ComponentContext;
97import org.slf4j.Logger;
98
Priyanka Bc1e4e4c2016-07-01 14:57:19 +053099import static org.onosproject.pcep.controller.PcepAnnotationKeys.BANDWIDTH;
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530100import static org.onosproject.pcep.controller.PcepAnnotationKeys.DELEGATE;
101import static org.onosproject.pcep.controller.PcepAnnotationKeys.LSP_SIG_TYPE;
102import static org.onosproject.pcep.controller.PcepAnnotationKeys.PCE_INIT;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530103import static org.onosproject.pcep.controller.PcepSyncStatus.IN_SYNC;
104import static org.onosproject.pcep.controller.PcepSyncStatus.SYNCED;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530105import static org.onosproject.net.flow.criteria.Criterion.Type.EXTENSION;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530106import static com.google.common.base.Preconditions.checkNotNull;
Priyanka B9bee0802016-04-27 22:06:02 +0530107import static org.slf4j.LoggerFactory.getLogger;
108
109/**
110 * Implementation of BGP-PCEP flow provider.
111 */
112@Component(immediate = true)
113public class BgpcepFlowRuleProvider extends AbstractProvider
114 implements FlowRuleProvider {
115
116 private final Logger log = getLogger(getClass());
117
118 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
119 protected FlowRuleProviderRegistry providerRegistry;
120
121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Priyanka B9bee0802016-04-27 22:06:02 +0530122 protected BgpController bgpController;
123
124 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
125 protected PcepClientController pcepController;
126
127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
128 protected ResourceService resourceService;
129
Priyanka Bbd455ca2016-05-05 22:13:25 +0530130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
131 protected TunnelService tunnelService;
132
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
134 protected DeviceService deviceService;
135
Priyanka B9bee0802016-04-27 22:06:02 +0530136 private FlowRuleProviderService providerService;
Priyanka Bbd455ca2016-05-05 22:13:25 +0530137 private PcepLabelObject labelObj;
138 public static final int OUT_LABEL_TYPE = 0;
139 public static final int IN_LABEL_TYPE = 1;
140 public static final long IDENTIFIER_SET = 0x100000000L;
141 public static final long SET = 0xFFFFFFFFL;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530142 private static final String LSRID = "lsrId";
Priyanka B9bee0802016-04-27 22:06:02 +0530143
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530144 private enum PcepFlowType {
145 ADD,
146 MODIFY,
147 REMOVE
148 }
149
Priyanka B9bee0802016-04-27 22:06:02 +0530150 /**
151 * Creates a BgpFlow host provider.
152 */
153 public BgpcepFlowRuleProvider() {
154 super(new ProviderId("l3", "org.onosproject.provider.bgpcep"));
155 }
156
157 @Activate
158 public void activate(ComponentContext context) {
Priyanka B9bee0802016-04-27 22:06:02 +0530159 providerService = providerRegistry.register(this);
160 log.info("Started");
161 }
162
163 @Deactivate
164 public void deactivate(ComponentContext context) {
Priyanka B9bee0802016-04-27 22:06:02 +0530165 providerRegistry.unregister(this);
166 providerService = null;
167 log.info("Stopped");
168 }
169
170 @Override
171 public void applyFlowRule(FlowRule... flowRules) {
172 for (FlowRule flowRule : flowRules) {
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530173 processRule(flowRule, PcepFlowType.ADD);
Priyanka B9bee0802016-04-27 22:06:02 +0530174 }
175 }
176
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530177 @Override
178 public void removeFlowRule(FlowRule... flowRules) {
179 for (FlowRule flowRule : flowRules) {
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530180 processRule(flowRule, PcepFlowType.REMOVE);
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530181 }
182 }
Priyanka B9bee0802016-04-27 22:06:02 +0530183
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530184 private void processRule(FlowRule flowRule, PcepFlowType type) {
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530185 MplsLabel mplsLabel = null;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530186 IpPrefix ip4PrefixSrc = null;
187 IpPrefix ip4PrefixDst = null;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530188 PortNumber port = null;
189 TunnelId tunnelId = null;
190 long labelType = 0;
191 boolean bottomOfStack = false;
Priyanka B9bee0802016-04-27 22:06:02 +0530192
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530193 TrafficSelector selector = flowRule.selector();
194 for (Criterion c : selector.criteria()) {
195 switch (c.type()) {
196 case MPLS_LABEL:
197 MplsCriterion lc = (MplsCriterion) c;
198 mplsLabel = lc.label();
199 break;
200 case IPV4_SRC:
201 IPCriterion ipCriterion = (IPCriterion) c;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530202 ip4PrefixSrc = ipCriterion.ip().getIp4Prefix();
203 break;
204 case IPV4_DST:
205 ipCriterion = (IPCriterion) c;
206 ip4PrefixDst = ipCriterion.ip().getIp4Prefix();
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530207 break;
208 case IN_PORT:
209 PortCriterion inPort = (PortCriterion) c;
210 port = inPort.port();
211 break;
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530212 case TUNNEL_ID:
213 TunnelIdCriterion tc = (TunnelIdCriterion) c;
214 tunnelId = TunnelId.valueOf(String.valueOf(tc.tunnelId()));
215 break;
216 case METADATA:
217 MetadataCriterion metadata = (MetadataCriterion) c;
218 labelType = metadata.metadata();
219 break;
220 case MPLS_BOS:
221 MplsBosCriterion mplsBos = (MplsBosCriterion) c;
222 bottomOfStack = mplsBos.mplsBos();
223 break;
224 default:
225 break;
226 }
227 }
228
229 checkNotNull(mplsLabel);
230 LabelResourceId label = LabelResourceId.labelResourceId(mplsLabel.toInt());
231
232 try {
233 if (tunnelId != null) {
234 pushLocalLabels(flowRule.deviceId(), label, port, tunnelId, bottomOfStack, labelType, type);
235 return;
236 }
237
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530238 if (ip4PrefixDst != null) {
239 pushAdjacencyLabel(flowRule.deviceId(), label, ip4PrefixSrc, ip4PrefixDst, type);
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530240 return;
241 }
242
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530243 pushGlobalNodeLabel(flowRule.deviceId(), label, ip4PrefixSrc, type, bottomOfStack);
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530244
245 } catch (PcepParseException e) {
246 log.error("Exception occured while sending label message to PCC {}", e.getMessage());
247 }
248
Priyanka B9bee0802016-04-27 22:06:02 +0530249 }
250
Priyanka Bbd455ca2016-05-05 22:13:25 +0530251 /**
252 * Returns PCEP client.
253 *
254 * @return PCEP client
255 */
256 private PcepClient getPcepClient(DeviceId deviceId) {
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530257 Device device = deviceService.getDevice(deviceId);
Priyanka Bbd455ca2016-05-05 22:13:25 +0530258
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530259 // In future projections instead of annotations will be used to fetch LSR ID.
260 String lsrId = device.annotations().value(LSRID);
261
262 PcepClient pcc = pcepController.getClient(PccId.pccId(IpAddress.valueOf(lsrId)));
263 return pcc;
Priyanka Bbd455ca2016-05-05 22:13:25 +0530264 }
265
266 //Pushes node labels to the specified device.
267 private void pushGlobalNodeLabel(DeviceId deviceId, LabelResourceId labelId,
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530268 IpPrefix ipPrefix, PcepFlowType type, boolean isBos) throws PcepParseException {
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530269
270 checkNotNull(deviceId);
271 checkNotNull(labelId);
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530272 checkNotNull(type);
273
Priyanka Bbd455ca2016-05-05 22:13:25 +0530274 PcepClient pc = getPcepClient(deviceId);
275 if (pc == null) {
276 log.error("PCEP client not found");
277 return;
278 }
279
280 LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
281
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530282 if (ipPrefix == null) {
283 // Pushing self node label to device.
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530284 ipPrefix = IpPrefix.valueOf(pc.getPccId().ipAddress(), 32);
Avantika-Huaweia4f66f62016-05-25 16:52:08 +0530285 }
286
Priyanka Bbd455ca2016-05-05 22:13:25 +0530287 PcepFecObjectIPv4 fecObject = pc.factory().buildFecObjectIpv4()
288 .setNodeID(ipPrefix.address().getIp4Address().toInt())
289 .build();
290
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530291 boolean bSFlag = false;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530292 if (pc.labelDbSyncStatus() == IN_SYNC && !isBos) {
293 // Need to set sync flag in all messages till sync completes.
294 bSFlag = true;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530295 }
296
297 PcepSrpObject srpObj = getSrpObject(pc, type, bSFlag);
Priyanka Bbd455ca2016-05-05 22:13:25 +0530298
299 //Global NODE-SID as label object
300 PcepLabelObject labelObject = pc.factory().buildLabelObject()
301 .setLabel((int) labelId.labelId())
302 .build();
303
304 PcepLabelMap labelMap = new PcepLabelMap();
305 labelMap.setFecObject(fecObject);
306 labelMap.setLabelObject(labelObject);
307 labelMap.setSrpObject(srpObj);
308
309 labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
310 .setLabelMap(labelMap)
311 .build());
312
313 PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
314 .setPcLabelUpdateList(labelUpdateList)
315 .build();
316
317 pc.sendMessage(labelMsg);
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530318
319 if (isBos) {
320 // Sync is completed.
321 pc.setLabelDbSyncStatus(SYNCED);
322 }
Priyanka Bbd455ca2016-05-05 22:13:25 +0530323 }
324
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530325 private PcepSrpObject getSrpObject(PcepClient pc, PcepFlowType type, boolean bSFlag)
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530326 throws PcepParseException {
Priyanka Bbd455ca2016-05-05 22:13:25 +0530327 PcepSrpObject srpObj;
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530328 boolean bRFlag = false;
329
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530330 if (!type.equals(PcepFlowType.ADD)) {
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530331 // To cleanup labels, R bit is set
332 bRFlag = true;
Priyanka Bbd455ca2016-05-05 22:13:25 +0530333 }
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530334
335 srpObj = pc.factory().buildSrpObject()
336 .setRFlag(bRFlag)
337 .setSFlag(bSFlag)
338 .setSrpID(SrpIdGenerators.create())
339 .build();
340
Priyanka Bbd455ca2016-05-05 22:13:25 +0530341 return srpObj;
342 }
343
344 //Pushes adjacency labels to the specified device.
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530345 private void pushAdjacencyLabel(DeviceId deviceId, LabelResourceId labelId, IpPrefix ip4PrefixSrc,
346 IpPrefix ip4PrefixDst, PcepFlowType type)
347 throws PcepParseException {
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530348
349 checkNotNull(deviceId);
350 checkNotNull(labelId);
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530351 checkNotNull(ip4PrefixSrc);
352 checkNotNull(ip4PrefixDst);
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530353 checkNotNull(type);
354
Priyanka Bbd455ca2016-05-05 22:13:25 +0530355 PcepClient pc = getPcepClient(deviceId);
356 if (pc == null) {
357 log.error("PCEP client not found");
358 return;
359 }
360
361 LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
362
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530363 int srcPortNo = ip4PrefixSrc.address().getIp4Address().toInt();
364 int dstPortNo = ip4PrefixDst.address().getIp4Address().toInt();
Priyanka Bbd455ca2016-05-05 22:13:25 +0530365
366 PcepFecObjectIPv4Adjacency fecAdjObject = pc.factory().buildFecIpv4Adjacency()
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530367 .seRemoteIPv4Address(dstPortNo)
368 .seLocalIPv4Address(srcPortNo)
Priyanka Bbd455ca2016-05-05 22:13:25 +0530369 .build();
370
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530371 boolean bSFlag = false;
372 if (pc.labelDbSyncStatus() == IN_SYNC) {
373 // Need to set sync flag in all messages till sync completes.
374 bSFlag = true;
375 }
376
377 PcepSrpObject srpObj = getSrpObject(pc, type, bSFlag);
Priyanka Bbd455ca2016-05-05 22:13:25 +0530378
379 //Adjacency label object
380 PcepLabelObject labelObject = pc.factory().buildLabelObject()
381 .setLabel((int) labelId.labelId())
382 .build();
383
384 PcepLabelMap labelMap = new PcepLabelMap();
385 labelMap.setFecObject(fecAdjObject);
386 labelMap.setLabelObject(labelObject);
387 labelMap.setSrpObject(srpObj);
388
389 labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
390 .setLabelMap(labelMap)
391 .build());
392
393 PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
394 .setPcLabelUpdateList(labelUpdateList)
395 .build();
396
397 pc.sendMessage(labelMsg);
398 }
399
400 //Pushes local labels to the device which is specific to path [CR-case].
401 private void pushLocalLabels(DeviceId deviceId, LabelResourceId labelId,
402 PortNumber portNum, TunnelId tunnelId,
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530403 Boolean isBos, Long labelType, PcepFlowType type) throws PcepParseException {
Priyanka Bbd455ca2016-05-05 22:13:25 +0530404
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530405 checkNotNull(deviceId);
406 checkNotNull(labelId);
407 checkNotNull(portNum);
408 checkNotNull(tunnelId);
409 checkNotNull(labelType);
410 checkNotNull(type);
411
Priyanka Bbd455ca2016-05-05 22:13:25 +0530412 PcepClient pc = getPcepClient(deviceId);
413 if (pc == null) {
414 log.error("PCEP client not found");
415 return;
416 }
417
418 PcepLspObject lspObj;
419 LinkedList<PcepLabelUpdate> labelUpdateList = new LinkedList<>();
420 LinkedList<PcepLabelObject> labelObjects = new LinkedList<>();
421 PcepSrpObject srpObj;
422 PcepLabelDownload labelDownload = new PcepLabelDownload();
423 LinkedList<PcepValueType> optionalTlv = new LinkedList<>();
424
425 long portNo = portNum.toLong();
426 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
427
428 optionalTlv.add(NexthopIPv4addressTlv.of((int) portNo));
429
430 Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
431
432 PcepLabelObject labelObj = pc.factory().buildLabelObject()
433 .setOFlag(labelType == OUT_LABEL_TYPE ? true : false)
434 .setOptionalTlv(optionalTlv)
435 .setLabel((int) labelId.labelId())
436 .build();
437
438 /**
439 * Check whether transit node or not. For transit node, label update message should include IN and OUT labels.
440 * Hence store IN label object and next when out label comes add IN and OUT label objects and encode label
441 * update message and send to specified client.
442 */
443 if (!deviceId.equals(tunnel.path().src().deviceId()) && !deviceId.equals(tunnel.path().dst().deviceId())) {
444 //Device is transit node
445 if (labelType == IN_LABEL_TYPE) {
446 //Store label object having IN label value
447 this.labelObj = labelObj;
448 return;
449 }
450 //Add IN label object
451 labelObjects.add(this.labelObj);
452 }
453
454 //Add OUT label object in case of transit node
455 labelObjects.add(labelObj);
456
Avantika-Huawei7c14e662016-05-16 19:13:34 +0530457 srpObj = getSrpObject(pc, type, false);
Priyanka Bbd455ca2016-05-05 22:13:25 +0530458
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530459 String lspId = tunnel.annotations().value(PcepAnnotationKeys.LOCAL_LSP_ID);
460 String plspId = tunnel.annotations().value(PcepAnnotationKeys.PLSP_ID);
Priyanka Bbd455ca2016-05-05 22:13:25 +0530461 String tunnelIdentifier = tunnel.annotations().value(PcepAnnotationKeys.PCC_TUNNEL_ID);
462
463 LinkedList<PcepValueType> tlvs = new LinkedList<>();
464 StatefulIPv4LspIdentifiersTlv lspIdTlv = new StatefulIPv4LspIdentifiersTlv(((IpTunnelEndPoint) tunnel.src())
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530465 .ip().getIp4Address().toInt(), Short.valueOf(lspId), Short.valueOf(tunnelIdentifier),
466 ((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt(),
Priyanka Bbd455ca2016-05-05 22:13:25 +0530467 ((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt());
468 tlvs.add(lspIdTlv);
469
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530470 if (tunnel.tunnelName().value() != null) {
471 SymbolicPathNameTlv pathNameTlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
472 tlvs.add(pathNameTlv);
473 }
474
475 boolean delegated = (tunnel.annotations().value(DELEGATE) == null) ? false
476 : Boolean.valueOf(tunnel.annotations()
477 .value(DELEGATE));
478 boolean initiated = (tunnel.annotations().value(PCE_INIT) == null) ? false
479 : Boolean.valueOf(tunnel.annotations()
480 .value(PCE_INIT));
481
Priyanka Bbd455ca2016-05-05 22:13:25 +0530482 lspObj = pc.factory().buildLspObject()
483 .setRFlag(false)
484 .setAFlag(true)
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530485 .setDFlag(delegated)
486 .setCFlag(initiated)
Priyanka Bbd455ca2016-05-05 22:13:25 +0530487 .setPlspId(Integer.valueOf(plspId))
488 .setOptionalTlv(tlvs)
489 .build();
490
491 labelDownload.setLabelList(labelObjects);
492 labelDownload.setLspObject(lspObj);
493 labelDownload.setSrpObject(srpObj);
494
495 labelUpdateList.add(pc.factory().buildPcepLabelUpdateObject()
496 .setLabelDownload(labelDownload)
497 .build());
498
499 PcepLabelUpdateMsg labelMsg = pc.factory().buildPcepLabelUpdateMsg()
500 .setPcLabelUpdateList(labelUpdateList)
501 .build();
502
503 pc.sendMessage(labelMsg);
504
505 //If isBos is true, label download is done along the LSP, send PCEP update message.
506 if (isBos) {
507 sendPcepUpdateMsg(pc, lspObj, tunnel);
508 }
509 }
510
511 //Sends PCEP update message.
512 private void sendPcepUpdateMsg(PcepClient pc, PcepLspObject lspObj, Tunnel tunnel) throws PcepParseException {
513 LinkedList<PcepUpdateRequest> updateRequestList = new LinkedList<>();
514 LinkedList<PcepValueType> subObjects = createEroSubObj(tunnel.path());
515
516 if (subObjects == null) {
517 log.error("ERO subjects not present");
518 return;
519 }
520
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530521 // set PathSetupTypeTlv of SRP object
522 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
523 LspType lspSigType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
524 llOptionalTlv.add(new PathSetupTypeTlv(lspSigType.type()));
525
Priyanka Bbd455ca2016-05-05 22:13:25 +0530526 PcepSrpObject srpObj = pc.factory().buildSrpObject()
527 .setRFlag(false)
528 .setSrpID(SrpIdGenerators.create())
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530529 .setOptionalTlv(llOptionalTlv)
Priyanka Bbd455ca2016-05-05 22:13:25 +0530530 .build();
531
532 PcepEroObject eroObj = pc.factory().buildEroObject()
533 .setSubObjects(subObjects)
534 .build();
535
Priyanka Bc1e4e4c2016-07-01 14:57:19 +0530536 float iBandwidth = 0;
537 if (tunnel.annotations().value(BANDWIDTH) != null) {
538 //iBandwidth = Float.floatToIntBits(Float.parseFloat(tunnel.annotations().value(BANDWIDTH)));
539 iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
540 }
541 // build bandwidth object
542 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject()
543 .setBandwidth(iBandwidth)
544 .build();
545 // build pcep attribute
546 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute()
547 .setBandwidthObject(bandwidthObject)
548 .build();
549
Priyanka Bbd455ca2016-05-05 22:13:25 +0530550 PcepMsgPath msgPath = pc.factory().buildPcepMsgPath()
551 .setEroObject(eroObj)
Priyanka Bc1e4e4c2016-07-01 14:57:19 +0530552 .setPcepAttribute(pcepAttribute)
Priyanka Bbd455ca2016-05-05 22:13:25 +0530553 .build();
554
555 PcepUpdateRequest updateReq = pc.factory().buildPcepUpdateRequest()
556 .setSrpObject(srpObj)
557 .setMsgPath(msgPath)
558 .setLspObject(lspObj)
559 .build();
560
561 updateRequestList.add(updateReq);
562
563 //TODO: P = 1 is it P flag in PCEP obj header
564 PcepUpdateMsg updateMsg = pc.factory().buildUpdateMsg()
565 .setUpdateRequestList(updateRequestList)
566 .build();
567
568 pc.sendMessage(updateMsg);
569 }
570
571 private LinkedList<PcepValueType> createEroSubObj(Path path) {
572 LinkedList<PcepValueType> subObjects = new LinkedList<>();
573 List<Link> links = path.links();
574 ConnectPoint source = null;
575 ConnectPoint destination = null;
576 IpAddress ipDstAddress = null;
577 IpAddress ipSrcAddress = null;
578 PcepValueType subObj = null;
579 long portNo;
580
581 for (Link link : links) {
582 source = link.src();
583 if (!(source.equals(destination))) {
584 //set IPv4SubObject for ERO object
585 portNo = source.port().toLong();
586 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
587 ipSrcAddress = Ip4Address.valueOf((int) portNo);
588 subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
589 subObjects.add(subObj);
590 }
591
592 destination = link.dst();
593 portNo = destination.port().toLong();
594 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
595 ipDstAddress = Ip4Address.valueOf((int) portNo);
596 subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
597 subObjects.add(subObj);
598 }
599 return subObjects;
600 }
601
Priyanka B9bee0802016-04-27 22:06:02 +0530602 @Override
Priyanka B9bee0802016-04-27 22:06:02 +0530603 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
604 // TODO
605 removeFlowRule(flowRules);
606 }
607
608 @Override
609 public void executeBatch(FlowRuleBatchOperation batch) {
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530610 Collection<FlowEntry> flowEntries = new ArrayList<>();
611
612 for (FlowRuleBatchEntry fbe : batch.getOperations()) {
613 Criterion criteria = fbe.target().selector().getCriterion(EXTENSION);
614
615 switch (fbe.operator()) {
616 case ADD:
617 if (criteria == null) {
618 processRule(fbe.target(), PcepFlowType.ADD);
619 flowEntries.add(new DefaultFlowEntry(fbe.target(), FlowEntryState.ADDED, 0, 0, 0));
620 }
621 break;
622 case REMOVE:
623 if (criteria == null) {
624 processRule(fbe.target(), PcepFlowType.REMOVE);
625 flowEntries.add(new DefaultFlowEntry(fbe.target(), FlowEntryState.REMOVED, 0, 0, 0));
626 }
627 break;
628 default:
629 log.error("Unknown flow operation: {}", fbe);
630 }
631 }
632
633 CompletedBatchOperation status = new CompletedBatchOperation(true, Collections.emptySet(), batch.deviceId());
634 providerService.batchOperationCompleted(batch.id(), status);
635 providerService.pushFlowMetrics(batch.deviceId(), flowEntries);
Priyanka B9bee0802016-04-27 22:06:02 +0530636 }
637}