blob: 844852814bd3dadd6470627b7153529a80afff10 [file] [log] [blame]
cheng fan48e832c2015-05-29 01:54:47 +08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
cheng fan48e832c2015-05-29 01:54:47 +08003 *
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.pcep.tunnel.impl;
17
chengfan2fff70f2015-08-24 18:20:19 -050018import com.google.common.collect.Maps;
Avantika-Huawei56c11842016-04-28 00:56:56 +053019
cheng fan48e832c2015-05-29 01:54:47 +080020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
chengfan2fff70f2015-08-24 18:20:19 -050023import org.apache.felix.scr.annotations.Property;
cheng fan48e832c2015-05-29 01:54:47 +080024import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
Priyanka Bcdf9b102016-06-07 20:01:38 +053027import org.onlab.packet.Ip4Address;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053028import org.onlab.packet.IpAddress;
chengfan2fff70f2015-08-24 18:20:19 -050029import org.onosproject.cfg.ComponentConfigService;
cheng fan48e832c2015-05-29 01:54:47 +080030import org.onosproject.core.DefaultGroupId;
31import org.onosproject.incubator.net.tunnel.DefaultOpticalTunnelEndPoint;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053032import org.onosproject.incubator.net.tunnel.DefaultTunnel;
cheng fan48e832c2015-05-29 01:54:47 +080033import org.onosproject.incubator.net.tunnel.DefaultTunnelDescription;
chengfan2fff70f2015-08-24 18:20:19 -050034import org.onosproject.incubator.net.tunnel.DefaultTunnelStatistics;
Jonathan Hart51539b82015-10-29 09:53:04 -070035import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
cheng fan48e832c2015-05-29 01:54:47 +080036import org.onosproject.incubator.net.tunnel.OpticalLogicId;
37import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
38import org.onosproject.incubator.net.tunnel.Tunnel;
Avantika-Huawei56c11842016-04-28 00:56:56 +053039import org.onosproject.incubator.net.tunnel.Tunnel.State;
Priyanka B413fbe82016-05-26 11:44:45 +053040import org.onosproject.incubator.net.tunnel.TunnelAdminService;
cheng fan48e832c2015-05-29 01:54:47 +080041import org.onosproject.incubator.net.tunnel.TunnelDescription;
42import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
43import org.onosproject.incubator.net.tunnel.TunnelId;
44import org.onosproject.incubator.net.tunnel.TunnelName;
45import org.onosproject.incubator.net.tunnel.TunnelProvider;
46import org.onosproject.incubator.net.tunnel.TunnelProviderRegistry;
47import org.onosproject.incubator.net.tunnel.TunnelProviderService;
chengfan2fff70f2015-08-24 18:20:19 -050048import org.onosproject.incubator.net.tunnel.TunnelService;
49import org.onosproject.incubator.net.tunnel.TunnelStatistics;
Priyanka B413fbe82016-05-26 11:44:45 +053050import org.onosproject.mastership.MastershipService;
51import org.onosproject.net.AnnotationKeys;
cheng fan48e832c2015-05-29 01:54:47 +080052import org.onosproject.net.ConnectPoint;
53import org.onosproject.net.DefaultAnnotations;
Avantika-Huawei56c11842016-04-28 00:56:56 +053054import org.onosproject.net.DefaultAnnotations.Builder;
cheng fan48e832c2015-05-29 01:54:47 +080055import org.onosproject.net.DefaultLink;
56import org.onosproject.net.DefaultPath;
Priyanka B413fbe82016-05-26 11:44:45 +053057import org.onosproject.net.Device;
cheng fan48e832c2015-05-29 01:54:47 +080058import org.onosproject.net.DeviceId;
59import org.onosproject.net.ElementId;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053060import org.onosproject.net.IpElementId;
cheng fan48e832c2015-05-29 01:54:47 +080061import org.onosproject.net.Link;
62import org.onosproject.net.Path;
63import org.onosproject.net.PortNumber;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053064import org.onosproject.net.SparseAnnotations;
Priyanka B413fbe82016-05-26 11:44:45 +053065import org.onosproject.net.device.DeviceService;
cheng fan48e832c2015-05-29 01:54:47 +080066import org.onosproject.net.provider.AbstractProvider;
67import org.onosproject.net.provider.ProviderId;
68import org.onosproject.pcep.api.PcepController;
69import org.onosproject.pcep.api.PcepDpid;
70import org.onosproject.pcep.api.PcepHopNodeDescription;
71import org.onosproject.pcep.api.PcepOperator.OperationType;
72import org.onosproject.pcep.api.PcepTunnel;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053073import org.onosproject.pcep.api.PcepTunnel.PathState;
Jonathan Hart51539b82015-10-29 09:53:04 -070074import org.onosproject.pcep.api.PcepTunnel.PathType;
cheng fan48e832c2015-05-29 01:54:47 +080075import org.onosproject.pcep.api.PcepTunnelListener;
chengfan2fff70f2015-08-24 18:20:19 -050076import org.onosproject.pcep.api.PcepTunnelStatistics;
Priyanka B413fbe82016-05-26 11:44:45 +053077import org.onosproject.pcep.controller.LspKey;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053078import org.onosproject.pcep.controller.PccId;
79import org.onosproject.pcep.controller.PcepClient;
80import org.onosproject.pcep.controller.PcepClientController;
81import org.onosproject.pcep.controller.PcepClientListener;
82import org.onosproject.pcep.controller.PcepEventListener;
Priyanka B259847d2016-06-03 21:28:35 +053083import org.onosproject.pcep.controller.PcepLspStatus;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053084import org.onosproject.pcep.controller.PcepLspSyncAction;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053085import org.onosproject.pcep.controller.SrpIdGenerators;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053086import org.onosproject.pcepio.exceptions.PcepParseException;
87import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
88import org.onosproject.pcepio.protocol.PcepAttribute;
89import org.onosproject.pcepio.protocol.PcepBandwidthObject;
90import org.onosproject.pcepio.protocol.PcepEndPointsObject;
91import org.onosproject.pcepio.protocol.PcepEroObject;
92import org.onosproject.pcepio.protocol.PcepInitiateMsg;
93import org.onosproject.pcepio.protocol.PcepLspObject;
94import org.onosproject.pcepio.protocol.PcepMessage;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053095import org.onosproject.pcepio.protocol.PcepMetricObject;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053096import org.onosproject.pcepio.protocol.PcepMsgPath;
97import org.onosproject.pcepio.protocol.PcepReportMsg;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053098import org.onosproject.pcepio.protocol.PcepSrpObject;
99import org.onosproject.pcepio.protocol.PcepStateReport;
100import org.onosproject.pcepio.protocol.PcepUpdateMsg;
101import org.onosproject.pcepio.protocol.PcepUpdateRequest;
102import org.onosproject.pcepio.types.IPv4SubObject;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530103import org.onosproject.pcepio.types.PathSetupTypeTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530104import org.onosproject.pcepio.types.PcepValueType;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530105import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530106import org.onosproject.pcepio.types.SymbolicPathNameTlv;
chengfan2fff70f2015-08-24 18:20:19 -0500107import org.osgi.service.component.ComponentContext;
Jonathan Hart51539b82015-10-29 09:53:04 -0700108import org.osgi.service.component.annotations.Modified;
109import org.slf4j.Logger;
110
111import java.util.ArrayList;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530112import java.util.Arrays;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530113import java.util.Collection;
Jonathan Hart51539b82015-10-29 09:53:04 -0700114import java.util.Collections;
115import java.util.Dictionary;
116import java.util.HashMap;
117import java.util.LinkedList;
118import java.util.List;
119import java.util.ListIterator;
120import java.util.Optional;
Priyanka B413fbe82016-05-26 11:44:45 +0530121import java.util.concurrent.Executors;
122import java.util.concurrent.ScheduledExecutorService;
123import java.util.concurrent.TimeUnit;
Jonathan Hart51539b82015-10-29 09:53:04 -0700124
125import static com.google.common.base.Preconditions.checkNotNull;
126import static com.google.common.base.Strings.isNullOrEmpty;
127import static org.onlab.util.Tools.get;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530128import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
Jonathan Hart51539b82015-10-29 09:53:04 -0700129import static org.onosproject.net.DefaultAnnotations.EMPTY;
130import static org.onosproject.net.DeviceId.deviceId;
131import static org.onosproject.net.PortNumber.portNumber;
132import static org.onosproject.pcep.api.PcepDpid.uri;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530133import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530134import static org.onosproject.provider.pcep.tunnel.impl.LspType.SR_WITHOUT_SIGNALLING;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530135import static org.onosproject.pcep.controller.PcepAnnotationKeys.BANDWIDTH;
136import static org.onosproject.pcep.controller.PcepAnnotationKeys.LOCAL_LSP_ID;
137import static org.onosproject.pcep.controller.PcepAnnotationKeys.LSP_SIG_TYPE;
138import static org.onosproject.pcep.controller.PcepAnnotationKeys.PCC_TUNNEL_ID;
139import static org.onosproject.pcep.controller.PcepAnnotationKeys.PLSP_ID;
140import static org.onosproject.pcep.controller.PcepAnnotationKeys.DELEGATE;
141import static org.onosproject.pcep.controller.PcepAnnotationKeys.COST_TYPE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530142import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
143import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
144import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
145import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530146import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530147import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
148import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
149import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
150import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
151import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
Jonathan Hart51539b82015-10-29 09:53:04 -0700152import static org.slf4j.LoggerFactory.getLogger;
cheng fan48e832c2015-05-29 01:54:47 +0800153
154/**
155 * Provider which uses an PCEP controller to detect, update, create network
156 * tunnels.
157 */
158@Component(immediate = true)
159@Service
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530160public class PcepTunnelProvider extends AbstractProvider implements TunnelProvider {
cheng fan48e832c2015-05-29 01:54:47 +0800161
162 private static final Logger log = getLogger(PcepTunnelProvider.class);
163 private static final long MAX_BANDWIDTH = 99999744;
164 private static final long MIN_BANDWIDTH = 64;
cheng fan7716ec92015-05-31 01:53:19 +0800165 private static final String BANDWIDTH_UINT = "kbps";
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530166 static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
Priyanka B413fbe82016-05-26 11:44:45 +0530167 public static final long IDENTIFIER_SET = 0x100000000L;
168 public static final long SET = 0xFFFFFFFFL;
169 private static final int DELAY = 2;
170 private static final int WAIT_TIME = 5;
171 public static final String LSRID = "lsrId";
cheng fan48e832c2015-05-29 01:54:47 +0800172
chengfan2fff70f2015-08-24 18:20:19 -0500173 static final int POLL_INTERVAL = 10;
174 @Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
175 label = "Frequency (in seconds) for polling tunnel statistics")
176 private int tunnelStatsPollFrequency = POLL_INTERVAL;
177
cheng fan48e832c2015-05-29 01:54:47 +0800178 private static final String TUNNLE_NOT_NULL = "Create failed,The given port may be wrong or has been occupied.";
179
180 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
181 protected TunnelProviderRegistry tunnelProviderRegistry;
182
183 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
184 protected PcepController controller;
185
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530186 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
187 protected PcepClientController pcepClientController;
chengfan2fff70f2015-08-24 18:20:19 -0500188
189 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
190 protected TunnelService tunnelService;
191
192 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
193 protected ComponentConfigService cfgService;
194
Priyanka B413fbe82016-05-26 11:44:45 +0530195 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
196 protected TunnelAdminService tunnelAdminService;
197
198 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
199 protected MastershipService mastershipService;
200
201 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
202 protected DeviceService deviceService;
203
cheng fan48e832c2015-05-29 01:54:47 +0800204 TunnelProviderService service;
205
206 HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
chengfan2fff70f2015-08-24 18:20:19 -0500207 HashMap<TunnelId, TunnelStatistics> tunnelStatisticsMap = new HashMap<>();
Brian Stanke9a108972016-04-11 15:25:17 -0400208 private HashMap<String, TunnelStatsCollector> collectors = Maps.newHashMap();
cheng fan48e832c2015-05-29 01:54:47 +0800209
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530210 private InnerTunnelProvider listener = new InnerTunnelProvider();
211
Jonathan Hart51539b82015-10-29 09:53:04 -0700212 protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530213 private static final int DEFAULT_BANDWIDTH_VALUE = 10;
cheng fan48e832c2015-05-29 01:54:47 +0800214
215 /**
216 * Creates a Tunnel provider.
217 */
218 public PcepTunnelProvider() {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530219 super(new ProviderId("pcep", PROVIDER_ID));
cheng fan48e832c2015-05-29 01:54:47 +0800220 }
221
222 @Activate
223 public void activate() {
chengfan2fff70f2015-08-24 18:20:19 -0500224 cfgService.registerProperties(getClass());
cheng fan48e832c2015-05-29 01:54:47 +0800225 service = tunnelProviderRegistry.register(this);
226 controller.addTunnelListener(listener);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530227 pcepClientController.addListener(listener);
228 pcepClientController.addEventListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500229 tunnelService.queryAllTunnels().forEach(tunnel -> {
Jonathan Hart51539b82015-10-29 09:53:04 -0700230 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
chengfan2fff70f2015-08-24 18:20:19 -0500231 TunnelStatsCollector tsc = new TunnelStatsCollector(pcepTunnelId, tunnelStatsPollFrequency);
232 tsc.start();
233 collectors.put(tunnel.tunnelId().id(), tsc);
234
235 });
236
cheng fan48e832c2015-05-29 01:54:47 +0800237 log.info("Started");
238 }
239
240 @Deactivate
241 public void deactivate() {
242 tunnelProviderRegistry.unregister(this);
243 controller.removeTunnelListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500244 collectors.values().forEach(TunnelStatsCollector::stop);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530245 pcepClientController.removeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800246 log.info("Stopped");
247 }
248
chengfan2fff70f2015-08-24 18:20:19 -0500249 @Modified
250 public void modified(ComponentContext context) {
251 Dictionary<?, ?> properties = context.getProperties();
252 int newTunnelStatsPollFrequency;
253 try {
254 String s = get(properties, "tunnelStatsPollFrequency");
255 newTunnelStatsPollFrequency = isNullOrEmpty(s) ? tunnelStatsPollFrequency : Integer.parseInt(s.trim());
256
257 } catch (NumberFormatException | ClassCastException e) {
258 newTunnelStatsPollFrequency = tunnelStatsPollFrequency;
259 }
260
261 if (newTunnelStatsPollFrequency != tunnelStatsPollFrequency) {
262 tunnelStatsPollFrequency = newTunnelStatsPollFrequency;
263 collectors.values().forEach(tsc -> tsc.adjustPollInterval(tunnelStatsPollFrequency));
264 log.info("New setting: tunnelStatsPollFrequency={}", tunnelStatsPollFrequency);
265 }
266
267 }
268
cheng fan48e832c2015-05-29 01:54:47 +0800269 @Override
270 public void setupTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530271 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530272 log.error("Tunnel Type MPLS is only supported");
273 return;
274 }
cheng fan48e832c2015-05-29 01:54:47 +0800275
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530276 // check for tunnel end points
277 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
278 log.error("Tunnel source or destination is not valid");
279 return;
280 }
281
282 // Get the pcc client
283 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
284
285 if (!(pc instanceof PcepClient)) {
286 log.error("There is no PCC connected with ip addresss {}"
chengfan2fff70f2015-08-24 18:20:19 -0500287 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530288 return;
289 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530290
291 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
Priyanka B413fbe82016-05-26 11:44:45 +0530292 //Only master will initiate setup tunnel
293 if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530294 pcepSetupTunnel(tunnel, path, pc);
295 }
cheng fan48e832c2015-05-29 01:54:47 +0800296 }
297
298 @Override
299 public void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800300
Avantika-Huawei56c11842016-04-28 00:56:56 +0530301 if (tunnel.annotations().value(PLSP_ID) != null) {
302 updateTunnel(tunnel, path);
303 return;
304 }
305
306 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530307 log.error("Tunnel Type MPLS is only supported");
308 return;
309 }
310
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530311 // check for tunnel end points
312 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
313 log.error("Tunnel source or destination is not valid");
314 return;
315 }
316
Priyanka Bcdf9b102016-06-07 20:01:38 +0530317 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530318
319 if (!(pc instanceof PcepClient)) {
320 log.error("There is no PCC connected with ip addresss {}"
321 + ((IpElementId) srcElement).ipAddress().toString());
322 return;
323 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530324
Priyanka B413fbe82016-05-26 11:44:45 +0530325 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
326 //Only master will initiate setup tunnel
327 if (pc.capability().pcInstantiationCapability()
328 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530329 pcepSetupTunnel(tunnel, path, pc);
330 }
cheng fan48e832c2015-05-29 01:54:47 +0800331 }
332
333 @Override
334 public void releaseTunnel(Tunnel tunnel) {
cheng fan48e832c2015-05-29 01:54:47 +0800335
Avantika-Huawei56c11842016-04-28 00:56:56 +0530336 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530337 log.error("Tunnel Type MPLS is only supported");
338 return;
339 }
340
341 // check for tunnel end points
342 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
343 log.error("Tunnel source or destination is not valid");
344 return;
345 }
346
347 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
348
349 if (!(pc instanceof PcepClient)) {
350 log.error("There is no PCC connected with ip addresss {}"
351 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
352 return;
353 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530354
Priyanka B413fbe82016-05-26 11:44:45 +0530355 //Only master will release tunnel
356 if (pc.capability().pcInstantiationCapability()
357 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530358 pcepReleaseTunnel(tunnel, pc);
359 }
cheng fan48e832c2015-05-29 01:54:47 +0800360 }
361
362 @Override
363 public void releaseTunnel(ElementId srcElement, Tunnel tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530364 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530365 log.error("Tunnel Type MPLS is only supported");
366 return;
367 }
cheng fan48e832c2015-05-29 01:54:47 +0800368
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530369 if (!(srcElement instanceof IpElementId)) {
370 log.error("Element id is not valid");
371 return;
372 }
373
374 // check for tunnel end points
375 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
376 log.error("Tunnel source or destination is not valid");
377 return;
378 }
379
380 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
381
382 if (!(pc instanceof PcepClient)) {
383 log.error("There is no PCC connected with ip addresss {}"
384 + ((IpElementId) srcElement).ipAddress().toString());
385 return;
386 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530387
Priyanka B413fbe82016-05-26 11:44:45 +0530388 //Only master will release tunnel
389 if (pc.capability().pcInstantiationCapability()
390 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530391 pcepReleaseTunnel(tunnel, pc);
392 }
cheng fan48e832c2015-05-29 01:54:47 +0800393 }
394
395 @Override
396 public void updateTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530397 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530398 log.error("Tunnel Type MPLS is only supported");
399 return;
400 }
cheng fan48e832c2015-05-29 01:54:47 +0800401
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530402 // check for tunnel end points
403 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
404 log.error("Tunnel source or destination is not valid");
405 return;
406 }
407
408 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
409
410 if (!(pc instanceof PcepClient)) {
411 log.error("There is no PCC connected with ip addresss {}"
412 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
413 return;
414 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530415
Priyanka B413fbe82016-05-26 11:44:45 +0530416 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
417 // LSP].If annotation is null D flag is not set else it is set.
418 if (pc.capability().statefulPceCapability()
419 && pc.delegationInfo(
420 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
421 .annotations().value(LOCAL_LSP_ID)))) != null) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530422 pcepUpdateTunnel(tunnel, path, pc);
423 }
cheng fan48e832c2015-05-29 01:54:47 +0800424 }
425
426 @Override
427 public void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800428
Avantika-Huawei56c11842016-04-28 00:56:56 +0530429 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530430 log.error("Tunnel Type MPLS is only supported");
431 return;
432 }
433
434 if (!(srcElement instanceof IpElementId)) {
435 log.error("Element id is not valid");
436 return;
437 }
438
439 // check for tunnel end points
440 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
441 log.error("Tunnel source or destination is not valid");
442 return;
443 }
444
445 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
446
447 if (!(pc instanceof PcepClient)) {
448 log.error("There is no PCC connected with ip addresss {}"
449 + ((IpElementId) srcElement).ipAddress().toString());
450 return;
451 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530452
Priyanka B413fbe82016-05-26 11:44:45 +0530453 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
454 // LSP].If annotation is null D flag is not set else it is set.
455 if (pc.capability().statefulPceCapability()
456 && pc.delegationInfo(
457 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
458 .annotations().value(LOCAL_LSP_ID)))) != null) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530459 pcepUpdateTunnel(tunnel, path, pc);
460 }
cheng fan48e832c2015-05-29 01:54:47 +0800461 }
462
463 @Override
464 public TunnelId tunnelAdded(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530465 return handleTunnelAdded(tunnel, null);
466 }
467
468 public TunnelId tunnelAdded(TunnelDescription tunnel, State tunnelState) {
469 return handleTunnelAdded(tunnel, tunnelState);
470 }
471
472 private TunnelId handleTunnelAdded(TunnelDescription tunnel, State tunnelState) {
473
474 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700475 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530476
477 if (tunnelState == null) {
478 return service.tunnelAdded(tunnel);
479 } else {
480 return service.tunnelAdded(tunnel, tunnelState);
481 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530482 }
cheng fan48e832c2015-05-29 01:54:47 +0800483
Avantika-Huawei56c11842016-04-28 00:56:56 +0530484 long bandwidth = Long.parseLong(tunnel.annotations().value(BANDWIDTH));
cheng fan48e832c2015-05-29 01:54:47 +0800485
486 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800487 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800488 return null;
489 }
490
491 // endpoints
492 OpticalTunnelEndPoint src = (org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint) tunnel
493 .src();
494 OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst();
495 // devices
496 DeviceId srcId = (DeviceId) src.elementId().get();
497 DeviceId dstId = (DeviceId) dst.elementId().get();
498
499 // ports
500 long srcPort = src.portNumber().get().toLong();
501 long dstPort = dst.portNumber().get().toLong();
502
503 // type
504 if (tunnel.type() != Tunnel.Type.VLAN) {
cheng fan7716ec92015-05-31 01:53:19 +0800505 error("Illegal tunnel type. Only support VLAN tunnel creation.");
cheng fan48e832c2015-05-29 01:54:47 +0800506 return null;
507 }
508
509 PcepTunnel pcepTunnel = controller.applyTunnel(srcId, dstId, srcPort,
510 dstPort, bandwidth,
511 tunnel.tunnelName()
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530512 .value());
cheng fan48e832c2015-05-29 01:54:47 +0800513
514 checkNotNull(pcepTunnel, TUNNLE_NOT_NULL);
515 TunnelDescription tunnelAdded = buildOpticalTunnel(pcepTunnel, null);
516 TunnelId tunnelId = service.tunnelAdded(tunnelAdded);
517
518 tunnelMap.put(String.valueOf(pcepTunnel.id()), tunnelId);
519 return tunnelId;
520 }
521
Priyanka B413fbe82016-05-26 11:44:45 +0530522 private void tunnelUpdated(Tunnel tunnel, Path path) {
523 handleTunnelUpdate(tunnel, path);
524 }
525
526 //Handles tunnel updated using tunnel admin service[specially to update annotations].
527 private void handleTunnelUpdate(Tunnel tunnel, Path path) {
528
529 if (tunnel.type() == MPLS) {
530 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
531
532 tunnelAdminService.updateTunnel(tunnel, path);
533
534 return;
535 }
536
537 Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
538 if (tunnelOld.type() != Tunnel.Type.VLAN) {
539 error("Illegal tunnel type. Only support VLAN tunnel update.");
540 return;
541 }
542
543 long bandwidth = Long
544 .parseLong(tunnel.annotations().value("bandwidth"));
545 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
546 error("Update failed, invalid bandwidth.");
547 return;
548 }
549 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
550
551 checkNotNull(pcepTunnelId, "Invalid tunnel id");
552 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
553 error("Update failed,maybe invalid bandwidth.");
554 return;
555 }
556 tunnelAdminService.updateTunnel(tunnel, path);
557 }
558
cheng fan48e832c2015-05-29 01:54:47 +0800559 @Override
560 public void tunnelRemoved(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530561 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700562 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530563 service.tunnelRemoved(tunnel);
564 }
565
cheng fan48e832c2015-05-29 01:54:47 +0800566 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
567 checkNotNull(tunnelOld, "The tunnel id is not exsited.");
568 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800569 error("Illegal tunnel type. Only support VLAN tunnel deletion.");
cheng fan48e832c2015-05-29 01:54:47 +0800570 return;
571 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700572 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800573 checkNotNull(pcepTunnelId, "The tunnel id is not exsited.");
cheng fan7716ec92015-05-31 01:53:19 +0800574 if (!controller.deleteTunnel(pcepTunnelId)) {
575 error("Delete tunnel failed, Maybe some devices have been disconnected.");
576 return;
cheng fan48e832c2015-05-29 01:54:47 +0800577 }
578 tunnelMap.remove(pcepTunnelId);
579 service.tunnelRemoved(tunnel);
cheng fan48e832c2015-05-29 01:54:47 +0800580 }
581
582 @Override
583 public void tunnelUpdated(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530584 handleTunnelUpdate(tunnel, null);
585 }
586
587 public void tunnelUpdated(TunnelDescription tunnel, State tunnelState) {
588 handleTunnelUpdate(tunnel, tunnelState);
589 }
590
591 private void handleTunnelUpdate(TunnelDescription tunnel, State tunnelState) {
592 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700593 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530594
595 if (tunnelState == null) {
596 service.tunnelUpdated(tunnel);
597 } else {
598 service.tunnelUpdated(tunnel, tunnelState);
599 }
600 return;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530601 }
cheng fan48e832c2015-05-29 01:54:47 +0800602
603 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
604 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800605 error("Illegal tunnel type. Only support VLAN tunnel update.");
cheng fan48e832c2015-05-29 01:54:47 +0800606 return;
607 }
cheng fan7716ec92015-05-31 01:53:19 +0800608 long bandwidth = Long
609 .parseLong(tunnel.annotations().value("bandwidth"));
cheng fan48e832c2015-05-29 01:54:47 +0800610 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800611 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800612 return;
613 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700614 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800615
616 checkNotNull(pcepTunnelId, "Invalid tunnel id");
617 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
618
cheng fan7716ec92015-05-31 01:53:19 +0800619 error("Update failed,maybe invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800620 return;
621
622 }
623 service.tunnelUpdated(tunnel);
624 }
625
cheng fan7716ec92015-05-31 01:53:19 +0800626 private void error(String info) {
627 System.err.println(info);
628 }
629
cheng fan48e832c2015-05-29 01:54:47 +0800630 // Short-hand for creating a connection point.
631 private ConnectPoint connectPoint(PcepDpid id, long port) {
632 return new ConnectPoint(deviceId(uri(id)), portNumber(port));
633 }
634
635 // Short-hand for creating a link.
636 private Link link(PcepDpid src, long sp, PcepDpid dst, long dp) {
Ray Milkey2693bda2016-01-22 16:08:14 -0800637 return DefaultLink.builder()
638 .providerId(id())
639 .src(connectPoint(src, sp))
640 .dst(connectPoint(dst, dp))
641 .type(Link.Type.TUNNEL)
642 .build();
cheng fan48e832c2015-05-29 01:54:47 +0800643 }
644
645 // Creates a path that leads through the given devices.
646 private Path createPath(List<PcepHopNodeDescription> hopList,
Jonathan Hart51539b82015-10-29 09:53:04 -0700647 PathType pathtype, PathState pathState) {
cheng fan48e832c2015-05-29 01:54:47 +0800648 if (hopList == null || hopList.size() == 0) {
649 return null;
650 }
651 List<Link> links = new ArrayList<>();
652 for (int i = 1; i < hopList.size() - 1; i = i + 2) {
653 links.add(link(hopList.get(i).getDeviceId(), hopList.get(i)
654 .getPortNum(), hopList.get(i + 1).getDeviceId(), hopList
655 .get(i + 1).getPortNum()));
656 }
657
658 int hopNum = hopList.size() - 2;
659 DefaultAnnotations extendAnnotations = DefaultAnnotations.builder()
660 .set("pathNum", String.valueOf(hopNum))
cheng fan93258c72015-06-02 23:42:32 +0800661 .set("pathState", String.valueOf(pathState))
cheng fan48e832c2015-05-29 01:54:47 +0800662 .set("pathType", String.valueOf(pathtype)).build();
663 return new DefaultPath(id(), links, hopNum, extendAnnotations);
664 }
665
666 // convert the path description to a string.
667 public String pathToString(List<Link> links) {
668 StringBuilder builder = new StringBuilder();
669 builder.append("{");
670 for (Link link : links) {
671 builder.append("(Device:" + link.src().deviceId() + " Port:"
672 + link.src().port().toLong());
673 builder.append(" Device:" + link.dst().deviceId() + " Port:"
674 + link.dst().port().toLong());
675 builder.append(")");
676 }
677 builder.append("}");
678 return builder.toString();
679 }
680
681 // build a TunnelDescription.
682 private TunnelDescription buildOpticalTunnel(PcepTunnel pcepTunnel,
683 TunnelId tunnelId) {
684 TunnelEndPoint srcPoint = null;
685 TunnelEndPoint dstPoint = null;
686 Tunnel.Type tunnelType = null;
687 TunnelName name = TunnelName.tunnelName(pcepTunnel.name());
688
689 // add path after codes of tunnel's path merged
690 Path path = createPath(pcepTunnel.getHopList(),
cheng fan93258c72015-06-02 23:42:32 +0800691 pcepTunnel.getPathType(),
692 pcepTunnel.getPathState());
cheng fan48e832c2015-05-29 01:54:47 +0800693
694 OpticalTunnelEndPoint.Type endPointType = null;
695 switch (pcepTunnel.type()) {
696 case OCH:
697 tunnelType = Tunnel.Type.OCH;
698 endPointType = OpticalTunnelEndPoint.Type.LAMBDA;
699 break;
700
701 case OTN:
702 tunnelType = Tunnel.Type.ODUK;
703 endPointType = OpticalTunnelEndPoint.Type.TIMESLOT;
704 break;
705
706 case UNI:
707 tunnelType = Tunnel.Type.VLAN;
708 endPointType = null;
709 break;
710
711 default:
712 break;
713 }
714 DeviceId srcDid = deviceId(uri(pcepTunnel.srcDeviceID()));
715 DeviceId dstDid = deviceId(uri(pcepTunnel.dstDeviceId()));
716 PortNumber srcPort = PortNumber.portNumber(pcepTunnel.srcPort());
717 PortNumber dstPort = PortNumber.portNumber(pcepTunnel.dstPort());
718
719 srcPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(srcDid),
720 Optional.of(srcPort), null,
721 endPointType,
722 OpticalLogicId.logicId(0),
723 true);
724 dstPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(dstDid),
725 Optional.of(dstPort), null,
726 endPointType,
727 OpticalLogicId.logicId(0),
728 true);
729
730 // basic annotations
cheng fan7716ec92015-05-31 01:53:19 +0800731 DefaultAnnotations annotations = DefaultAnnotations
732 .builder()
cheng fan48e832c2015-05-29 01:54:47 +0800733 .set("SLA", String.valueOf(pcepTunnel.getSla()))
cheng fan7716ec92015-05-31 01:53:19 +0800734 .set("bandwidth",
735 String.valueOf(pcepTunnel.bandWidth()) + BANDWIDTH_UINT)
cheng fan48e832c2015-05-29 01:54:47 +0800736 .set("index", String.valueOf(pcepTunnel.id())).build();
737
cheng fan48e832c2015-05-29 01:54:47 +0800738 // a VLAN tunnel always carry OCH tunnel, this annotation is the index
739 // of a OCH tunnel.
cheng fan93258c72015-06-02 23:42:32 +0800740 if (pcepTunnel.underlayTunnelId() != 0) {
cheng fan48e832c2015-05-29 01:54:47 +0800741 DefaultAnnotations extendAnnotations = DefaultAnnotations
742 .builder()
743 .set("underLayTunnelIndex",
cheng fan93258c72015-06-02 23:42:32 +0800744 String.valueOf(pcepTunnel.underlayTunnelId())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800745 annotations = DefaultAnnotations.merge(annotations,
746 extendAnnotations);
747
748 }
749 TunnelDescription tunnel = new DefaultTunnelDescription(
750 tunnelId,
751 srcPoint,
752 dstPoint,
753 tunnelType,
754 new DefaultGroupId(
755 0),
756 id(), name,
757 path,
758 annotations);
759 return tunnel;
cheng fan48e832c2015-05-29 01:54:47 +0800760 }
761
762 /**
763 * Get the tunnelID according to the tunnel key.
764 *
765 * @param tunnelKey tunnel key
766 * @return corresponding tunnel id of the a tunnel key.
767 */
768 private TunnelId getTunnelId(String tunnelKey) {
cheng fan48e832c2015-05-29 01:54:47 +0800769 for (String key : tunnelMap.keySet()) {
770 if (key.equals(tunnelKey)) {
771 return tunnelMap.get(key);
772 }
773 }
774 return null;
775 }
776
777 /**
778 * Get the tunnel key according to the tunnelID.
779 *
780 * @param tunnelId tunnel id
781 * @return corresponding a tunnel key of the tunnel id.
782 */
Jonathan Hart51539b82015-10-29 09:53:04 -0700783 private String getPcepTunnelKey(TunnelId tunnelId) {
cheng fan48e832c2015-05-29 01:54:47 +0800784 for (String key : tunnelMap.keySet()) {
785 if (tunnelMap.get(key).id() == tunnelId.id()) {
786 return key;
787 }
788 }
789 return null;
790
791 }
792
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530793 /**
chengfan2fff70f2015-08-24 18:20:19 -0500794 * Build a DefaultTunnelStatistics from a PcepTunnelStatistics.
795 *
796 * @param statistics statistics data from a PCEP tunnel
797 * @return TunnelStatistics
798 */
799 private TunnelStatistics buildTunnelStatistics(PcepTunnelStatistics statistics) {
800 DefaultTunnelStatistics.Builder builder = new DefaultTunnelStatistics.Builder();
801 DefaultTunnelStatistics tunnelStatistics = builder.setBwUtilization(statistics.bandwidthUtilization())
802 .setPacketLossRatio(statistics.packetLossRate())
803 .setFlowDelay(statistics.flowDelay())
804 .setAlarms(statistics.alarms())
805 .build();
806 return tunnelStatistics;
807 }
808 /**
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530809 * Creates list of hops for ERO object from Path.
810 *
811 * @param path network path
812 * @return list of ipv4 subobjects
813 */
814 private LinkedList<PcepValueType> createPcepPath(Path path) {
815 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
816 List<Link> listLink = path.links();
817 ConnectPoint source = null;
818 ConnectPoint destination = null;
819 IpAddress ipDstAddress = null;
820 IpAddress ipSrcAddress = null;
821 PcepValueType subObj = null;
Priyanka Bcdf9b102016-06-07 20:01:38 +0530822 long portNo;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530823
824 for (Link link : listLink) {
825 source = link.src();
826 if (!(source.equals(destination))) {
827 //set IPv4SubObject for ERO object
Priyanka Bcdf9b102016-06-07 20:01:38 +0530828 portNo = source.port().toLong();
829 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
830 ipSrcAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530831 subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
832 llSubObjects.add(subObj);
833 }
834
835 destination = link.dst();
Priyanka Bcdf9b102016-06-07 20:01:38 +0530836 portNo = destination.port().toLong();
837 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
838 ipDstAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530839 subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
840 llSubObjects.add(subObj);
841 }
Priyanka Bcdf9b102016-06-07 20:01:38 +0530842
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530843 return llSubObjects;
844 }
845
846 /**
847 * Creates PcInitiated lsp request list for setup tunnel.
848 *
849 * @param tunnel mpls tunnel
850 * @param path network path
851 * @param pc pcep client
852 * @param srpId unique id for pcep message
853 * @return list of PcInitiatedLspRequest
854 * @throws PcepParseException while building pcep objects fails
855 */
856 LinkedList<PcInitiatedLspRequest> createPcInitiatedLspReqList(Tunnel tunnel, Path path,
857 PcepClient pc, int srpId)
858 throws PcepParseException {
859 PcepValueType tlv;
860 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
861
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700862 if (llSubObjects == null || llSubObjects.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530863 log.error("There is no link information to create tunnel");
864 return null;
865 }
866
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530867 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530868
869 // set PathSetupTypeTlv of SRP object
870 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)).type());
871 llOptionalTlv.add(tlv);
872
873 // build SRP object
874 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
875 .setOptionalTlv(llOptionalTlv).build();
876
877 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530878 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530879
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530880 // set LSP identifiers TLV
Avantika-Huawei56c11842016-04-28 00:56:56 +0530881 short localLspId = 0;
882 if (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) != WITH_SIGNALLING) {
883 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
884 if (localLspIdString != null) {
885 localLspId = Short.valueOf(localLspIdString);
886 }
887 }
888
889 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
890 localLspId, (short) 0, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
891 .getIp4Address().toInt()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530892 llOptionalTlv.add(tlv);
893 //set SymbolicPathNameTlv of LSP object
894 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
895 llOptionalTlv.add(tlv);
896
897 //build LSP object
898 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setOFlag((byte) 0).setPlspId(0)
899 .setOptionalTlv(llOptionalTlv).build();
900
901 //build ENDPOINTS object
902 PcepEndPointsObject endpointsobj = pc.factory().buildEndPointsObject()
903 .setSourceIpAddress(((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt())
904 .setDestIpAddress(((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt())
905 .setPFlag(true).build();
906
907 //build ERO object
908 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
909
Priyanka Bcdf9b102016-06-07 20:01:38 +0530910 float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530911 if (tunnel.annotations().value(BANDWIDTH) != null) {
Priyanka Bcdf9b102016-06-07 20:01:38 +0530912 iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530913 }
914 // build bandwidth object
915 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
916 // build pcep attribute
917 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
918
919 PcInitiatedLspRequest initiateLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
920 .setLspObject(lspobj).setEndPointsObject(endpointsobj).setEroObject(eroobj)
921 .setPcepAttribute(pcepAttribute).build();
922 llPcInitiatedLspRequestList.add(initiateLspRequest);
923 return llPcInitiatedLspRequestList;
924 }
925
926 /**
927 * To send initiate tunnel message to pcc.
928 *
929 * @param tunnel mpls tunnel info
930 * @param path explicit route for the tunnel
931 * @param pc pcep client to send message
932 */
933 private void pcepSetupTunnel(Tunnel tunnel, Path path, PcepClient pc) {
934 try {
935 int srpId = SrpIdGenerators.create();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530936 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, CREATE);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530937
Jonathan Hart51539b82015-10-29 09:53:04 -0700938 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530939
940 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = createPcInitiatedLspReqList(tunnel, path,
941 pc, srpId);
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700942 if (llPcInitiatedLspRequestList == null || llPcInitiatedLspRequestList.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530943 log.error("Failed to create PcInitiatedLspRequestList");
944 return;
945 }
946
947 //build PCInitiate message
948 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
949 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList)
950 .build();
951
952 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
953
Jonathan Hart51539b82015-10-29 09:53:04 -0700954 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530955 } catch (PcepParseException e) {
956 log.error("PcepParseException occurred while processing setup tunnel {}", e.getMessage());
957 }
958 }
959
960 /**
961 * To send Release tunnel message to pcc.
962 *
963 * @param tunnel mpls tunnel info
964 * @param pc pcep client to send message
965 */
966 private void pcepReleaseTunnel(Tunnel tunnel, PcepClient pc) {
967 try {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530968 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, DELETE);
Jonathan Hart51539b82015-10-29 09:53:04 -0700969 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530970 int srpId = SrpIdGenerators.create();
971 TunnelId tunnelId = tunnel.tunnelId();
972 int plspId = 0;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530973
Jonathan Hart51539b82015-10-29 09:53:04 -0700974 if (!(pcepTunnelApiMapper.checkFromTunnelDBQueue(tunnelId))) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530975 log.error("Tunnel doesnot exists. Tunnel id {}" + tunnelId.toString());
976 return;
977 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -0700978 PcepTunnelData pcepTunnelDbData = pcepTunnelApiMapper.getDataFromTunnelDBQueue(tunnelId);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530979 plspId = pcepTunnelDbData.plspId();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530980 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530981
982 PcepValueType tlv;
983 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530984
985 // set PathSetupTypeTlv of SRP object
986 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))
987 .type());
988 llOptionalTlv.add(tlv);
989
990 // build SRP object
991 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(true)
992 .setOptionalTlv(llOptionalTlv).build();
993
994 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530995 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
996
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530997 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
998 llOptionalTlv.add(tlv);
999 // build lsp object, set r flag as false to delete the tunnel
1000 PcepLspObject lspobj = pc.factory().buildLspObject().setRFlag(false).setPlspId(plspId)
1001 .setOptionalTlv(llOptionalTlv).build();
1002
1003 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
1004 .setLspObject(lspobj).build();
1005
1006 llPcInitiatedLspRequestList.add(releaseLspRequest);
1007
1008 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1009 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1010
1011 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1012
Jonathan Hart51539b82015-10-29 09:53:04 -07001013 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301014 } catch (PcepParseException e) {
1015 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1016 }
1017 }
1018
1019 /**
1020 * To send Update tunnel request message to pcc.
1021 *
1022 * @param tunnel mpls tunnel info
1023 * @param path explicit route for the tunnel
1024 * @param pc pcep client to send message
1025 */
1026 private void pcepUpdateTunnel(Tunnel tunnel, Path path, PcepClient pc) {
1027 try {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301028 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, UPDATE);
Jonathan Hart51539b82015-10-29 09:53:04 -07001029 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301030 int srpId = SrpIdGenerators.create();
1031 TunnelId tunnelId = tunnel.tunnelId();
1032 PcepValueType tlv;
1033 int plspId = 0;
1034
1035 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
1036 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
1037 LinkedList<PcepUpdateRequest> llUpdateRequestList = new LinkedList<PcepUpdateRequest>();
1038
Avantika-Huawei56c11842016-04-28 00:56:56 +05301039 // set PathSetupTypeTlv of SRP object
1040 LspType lspSigType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
1041 tlv = new PathSetupTypeTlv(lspSigType.type());
1042 llOptionalTlv.add(tlv);
1043
1044 // build SRP object
1045 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
1046 .setOptionalTlv(llOptionalTlv).build();
1047
1048 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301049
Jonathan Hart51539b82015-10-29 09:53:04 -07001050 if (!(pcepTunnelApiMapper.checkFromTunnelDBQueue(tunnelId))) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301051 log.error("Tunnel doesnot exists in DB");
1052 return;
1053 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -07001054 PcepTunnelData pcepTunnelDBData = pcepTunnelApiMapper.getDataFromTunnelDBQueue(tunnelId);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301055 plspId = pcepTunnelDBData.plspId();
1056 }
1057
Avantika-Huawei56c11842016-04-28 00:56:56 +05301058 if (lspSigType != WITH_SIGNALLING) {
1059 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
1060 String pccTunnelIdString = tunnel.annotations().value(PCC_TUNNEL_ID);
1061 short localLspId = 0;
1062 short pccTunnelId = 0;
1063
1064 if (localLspIdString != null) {
1065 localLspId = Short.valueOf(localLspIdString);
1066 }
1067
1068 if (pccTunnelIdString != null) {
1069 pccTunnelId = Short.valueOf(pccTunnelIdString);
1070 }
1071
1072 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src())
1073 .ip().getIp4Address().toInt()),
1074 localLspId, pccTunnelId, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
1075 .getIp4Address().toInt()));
1076 llOptionalTlv.add(tlv);
1077 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301078
1079 if (tunnel.tunnelName().value() != null) {
1080 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1081 llOptionalTlv.add(tlv);
1082 }
1083
1084 // build lsp object
1085 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setPlspId(plspId)
1086 .setOptionalTlv(llOptionalTlv).build();
1087 // build ero object
1088 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
1089
1090 int iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +05301091 if (tunnel.annotations().value(BANDWIDTH) != null) {
1092 iBandwidth = Integer.parseInt(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301093 }
1094 // build bandwidth object
1095 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
1096 // build pcep attribute
1097 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
1098 // build pcep msg path
1099 PcepMsgPath msgPath = pc.factory().buildPcepMsgPath().setEroObject(eroobj).setPcepAttribute(pcepAttribute)
1100 .build();
1101
1102 PcepUpdateRequest updateRequest = pc.factory().buildPcepUpdateRequest().setSrpObject(srpobj)
1103 .setLspObject(lspobj).setMsgPath(msgPath).build();
1104
1105 llUpdateRequestList.add(updateRequest);
1106
1107 PcepUpdateMsg pcUpdateMsg = pc.factory().buildUpdateMsg().setUpdateRequestList(llUpdateRequestList).build();
1108
1109 pc.sendMessage(Collections.singletonList(pcUpdateMsg));
Jonathan Hart51539b82015-10-29 09:53:04 -07001110 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301111 } catch (PcepParseException e) {
1112 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1113 }
1114 }
1115
chengfan2fff70f2015-08-24 18:20:19 -05001116
1117
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301118 private class InnerTunnelProvider implements PcepTunnelListener, PcepEventListener, PcepClientListener {
cheng fan48e832c2015-05-29 01:54:47 +08001119
1120 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -07001121 public void handlePcepTunnel(PcepTunnel pcepTunnel) {
cheng fan48e832c2015-05-29 01:54:47 +08001122 TunnelDescription tunnel = null;
1123 // instance and id identify a tunnel together
1124 String tunnelKey = String.valueOf(pcepTunnel.getInstance())
1125 + String.valueOf(pcepTunnel.id());
1126
1127 if (tunnelKey == null || "".equals(tunnelKey)) {
1128 log.error("Invalid PCEP tunnel");
1129 return;
1130 }
1131
1132 TunnelId tunnelId = getTunnelId(tunnelKey);
1133
1134 tunnel = buildOpticalTunnel(pcepTunnel, tunnelId);
1135
1136 OperationType operType = pcepTunnel.getOperationType();
1137 switch (operType) {
1138 case ADD:
1139 tunnelId = service.tunnelAdded(tunnel);
1140 tunnelMap.put(tunnelKey, tunnelId);
1141 break;
1142
1143 case UPDATE:
1144 service.tunnelUpdated(tunnel);
1145 break;
1146
1147 case DELETE:
1148 service.tunnelRemoved(tunnel);
1149 tunnelMap.remove(tunnelKey);
1150 break;
1151
1152 default:
1153 log.error("Invalid tunnel operation");
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301154 }
1155 }
cheng fan48e832c2015-05-29 01:54:47 +08001156
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301157 @Override
1158 public void handleMessage(PccId pccId, PcepMessage msg) {
1159 try {
1160 log.debug("tunnel provider handle message {}", msg.getType().toString());
1161 switch (msg.getType()) {
1162 case REPORT:
1163 int srpId = 0;
1164 LinkedList<PcepStateReport> llStateReportList = null;
1165 llStateReportList = ((PcepReportMsg) msg).getStateReportList();
1166 ListIterator<PcepStateReport> listIterator = llStateReportList.listIterator();
1167 PcepSrpObject srpObj = null;
1168 PcepLspObject lspObj = null;
1169 while (listIterator.hasNext()) {
1170 PcepStateReport stateRpt = listIterator.next();
1171 srpObj = stateRpt.getSrpObject();
1172 lspObj = stateRpt.getLspObject();
1173
1174 if (srpObj instanceof PcepSrpObject) {
1175 srpId = srpObj.getSrpID();
1176 }
1177
1178 log.debug("Plsp ID in handle message " + lspObj.getPlspId());
1179 log.debug("SRP ID in handle message " + srpId);
1180
Jonathan Hart51539b82015-10-29 09:53:04 -07001181 if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301182 // For PCRpt without matching SRP id.
1183 handleRptWithoutSrpId(stateRpt, pccId);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301184 continue;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301185 }
1186
Avantika-Huawei56c11842016-04-28 00:56:56 +05301187 handleReportMessage(srpId, lspObj, stateRpt);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301188 }
1189 break;
1190
1191 default:
1192 log.debug("Received unsupported message type {}", msg.getType().toString());
1193 }
1194 } catch (Exception e) {
1195 log.error("Exception occured while processing report message {}", e.getMessage());
1196 }
1197 }
1198
1199 /**
1200 * Handles report message for setup/update/delete tunnel request.
1201 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301202 * @param srpId unique identifier for PCEP message
1203 * @param lspObj LSP object
1204 * @param stateRpt parsed PCEP report msg.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301205 */
Avantika-Huawei56c11842016-04-28 00:56:56 +05301206 private void handleReportMessage(int srpId, PcepLspObject lspObj, PcepStateReport stateRpt) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301207 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Jonathan Hart51539b82015-10-29 09:53:04 -07001208 PcepTunnelData pcepTunnelData = pcepTunnelApiMapper.getDataFromTunnelRequestQueue(srpId);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301209
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301210 // store the values required from report message
1211 pcepTunnelData.setPlspId(lspObj.getPlspId());
1212 pcepTunnelData.setLspAFlag(lspObj.getAFlag());
1213 pcepTunnelData.setLspOFlag(lspObj.getOFlag());
1214 pcepTunnelData.setLspDFlag(lspObj.getDFlag());
1215
Avantika-Huawei56c11842016-04-28 00:56:56 +05301216 StatefulIPv4LspIdentifiersTlv ipv4LspTlv = null;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301217 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1218 while (listTlvIterator.hasNext()) {
1219 PcepValueType tlv = listTlvIterator.next();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301220 if (tlv.getType() == StatefulIPv4LspIdentifiersTlv.TYPE) {
1221 ipv4LspTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301222 break;
1223 }
1224 }
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001225 if (ipv4LspTlv != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301226 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspTlv);
cheng fan48e832c2015-05-29 01:54:47 +08001227 }
1228
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301229 Path path = pcepTunnelData.path();
1230 Tunnel tunnel = pcepTunnelData.tunnel();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301231 Builder annotationBuilder = DefaultAnnotations.builder();
1232 annotationBuilder.putAll(pcepTunnelData.tunnel().annotations());
1233
1234 // PCRpt in response to PCInitate msg will carry PLSP id allocated by PCC.
1235 if (tunnel.annotations().value(PLSP_ID) == null) {
1236 annotationBuilder.set(PLSP_ID, String.valueOf(lspObj.getPlspId()));
1237 }
1238
1239 // Signalled LSPs will carry local LSP id allocated by signalling protocol(PCC).
1240 if (tunnel.annotations().value(LOCAL_LSP_ID) == null) {
1241 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(ipv4LspTlv.getLspId()));
1242 }
1243
1244 SparseAnnotations annotations = annotationBuilder.build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301245 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(),
1246 tunnel.dst(), tunnel.type(), tunnel.groupId(),
1247 providerId, tunnel.tunnelName(), path,
1248 annotations);
1249
Avantika-Huawei56c11842016-04-28 00:56:56 +05301250 if (CREATE == pcepTunnelData.requestType()) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001251 pcepTunnelApiMapper.handleCreateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301252 } else if (DELETE == pcepTunnelData.requestType()) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001253 pcepTunnelApiMapper.handleRemoveFromTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301254 } else if (UPDATE == pcepTunnelData.requestType()) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301255 pcepTunnelData.setRptFlag(true);
Jonathan Hart51539b82015-10-29 09:53:04 -07001256 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1257 pcepTunnelApiMapper.handleUpdateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301258 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301259
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301260 PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
1261
Avantika-Huawei56c11842016-04-28 00:56:56 +05301262 if (lspObj.getRFlag()) {
1263 tunnelRemoved(td);
1264 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301265 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(pcepLspStatus);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301266 tunnelUpdated(td, tunnelState);
1267 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301268
1269 // SR-TE also needs PCUpd msg after receiving PCRpt with status GOING-UP even
1270 // though there are no labels to download for SR-TE.
1271 if ((pcepLspStatus == PcepLspStatus.GOING_UP)
1272 && (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) == SR_WITHOUT_SIGNALLING)) {
1273 updateTunnel(tunnel, tunnel.path());
1274 }
Avantika-Huawei56c11842016-04-28 00:56:56 +05301275 }
1276
Priyanka B413fbe82016-05-26 11:44:45 +05301277 private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301278 float bandwidth, LspType lspType, String costType) {
1279
1280 Builder builder = DefaultAnnotations.builder();
1281
1282 /*
1283 * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
1284 * for which no constraints need be applied to any of the metrics.
1285 */
1286 if (costType != null) {
1287 builder.set(COST_TYPE, costType);
1288 }
1289
1290 SparseAnnotations annotations = builder
Priyanka B413fbe82016-05-26 11:44:45 +05301291 .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
1292 .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
1293 .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
1294 .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
1295 .set(DELEGATE, String.valueOf(lspObj.getDFlag()))
1296 .build();
1297 return annotations;
1298 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301299
Priyanka B413fbe82016-05-26 11:44:45 +05301300 private LspType getLspType(PcepSrpObject srpObj) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301301 LspType lspType = WITH_SIGNALLING;
1302
1303 if (null != srpObj) {
1304 LinkedList<PcepValueType> llOptionalTlv = srpObj.getOptionalTlv();
1305 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
1306
1307 while (listIterator.hasNext()) {
1308 PcepValueType tlv = listIterator.next();
1309
1310 switch (tlv.getType()) {
1311 case PathSetupTypeTlv.TYPE:
1312 lspType = LspType.values()[Integer.valueOf(((PathSetupTypeTlv) tlv).getPst())];
1313 break;
1314
1315 default:
1316 break;
1317 }
1318 }
1319 }
Priyanka B413fbe82016-05-26 11:44:45 +05301320 return lspType;
1321 }
1322
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301323 private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
Priyanka B413fbe82016-05-26 11:44:45 +05301324 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301325 String costType = null;
Priyanka B413fbe82016-05-26 11:44:45 +05301326 PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
1327 checkNotNull(msgPath);
1328 PcepEroObject eroObj = msgPath.getEroObject();
1329 if (eroObj == null) {
1330 log.error("ERO object is null in report message.");
1331 return;
1332 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301333
1334 PcepAttribute attributes = msgPath.getPcepAttribute();
1335 int cost = 0;
1336 if (attributes != null && attributes.getMetricObjectList() != null) {
1337 ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
1338 PcepMetricObject metricObj = iterator.next();
1339
1340 while (metricObj != null) {
1341 if (metricObj.getBType() == IGP_METRIC) {
1342 costType = "COST";
1343 } else if (metricObj.getBType() == TE_METRIC) {
1344 costType = "TE_COST";
1345 }
1346
1347 if (costType != null) {
1348 cost = metricObj.getMetricVal();
1349 log.debug("Path cost {}", cost);
1350 break;
1351 }
1352 metricObj = iterator.next();
1353 }
1354 }
1355
1356 Path path = buildPathFromEroObj(eroObj, providerId, cost);
Priyanka B413fbe82016-05-26 11:44:45 +05301357
1358 float bandwidth = 0;
1359 if (msgPath.getBandwidthObject() != null) {
1360 bandwidth = msgPath.getBandwidthObject().getBandwidth();
1361 }
1362
1363 /*
1364 * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
1365 * from PCE.
1366 */
1367 PcepSrpObject srpObj = stateRpt.getSrpObject();
1368 LspType lspType = getLspType(srpObj);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301369
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301370 PcepLspObject lspObj = stateRpt.getLspObject();
1371 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1372 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
1373 SymbolicPathNameTlv pathNameTlv = null;
1374
1375 while (listTlvIterator.hasNext()) {
1376 PcepValueType tlv = listTlvIterator.next();
1377 switch (tlv.getType()) {
1378 case StatefulIPv4LspIdentifiersTlv.TYPE:
1379 ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
1380 break;
1381
1382 case SymbolicPathNameTlv.TYPE:
1383 pathNameTlv = (SymbolicPathNameTlv) tlv;
1384 break;
1385
1386 default:
1387 break;
1388 }
1389 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301390 /*
1391 * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
1392 * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
1393 */
1394 if (ipv4LspIdenTlv == null) {
1395 log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
1396 return;
1397 }
1398
1399 IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
1400 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
1401 IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
1402 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
1403 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
1404
Priyanka B413fbe82016-05-26 11:44:45 +05301405 // Store delegation flag info and that LSP info because only delegated PCE sends update message
1406 // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
1407 // not present then non-delegated , if present it is delegated.
1408 if (lspObj.getDFlag()) {
1409 pcepClientController.getClient(pccId).setLspAndDelegationInfo(
1410 new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
1411 }
1412
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301413 Tunnel tunnel = null;
1414 // Asynchronous status change message from PCC for LSP reported earlier.
1415 for (Tunnel tunnelObj : tunnelQueryResult) {
1416 if (tunnelObj.annotations().value(PLSP_ID) == null) {
1417 /*
1418 * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
1419 * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
1420 * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
1421 * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
1422 * session an LSP is "first" reported to a PCE.
1423 */
1424 if ((pathNameTlv != null)
1425 && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
1426 tunnel = tunnelObj;
1427 break;
1428 }
1429 continue;
1430 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301431 if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
1432 .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
1433 tunnel = tunnelObj;
1434 break;
1435 }
1436 }
1437
1438 DefaultTunnelDescription td;
Priyanka B413fbe82016-05-26 11:44:45 +05301439 SparseAnnotations annotations = null;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301440 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
1441 if (tunnel == null) {
1442 if (lspObj.getRFlag()) {
1443 /*
1444 * If PCC sends remove message and for any reason PCE does not have that entry, simply discard the
1445 * message. Or if PCRpt for initiated LSP received and PCE doesn't know, then too discard.
1446 */
1447 return;
1448 }
1449
Priyanka B413fbe82016-05-26 11:44:45 +05301450 DeviceId deviceId = getDevice(pccId);
1451 if (deviceId == null) {
1452 log.error("Ingress deviceId not found");
1453 return;
1454 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301455 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301456
Priyanka B413fbe82016-05-26 11:44:45 +05301457 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
1458 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
1459 annotations);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301460
1461 // Do not support PCC initiated LSP after LSP DB sync is completed.
1462 if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
1463 log.error("Received PCC initiated LSP while not in sync.");
1464 return;
1465 }
1466
Priyanka B413fbe82016-05-26 11:44:45 +05301467 /*
1468 * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
1469 * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
1470 * delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
1471 * wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
1472 * updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
1473 * send update message to that client.
1474 *
1475 * 1)Master can 1st get the Rpt message
1476 * a)Master adds the tunnel into core.
1477 * b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
1478 * after master, then runs timer then update the tunnel with D flag set.
1479 * 2)Non-Master can 1st get the Rpt message
1480 * a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
1481 * b)Master would have got the message while the non-master running timer, hence master adds
1482 * tunnel to core
1483 *
1484 * In general always master adds the tunnel to the core
1485 * while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
1486 */
1487 if (mastershipService.isLocalMaster(deviceId)) {
1488 TunnelId tId = tunnelAdded(td, tunnelState);
1489 Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
1490 tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
1491 .getValue())), path, annotations);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301492
Priyanka B413fbe82016-05-26 11:44:45 +05301493 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
1494 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
1495 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1496 } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
1497 //Start timer then update the tunnel with D flag
1498 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1499 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301500 return;
1501 }
1502
Priyanka B413fbe82016-05-26 11:44:45 +05301503 //delegated owner will update can be a master or non-master
1504 if (lspObj.getDFlag()) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301505 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Priyanka B413fbe82016-05-26 11:44:45 +05301506 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
1507 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
1508 annotations);
1509 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1510 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301511 removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
Priyanka B413fbe82016-05-26 11:44:45 +05301512 return;
1513 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301514
Priyanka B413fbe82016-05-26 11:44:45 +05301515 private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301516 State tunnelState) {
Priyanka B413fbe82016-05-26 11:44:45 +05301517 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
1518 tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
1519 (SparseAnnotations) tunnel.annotations());
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301520 if (lspObj.getRFlag()) {
1521 tunnelRemoved(td);
1522 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301523 tunnelUpdated(td, tunnelState);
1524 }
Priyanka B413fbe82016-05-26 11:44:45 +05301525 }
1526
1527 private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
1528 DefaultTunnelDescription td, ProviderId providerId) {
1529 //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
1530
1531 /*
1532 * If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
1533 * master has added the tunnel to the store] then update the tunnel.
1534 */
1535 ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
1536
1537 // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
1538 executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
1539 executor), DELAY, DELAY, TimeUnit.SECONDS);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301540 }
1541
1542 /**
Avantika-Huawei56c11842016-04-28 00:56:56 +05301543 * To build Path in network from ERO object.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301544 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301545 * @param eroObj ERO object
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301546 * @param providerId provider id
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301547 * @param cost cost of path
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301548 * @return path object
1549 */
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301550 private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId, int cost) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301551 checkNotNull(eroObj);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301552 List<Link> links = new ArrayList<Link>();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301553 LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301554 if (0 == llSubObj.size()) {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301555 log.error("ERO in report message does not have hop information");
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301556 }
1557 ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
1558
1559 ConnectPoint src = null;
1560 ConnectPoint dst = null;
1561 boolean isSrcSet = false;
1562 while (tlvIterator.hasNext()) {
1563 PcepValueType subObj = tlvIterator.next();
1564 switch (subObj.getType()) {
1565
1566 case IPv4SubObject.TYPE:
1567
1568 IPv4SubObject ipv4SubObj = (IPv4SubObject) subObj;
1569 if (!isSrcSet) {
1570 IpAddress srcIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1571 src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
1572 isSrcSet = true;
1573 } else {
1574 IpAddress dstIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1575 dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
Ray Milkey2693bda2016-01-22 16:08:14 -08001576 Link link = DefaultLink.builder()
1577 .providerId(providerId)
1578 .src(src)
1579 .dst(dst)
1580 .type(Link.Type.DIRECT)
1581 .build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301582 links.add(link);
1583 src = dst;
1584 }
1585 break;
1586 default:
1587 // the other sub objects are not required
1588 }
1589 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301590
1591 return new DefaultPath(providerId, links, cost, EMPTY);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301592 }
1593
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301594 @Override
1595 public void clientConnected(PccId pccId) {
1596 // TODO
1597 }
1598
1599 @Override
1600 public void clientDisconnected(PccId pccId) {
1601 // TODO
cheng fan48e832c2015-05-29 01:54:47 +08001602 }
chengfan2fff70f2015-08-24 18:20:19 -05001603
chengfan2fff70f2015-08-24 18:20:19 -05001604 @Override
1605 public void handlePcepTunnelStatistics(PcepTunnelStatistics pcepTunnelStatistics) {
1606 TunnelId id = getTunnelId(String.valueOf(pcepTunnelStatistics.id()));
1607 TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
1608 tunnelStatisticsMap.put(id, tunnelStatistics);
1609 }
cheng fan48e832c2015-05-29 01:54:47 +08001610
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301611 @Override
1612 public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301613
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301614 if (endOfSyncAction == SEND_UPDATE) {
1615 updateTunnel(tunnel, tunnel.path());
1616 return;
1617 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301618
1619 TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
1620 tunnel.src(), tunnel.dst(),
1621 tunnel.type(),
1622 tunnel.groupId(),
1623 tunnel.providerId(),
1624 tunnel.tunnelName(),
1625 tunnel.path(),
1626 (SparseAnnotations) tunnel.annotations());
1627
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301628
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301629 if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
1630
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301631 // Send PCInit msg again after global reoptimization.
1632 tunnelUpdated(td, UNSTABLE);
1633
1634 // To remove the old tunnel from store whose PLSPID is not
1635 // recognized by ingress PCC.
1636 tunnelRemoved(td);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301637
1638 } else if (endOfSyncAction == REMOVE) {
1639 tunnelRemoved(td);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301640 }
1641 }
1642
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301643 @Override
1644 public void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction) {
1645 try {
1646 if ((msg instanceof PcepInitiateMsg) && (endOfSyncAction == SEND_DELETE)) {
1647 PcepClient pc = pcepClientController.getClient(pccId);
1648 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = ((PcepInitiateMsg) msg)
1649 .getPcInitiatedLspRequestList();
1650 PcInitiatedLspRequest pcInitMsg = llPcInitiatedLspRequestList.iterator().next();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301651
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301652 if (pcInitMsg != null) {
1653 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
1654 .setRFlag(true).build();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301655
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301656 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
1657 .setLspObject(pcInitMsg.getLspObject()).setSrpObject(srpobj).build();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301658
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301659 llPcInitiatedLspRequestList.remove(pcInitMsg);
1660 llPcInitiatedLspRequestList.add(releaseLspRequest);
1661
1662 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1663 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1664
1665 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1666 }
1667 }
1668 } catch (PcepParseException e) {
1669 log.error("Exception occured while sending initiate delete message {}", e.getMessage());
1670 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301671 }
1672 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301673 @Override
1674 public Tunnel tunnelQueryById(TunnelId tunnelId) {
1675 return service.tunnelQueryById(tunnelId);
1676 }
1677
Priyanka B413fbe82016-05-26 11:44:45 +05301678
1679 private DeviceId getDevice(PccId pccId) {
1680 // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
1681 IpAddress lsrId = pccId.ipAddress();
1682 String lsrIdentifier = String.valueOf(lsrId);
1683
1684 // Find PCC deviceID from lsrId stored as annotations
1685 Iterable<Device> devices = deviceService.getAvailableDevices();
1686 for (Device dev : devices) {
1687 if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
1688 && dev.annotations().value(LSRID).equals(lsrIdentifier)) {
1689 return dev.id();
1690 }
1691 }
1692 return null;
1693 }
1694
1695 /**
1696 * Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
1697 * tunnel is found.
1698 */
1699 private class UpdateDelegation implements Runnable {
1700 DefaultTunnelDescription td;
1701 ProviderId providerId;
1702 SparseAnnotations annotations;
1703 PccId pccId;
1704 ScheduledExecutorService executor;
1705
1706 /**
1707 * Creates an instance of UpdateDelegation.
1708 *
1709 * @param td tunnel description
1710 * @param providerId provider id
1711 * @param annotations tunnel annotations
1712 * @param pccId PCEP client id
1713 * @param executor service of delegated owner
1714 */
1715 public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
1716 PccId pccId, ScheduledExecutorService executor) {
1717 this.td = td;
1718 this.providerId = providerId;
1719 this.annotations = annotations;
1720 this.pccId = pccId;
1721 this.executor = executor;
1722 }
1723
1724 //Temporary using annotations later will use projection/network config service
1725 @Override
1726 public void run() {
1727 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
1728 TunnelId tempTunnelId = null;
1729 for (Tunnel t : tunnelQueryResult) {
1730 if (t.annotations().value(LOCAL_LSP_ID) == null || t.annotations().value(PLSP_ID) == null) {
1731 continue;
1732 }
1733
1734 if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
1735 && t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
1736 && ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
1737 tempTunnelId = t.tunnelId();
1738 break;
1739 }
1740 }
1741
1742 //If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
1743 //periodically
1744 if (tempTunnelId != null) {
1745 Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
1746 tempTunnelId, td.tunnelName(), td.path(), annotations);
1747 tunnelUpdated(tunnel, td.path());
1748 executor.shutdown();
1749 try {
1750 executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
1751 } catch (InterruptedException e) {
1752 log.error("updating delegation failed");
1753 }
1754 }
1755 }
1756 }
cheng fan48e832c2015-05-29 01:54:47 +08001757}