blob: 66e7f3137601144c61207264c394471a97a38231 [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;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053085import org.onosproject.pcepio.exceptions.PcepParseException;
86import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
87import org.onosproject.pcepio.protocol.PcepAttribute;
88import org.onosproject.pcepio.protocol.PcepBandwidthObject;
89import org.onosproject.pcepio.protocol.PcepEndPointsObject;
90import org.onosproject.pcepio.protocol.PcepEroObject;
91import org.onosproject.pcepio.protocol.PcepInitiateMsg;
92import org.onosproject.pcepio.protocol.PcepLspObject;
93import org.onosproject.pcepio.protocol.PcepMessage;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053094import org.onosproject.pcepio.protocol.PcepMetricObject;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053095import org.onosproject.pcepio.protocol.PcepMsgPath;
96import org.onosproject.pcepio.protocol.PcepReportMsg;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053097import org.onosproject.pcepio.protocol.PcepSrpObject;
98import org.onosproject.pcepio.protocol.PcepStateReport;
99import org.onosproject.pcepio.protocol.PcepUpdateMsg;
100import org.onosproject.pcepio.protocol.PcepUpdateRequest;
101import org.onosproject.pcepio.types.IPv4SubObject;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530102import org.onosproject.pcepio.types.PathSetupTypeTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530103import org.onosproject.pcepio.types.PcepValueType;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530104import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530105import org.onosproject.pcepio.types.SymbolicPathNameTlv;
chengfan2fff70f2015-08-24 18:20:19 -0500106import org.osgi.service.component.ComponentContext;
Jonathan Hart51539b82015-10-29 09:53:04 -0700107import org.osgi.service.component.annotations.Modified;
108import org.slf4j.Logger;
109
110import java.util.ArrayList;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530111import java.util.Arrays;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530112import java.util.Collection;
Jonathan Hart51539b82015-10-29 09:53:04 -0700113import java.util.Collections;
114import java.util.Dictionary;
115import java.util.HashMap;
116import java.util.LinkedList;
117import java.util.List;
118import java.util.ListIterator;
119import java.util.Optional;
Priyanka B413fbe82016-05-26 11:44:45 +0530120import java.util.concurrent.Executors;
121import java.util.concurrent.ScheduledExecutorService;
122import java.util.concurrent.TimeUnit;
Jonathan Hart51539b82015-10-29 09:53:04 -0700123
124import static com.google.common.base.Preconditions.checkNotNull;
125import static com.google.common.base.Strings.isNullOrEmpty;
126import static org.onlab.util.Tools.get;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530127import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
Jonathan Hart51539b82015-10-29 09:53:04 -0700128import static org.onosproject.net.DefaultAnnotations.EMPTY;
129import static org.onosproject.net.DeviceId.deviceId;
130import static org.onosproject.net.PortNumber.portNumber;
131import static org.onosproject.pcep.api.PcepDpid.uri;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530132import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530133import static org.onosproject.provider.pcep.tunnel.impl.LspType.SR_WITHOUT_SIGNALLING;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530134import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.BANDWIDTH;
135import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LOCAL_LSP_ID;
136import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.LSP_SIG_TYPE;
137import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PCC_TUNNEL_ID;
138import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.PLSP_ID;
Priyanka B413fbe82016-05-26 11:44:45 +0530139import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.DELEGATE;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530140import static org.onosproject.provider.pcep.tunnel.impl.PcepAnnotationKeys.COST_TYPE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530141import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
142import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
143import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
144import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530145import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530146import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
147import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
148import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
149import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
150import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
Jonathan Hart51539b82015-10-29 09:53:04 -0700151import static org.slf4j.LoggerFactory.getLogger;
cheng fan48e832c2015-05-29 01:54:47 +0800152
153/**
154 * Provider which uses an PCEP controller to detect, update, create network
155 * tunnels.
156 */
157@Component(immediate = true)
158@Service
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530159public class PcepTunnelProvider extends AbstractProvider implements TunnelProvider {
cheng fan48e832c2015-05-29 01:54:47 +0800160
161 private static final Logger log = getLogger(PcepTunnelProvider.class);
162 private static final long MAX_BANDWIDTH = 99999744;
163 private static final long MIN_BANDWIDTH = 64;
cheng fan7716ec92015-05-31 01:53:19 +0800164 private static final String BANDWIDTH_UINT = "kbps";
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530165 static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
Priyanka B413fbe82016-05-26 11:44:45 +0530166 public static final long IDENTIFIER_SET = 0x100000000L;
167 public static final long SET = 0xFFFFFFFFL;
168 private static final int DELAY = 2;
169 private static final int WAIT_TIME = 5;
170 public static final String LSRID = "lsrId";
cheng fan48e832c2015-05-29 01:54:47 +0800171
chengfan2fff70f2015-08-24 18:20:19 -0500172 static final int POLL_INTERVAL = 10;
173 @Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
174 label = "Frequency (in seconds) for polling tunnel statistics")
175 private int tunnelStatsPollFrequency = POLL_INTERVAL;
176
cheng fan48e832c2015-05-29 01:54:47 +0800177 private static final String TUNNLE_NOT_NULL = "Create failed,The given port may be wrong or has been occupied.";
178
179 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
180 protected TunnelProviderRegistry tunnelProviderRegistry;
181
182 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
183 protected PcepController controller;
184
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530185 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
186 protected PcepClientController pcepClientController;
chengfan2fff70f2015-08-24 18:20:19 -0500187
188 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
189 protected TunnelService tunnelService;
190
191 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
192 protected ComponentConfigService cfgService;
193
Priyanka B413fbe82016-05-26 11:44:45 +0530194 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
195 protected TunnelAdminService tunnelAdminService;
196
197 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
198 protected MastershipService mastershipService;
199
200 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
201 protected DeviceService deviceService;
202
cheng fan48e832c2015-05-29 01:54:47 +0800203 TunnelProviderService service;
204
205 HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
chengfan2fff70f2015-08-24 18:20:19 -0500206 HashMap<TunnelId, TunnelStatistics> tunnelStatisticsMap = new HashMap<>();
Brian Stanke9a108972016-04-11 15:25:17 -0400207 private HashMap<String, TunnelStatsCollector> collectors = Maps.newHashMap();
cheng fan48e832c2015-05-29 01:54:47 +0800208
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530209 private InnerTunnelProvider listener = new InnerTunnelProvider();
210
Jonathan Hart51539b82015-10-29 09:53:04 -0700211 protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530212 private static final int DEFAULT_BANDWIDTH_VALUE = 10;
cheng fan48e832c2015-05-29 01:54:47 +0800213
214 /**
215 * Creates a Tunnel provider.
216 */
217 public PcepTunnelProvider() {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530218 super(new ProviderId("pcep", PROVIDER_ID));
cheng fan48e832c2015-05-29 01:54:47 +0800219 }
220
221 @Activate
222 public void activate() {
chengfan2fff70f2015-08-24 18:20:19 -0500223 cfgService.registerProperties(getClass());
cheng fan48e832c2015-05-29 01:54:47 +0800224 service = tunnelProviderRegistry.register(this);
225 controller.addTunnelListener(listener);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530226 pcepClientController.addListener(listener);
227 pcepClientController.addEventListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500228 tunnelService.queryAllTunnels().forEach(tunnel -> {
Jonathan Hart51539b82015-10-29 09:53:04 -0700229 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
chengfan2fff70f2015-08-24 18:20:19 -0500230 TunnelStatsCollector tsc = new TunnelStatsCollector(pcepTunnelId, tunnelStatsPollFrequency);
231 tsc.start();
232 collectors.put(tunnel.tunnelId().id(), tsc);
233
234 });
235
cheng fan48e832c2015-05-29 01:54:47 +0800236 log.info("Started");
237 }
238
239 @Deactivate
240 public void deactivate() {
241 tunnelProviderRegistry.unregister(this);
242 controller.removeTunnelListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500243 collectors.values().forEach(TunnelStatsCollector::stop);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530244 pcepClientController.removeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800245 log.info("Stopped");
246 }
247
chengfan2fff70f2015-08-24 18:20:19 -0500248 @Modified
249 public void modified(ComponentContext context) {
250 Dictionary<?, ?> properties = context.getProperties();
251 int newTunnelStatsPollFrequency;
252 try {
253 String s = get(properties, "tunnelStatsPollFrequency");
254 newTunnelStatsPollFrequency = isNullOrEmpty(s) ? tunnelStatsPollFrequency : Integer.parseInt(s.trim());
255
256 } catch (NumberFormatException | ClassCastException e) {
257 newTunnelStatsPollFrequency = tunnelStatsPollFrequency;
258 }
259
260 if (newTunnelStatsPollFrequency != tunnelStatsPollFrequency) {
261 tunnelStatsPollFrequency = newTunnelStatsPollFrequency;
262 collectors.values().forEach(tsc -> tsc.adjustPollInterval(tunnelStatsPollFrequency));
263 log.info("New setting: tunnelStatsPollFrequency={}", tunnelStatsPollFrequency);
264 }
265
266 }
267
cheng fan48e832c2015-05-29 01:54:47 +0800268 @Override
269 public void setupTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530270 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530271 log.error("Tunnel Type MPLS is only supported");
272 return;
273 }
cheng fan48e832c2015-05-29 01:54:47 +0800274
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530275 // check for tunnel end points
276 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
277 log.error("Tunnel source or destination is not valid");
278 return;
279 }
280
281 // Get the pcc client
282 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
283
284 if (!(pc instanceof PcepClient)) {
285 log.error("There is no PCC connected with ip addresss {}"
chengfan2fff70f2015-08-24 18:20:19 -0500286 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530287 return;
288 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530289
290 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
Priyanka B413fbe82016-05-26 11:44:45 +0530291 //Only master will initiate setup tunnel
292 if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530293 pcepSetupTunnel(tunnel, path, pc);
294 }
cheng fan48e832c2015-05-29 01:54:47 +0800295 }
296
297 @Override
298 public void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800299
Avantika-Huawei56c11842016-04-28 00:56:56 +0530300 if (tunnel.annotations().value(PLSP_ID) != null) {
301 updateTunnel(tunnel, path);
302 return;
303 }
304
305 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530306 log.error("Tunnel Type MPLS is only supported");
307 return;
308 }
309
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530310 // check for tunnel end points
311 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
312 log.error("Tunnel source or destination is not valid");
313 return;
314 }
315
Priyanka Bcdf9b102016-06-07 20:01:38 +0530316 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530317
318 if (!(pc instanceof PcepClient)) {
319 log.error("There is no PCC connected with ip addresss {}"
320 + ((IpElementId) srcElement).ipAddress().toString());
321 return;
322 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530323
Priyanka B413fbe82016-05-26 11:44:45 +0530324 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
325 //Only master will initiate setup tunnel
326 if (pc.capability().pcInstantiationCapability()
327 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530328 pcepSetupTunnel(tunnel, path, pc);
329 }
cheng fan48e832c2015-05-29 01:54:47 +0800330 }
331
332 @Override
333 public void releaseTunnel(Tunnel tunnel) {
cheng fan48e832c2015-05-29 01:54:47 +0800334
Avantika-Huawei56c11842016-04-28 00:56:56 +0530335 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530336 log.error("Tunnel Type MPLS is only supported");
337 return;
338 }
339
340 // check for tunnel end points
341 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
342 log.error("Tunnel source or destination is not valid");
343 return;
344 }
345
346 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
347
348 if (!(pc instanceof PcepClient)) {
349 log.error("There is no PCC connected with ip addresss {}"
350 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
351 return;
352 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530353
Priyanka B413fbe82016-05-26 11:44:45 +0530354 //Only master will release tunnel
355 if (pc.capability().pcInstantiationCapability()
356 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530357 pcepReleaseTunnel(tunnel, pc);
358 }
cheng fan48e832c2015-05-29 01:54:47 +0800359 }
360
361 @Override
362 public void releaseTunnel(ElementId srcElement, Tunnel tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530363 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530364 log.error("Tunnel Type MPLS is only supported");
365 return;
366 }
cheng fan48e832c2015-05-29 01:54:47 +0800367
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530368 if (!(srcElement instanceof IpElementId)) {
369 log.error("Element id is not valid");
370 return;
371 }
372
373 // check for tunnel end points
374 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
375 log.error("Tunnel source or destination is not valid");
376 return;
377 }
378
379 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
380
381 if (!(pc instanceof PcepClient)) {
382 log.error("There is no PCC connected with ip addresss {}"
383 + ((IpElementId) srcElement).ipAddress().toString());
384 return;
385 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530386
Priyanka B413fbe82016-05-26 11:44:45 +0530387 //Only master will release tunnel
388 if (pc.capability().pcInstantiationCapability()
389 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530390 pcepReleaseTunnel(tunnel, pc);
391 }
cheng fan48e832c2015-05-29 01:54:47 +0800392 }
393
394 @Override
395 public void updateTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530396 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530397 log.error("Tunnel Type MPLS is only supported");
398 return;
399 }
cheng fan48e832c2015-05-29 01:54:47 +0800400
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530401 // check for tunnel end points
402 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
403 log.error("Tunnel source or destination is not valid");
404 return;
405 }
406
407 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
408
409 if (!(pc instanceof PcepClient)) {
410 log.error("There is no PCC connected with ip addresss {}"
411 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
412 return;
413 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530414
Priyanka B413fbe82016-05-26 11:44:45 +0530415 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
416 // LSP].If annotation is null D flag is not set else it is set.
417 if (pc.capability().statefulPceCapability()
418 && pc.delegationInfo(
419 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
420 .annotations().value(LOCAL_LSP_ID)))) != null) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530421 pcepUpdateTunnel(tunnel, path, pc);
422 }
cheng fan48e832c2015-05-29 01:54:47 +0800423 }
424
425 @Override
426 public void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800427
Avantika-Huawei56c11842016-04-28 00:56:56 +0530428 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530429 log.error("Tunnel Type MPLS is only supported");
430 return;
431 }
432
433 if (!(srcElement instanceof IpElementId)) {
434 log.error("Element id is not valid");
435 return;
436 }
437
438 // check for tunnel end points
439 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
440 log.error("Tunnel source or destination is not valid");
441 return;
442 }
443
444 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
445
446 if (!(pc instanceof PcepClient)) {
447 log.error("There is no PCC connected with ip addresss {}"
448 + ((IpElementId) srcElement).ipAddress().toString());
449 return;
450 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530451
Priyanka B413fbe82016-05-26 11:44:45 +0530452 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
453 // LSP].If annotation is null D flag is not set else it is set.
454 if (pc.capability().statefulPceCapability()
455 && pc.delegationInfo(
456 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
457 .annotations().value(LOCAL_LSP_ID)))) != null) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530458 pcepUpdateTunnel(tunnel, path, pc);
459 }
cheng fan48e832c2015-05-29 01:54:47 +0800460 }
461
462 @Override
463 public TunnelId tunnelAdded(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530464 return handleTunnelAdded(tunnel, null);
465 }
466
467 public TunnelId tunnelAdded(TunnelDescription tunnel, State tunnelState) {
468 return handleTunnelAdded(tunnel, tunnelState);
469 }
470
471 private TunnelId handleTunnelAdded(TunnelDescription tunnel, State tunnelState) {
472
473 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700474 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530475
476 if (tunnelState == null) {
477 return service.tunnelAdded(tunnel);
478 } else {
479 return service.tunnelAdded(tunnel, tunnelState);
480 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530481 }
cheng fan48e832c2015-05-29 01:54:47 +0800482
Avantika-Huawei56c11842016-04-28 00:56:56 +0530483 long bandwidth = Long.parseLong(tunnel.annotations().value(BANDWIDTH));
cheng fan48e832c2015-05-29 01:54:47 +0800484
485 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800486 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800487 return null;
488 }
489
490 // endpoints
491 OpticalTunnelEndPoint src = (org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint) tunnel
492 .src();
493 OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst();
494 // devices
495 DeviceId srcId = (DeviceId) src.elementId().get();
496 DeviceId dstId = (DeviceId) dst.elementId().get();
497
498 // ports
499 long srcPort = src.portNumber().get().toLong();
500 long dstPort = dst.portNumber().get().toLong();
501
502 // type
503 if (tunnel.type() != Tunnel.Type.VLAN) {
cheng fan7716ec92015-05-31 01:53:19 +0800504 error("Illegal tunnel type. Only support VLAN tunnel creation.");
cheng fan48e832c2015-05-29 01:54:47 +0800505 return null;
506 }
507
508 PcepTunnel pcepTunnel = controller.applyTunnel(srcId, dstId, srcPort,
509 dstPort, bandwidth,
510 tunnel.tunnelName()
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530511 .value());
cheng fan48e832c2015-05-29 01:54:47 +0800512
513 checkNotNull(pcepTunnel, TUNNLE_NOT_NULL);
514 TunnelDescription tunnelAdded = buildOpticalTunnel(pcepTunnel, null);
515 TunnelId tunnelId = service.tunnelAdded(tunnelAdded);
516
517 tunnelMap.put(String.valueOf(pcepTunnel.id()), tunnelId);
518 return tunnelId;
519 }
520
Priyanka B413fbe82016-05-26 11:44:45 +0530521 private void tunnelUpdated(Tunnel tunnel, Path path) {
522 handleTunnelUpdate(tunnel, path);
523 }
524
525 //Handles tunnel updated using tunnel admin service[specially to update annotations].
526 private void handleTunnelUpdate(Tunnel tunnel, Path path) {
527
528 if (tunnel.type() == MPLS) {
529 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
530
531 tunnelAdminService.updateTunnel(tunnel, path);
532
533 return;
534 }
535
536 Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
537 if (tunnelOld.type() != Tunnel.Type.VLAN) {
538 error("Illegal tunnel type. Only support VLAN tunnel update.");
539 return;
540 }
541
542 long bandwidth = Long
543 .parseLong(tunnel.annotations().value("bandwidth"));
544 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
545 error("Update failed, invalid bandwidth.");
546 return;
547 }
548 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
549
550 checkNotNull(pcepTunnelId, "Invalid tunnel id");
551 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
552 error("Update failed,maybe invalid bandwidth.");
553 return;
554 }
555 tunnelAdminService.updateTunnel(tunnel, path);
556 }
557
cheng fan48e832c2015-05-29 01:54:47 +0800558 @Override
559 public void tunnelRemoved(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530560 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700561 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530562 service.tunnelRemoved(tunnel);
563 }
564
cheng fan48e832c2015-05-29 01:54:47 +0800565 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
566 checkNotNull(tunnelOld, "The tunnel id is not exsited.");
567 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800568 error("Illegal tunnel type. Only support VLAN tunnel deletion.");
cheng fan48e832c2015-05-29 01:54:47 +0800569 return;
570 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700571 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800572 checkNotNull(pcepTunnelId, "The tunnel id is not exsited.");
cheng fan7716ec92015-05-31 01:53:19 +0800573 if (!controller.deleteTunnel(pcepTunnelId)) {
574 error("Delete tunnel failed, Maybe some devices have been disconnected.");
575 return;
cheng fan48e832c2015-05-29 01:54:47 +0800576 }
577 tunnelMap.remove(pcepTunnelId);
578 service.tunnelRemoved(tunnel);
cheng fan48e832c2015-05-29 01:54:47 +0800579 }
580
581 @Override
582 public void tunnelUpdated(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530583 handleTunnelUpdate(tunnel, null);
584 }
585
586 public void tunnelUpdated(TunnelDescription tunnel, State tunnelState) {
587 handleTunnelUpdate(tunnel, tunnelState);
588 }
589
590 private void handleTunnelUpdate(TunnelDescription tunnel, State tunnelState) {
591 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700592 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530593
594 if (tunnelState == null) {
595 service.tunnelUpdated(tunnel);
596 } else {
597 service.tunnelUpdated(tunnel, tunnelState);
598 }
599 return;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530600 }
cheng fan48e832c2015-05-29 01:54:47 +0800601
602 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
603 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800604 error("Illegal tunnel type. Only support VLAN tunnel update.");
cheng fan48e832c2015-05-29 01:54:47 +0800605 return;
606 }
cheng fan7716ec92015-05-31 01:53:19 +0800607 long bandwidth = Long
608 .parseLong(tunnel.annotations().value("bandwidth"));
cheng fan48e832c2015-05-29 01:54:47 +0800609 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800610 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800611 return;
612 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700613 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800614
615 checkNotNull(pcepTunnelId, "Invalid tunnel id");
616 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
617
cheng fan7716ec92015-05-31 01:53:19 +0800618 error("Update failed,maybe invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800619 return;
620
621 }
622 service.tunnelUpdated(tunnel);
623 }
624
cheng fan7716ec92015-05-31 01:53:19 +0800625 private void error(String info) {
626 System.err.println(info);
627 }
628
cheng fan48e832c2015-05-29 01:54:47 +0800629 // Short-hand for creating a connection point.
630 private ConnectPoint connectPoint(PcepDpid id, long port) {
631 return new ConnectPoint(deviceId(uri(id)), portNumber(port));
632 }
633
634 // Short-hand for creating a link.
635 private Link link(PcepDpid src, long sp, PcepDpid dst, long dp) {
Ray Milkey2693bda2016-01-22 16:08:14 -0800636 return DefaultLink.builder()
637 .providerId(id())
638 .src(connectPoint(src, sp))
639 .dst(connectPoint(dst, dp))
640 .type(Link.Type.TUNNEL)
641 .build();
cheng fan48e832c2015-05-29 01:54:47 +0800642 }
643
644 // Creates a path that leads through the given devices.
645 private Path createPath(List<PcepHopNodeDescription> hopList,
Jonathan Hart51539b82015-10-29 09:53:04 -0700646 PathType pathtype, PathState pathState) {
cheng fan48e832c2015-05-29 01:54:47 +0800647 if (hopList == null || hopList.size() == 0) {
648 return null;
649 }
650 List<Link> links = new ArrayList<>();
651 for (int i = 1; i < hopList.size() - 1; i = i + 2) {
652 links.add(link(hopList.get(i).getDeviceId(), hopList.get(i)
653 .getPortNum(), hopList.get(i + 1).getDeviceId(), hopList
654 .get(i + 1).getPortNum()));
655 }
656
657 int hopNum = hopList.size() - 2;
658 DefaultAnnotations extendAnnotations = DefaultAnnotations.builder()
659 .set("pathNum", String.valueOf(hopNum))
cheng fan93258c72015-06-02 23:42:32 +0800660 .set("pathState", String.valueOf(pathState))
cheng fan48e832c2015-05-29 01:54:47 +0800661 .set("pathType", String.valueOf(pathtype)).build();
662 return new DefaultPath(id(), links, hopNum, extendAnnotations);
663 }
664
665 // convert the path description to a string.
666 public String pathToString(List<Link> links) {
667 StringBuilder builder = new StringBuilder();
668 builder.append("{");
669 for (Link link : links) {
670 builder.append("(Device:" + link.src().deviceId() + " Port:"
671 + link.src().port().toLong());
672 builder.append(" Device:" + link.dst().deviceId() + " Port:"
673 + link.dst().port().toLong());
674 builder.append(")");
675 }
676 builder.append("}");
677 return builder.toString();
678 }
679
680 // build a TunnelDescription.
681 private TunnelDescription buildOpticalTunnel(PcepTunnel pcepTunnel,
682 TunnelId tunnelId) {
683 TunnelEndPoint srcPoint = null;
684 TunnelEndPoint dstPoint = null;
685 Tunnel.Type tunnelType = null;
686 TunnelName name = TunnelName.tunnelName(pcepTunnel.name());
687
688 // add path after codes of tunnel's path merged
689 Path path = createPath(pcepTunnel.getHopList(),
cheng fan93258c72015-06-02 23:42:32 +0800690 pcepTunnel.getPathType(),
691 pcepTunnel.getPathState());
cheng fan48e832c2015-05-29 01:54:47 +0800692
693 OpticalTunnelEndPoint.Type endPointType = null;
694 switch (pcepTunnel.type()) {
695 case OCH:
696 tunnelType = Tunnel.Type.OCH;
697 endPointType = OpticalTunnelEndPoint.Type.LAMBDA;
698 break;
699
700 case OTN:
701 tunnelType = Tunnel.Type.ODUK;
702 endPointType = OpticalTunnelEndPoint.Type.TIMESLOT;
703 break;
704
705 case UNI:
706 tunnelType = Tunnel.Type.VLAN;
707 endPointType = null;
708 break;
709
710 default:
711 break;
712 }
713 DeviceId srcDid = deviceId(uri(pcepTunnel.srcDeviceID()));
714 DeviceId dstDid = deviceId(uri(pcepTunnel.dstDeviceId()));
715 PortNumber srcPort = PortNumber.portNumber(pcepTunnel.srcPort());
716 PortNumber dstPort = PortNumber.portNumber(pcepTunnel.dstPort());
717
718 srcPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(srcDid),
719 Optional.of(srcPort), null,
720 endPointType,
721 OpticalLogicId.logicId(0),
722 true);
723 dstPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(dstDid),
724 Optional.of(dstPort), null,
725 endPointType,
726 OpticalLogicId.logicId(0),
727 true);
728
729 // basic annotations
cheng fan7716ec92015-05-31 01:53:19 +0800730 DefaultAnnotations annotations = DefaultAnnotations
731 .builder()
cheng fan48e832c2015-05-29 01:54:47 +0800732 .set("SLA", String.valueOf(pcepTunnel.getSla()))
cheng fan7716ec92015-05-31 01:53:19 +0800733 .set("bandwidth",
734 String.valueOf(pcepTunnel.bandWidth()) + BANDWIDTH_UINT)
cheng fan48e832c2015-05-29 01:54:47 +0800735 .set("index", String.valueOf(pcepTunnel.id())).build();
736
cheng fan48e832c2015-05-29 01:54:47 +0800737 // a VLAN tunnel always carry OCH tunnel, this annotation is the index
738 // of a OCH tunnel.
cheng fan93258c72015-06-02 23:42:32 +0800739 if (pcepTunnel.underlayTunnelId() != 0) {
cheng fan48e832c2015-05-29 01:54:47 +0800740 DefaultAnnotations extendAnnotations = DefaultAnnotations
741 .builder()
742 .set("underLayTunnelIndex",
cheng fan93258c72015-06-02 23:42:32 +0800743 String.valueOf(pcepTunnel.underlayTunnelId())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800744 annotations = DefaultAnnotations.merge(annotations,
745 extendAnnotations);
746
747 }
748 TunnelDescription tunnel = new DefaultTunnelDescription(
749 tunnelId,
750 srcPoint,
751 dstPoint,
752 tunnelType,
753 new DefaultGroupId(
754 0),
755 id(), name,
756 path,
757 annotations);
758 return tunnel;
cheng fan48e832c2015-05-29 01:54:47 +0800759 }
760
761 /**
762 * Get the tunnelID according to the tunnel key.
763 *
764 * @param tunnelKey tunnel key
765 * @return corresponding tunnel id of the a tunnel key.
766 */
767 private TunnelId getTunnelId(String tunnelKey) {
cheng fan48e832c2015-05-29 01:54:47 +0800768 for (String key : tunnelMap.keySet()) {
769 if (key.equals(tunnelKey)) {
770 return tunnelMap.get(key);
771 }
772 }
773 return null;
774 }
775
776 /**
777 * Get the tunnel key according to the tunnelID.
778 *
779 * @param tunnelId tunnel id
780 * @return corresponding a tunnel key of the tunnel id.
781 */
Jonathan Hart51539b82015-10-29 09:53:04 -0700782 private String getPcepTunnelKey(TunnelId tunnelId) {
cheng fan48e832c2015-05-29 01:54:47 +0800783 for (String key : tunnelMap.keySet()) {
784 if (tunnelMap.get(key).id() == tunnelId.id()) {
785 return key;
786 }
787 }
788 return null;
789
790 }
791
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530792 /**
chengfan2fff70f2015-08-24 18:20:19 -0500793 * Build a DefaultTunnelStatistics from a PcepTunnelStatistics.
794 *
795 * @param statistics statistics data from a PCEP tunnel
796 * @return TunnelStatistics
797 */
798 private TunnelStatistics buildTunnelStatistics(PcepTunnelStatistics statistics) {
799 DefaultTunnelStatistics.Builder builder = new DefaultTunnelStatistics.Builder();
800 DefaultTunnelStatistics tunnelStatistics = builder.setBwUtilization(statistics.bandwidthUtilization())
801 .setPacketLossRatio(statistics.packetLossRate())
802 .setFlowDelay(statistics.flowDelay())
803 .setAlarms(statistics.alarms())
804 .build();
805 return tunnelStatistics;
806 }
807 /**
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530808 * Creates list of hops for ERO object from Path.
809 *
810 * @param path network path
811 * @return list of ipv4 subobjects
812 */
813 private LinkedList<PcepValueType> createPcepPath(Path path) {
814 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
815 List<Link> listLink = path.links();
816 ConnectPoint source = null;
817 ConnectPoint destination = null;
818 IpAddress ipDstAddress = null;
819 IpAddress ipSrcAddress = null;
820 PcepValueType subObj = null;
Priyanka Bcdf9b102016-06-07 20:01:38 +0530821 long portNo;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530822
823 for (Link link : listLink) {
824 source = link.src();
825 if (!(source.equals(destination))) {
826 //set IPv4SubObject for ERO object
Priyanka Bcdf9b102016-06-07 20:01:38 +0530827 portNo = source.port().toLong();
828 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
829 ipSrcAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530830 subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
831 llSubObjects.add(subObj);
832 }
833
834 destination = link.dst();
Priyanka Bcdf9b102016-06-07 20:01:38 +0530835 portNo = destination.port().toLong();
836 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
837 ipDstAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530838 subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
839 llSubObjects.add(subObj);
840 }
Priyanka Bcdf9b102016-06-07 20:01:38 +0530841
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530842 return llSubObjects;
843 }
844
845 /**
846 * Creates PcInitiated lsp request list for setup tunnel.
847 *
848 * @param tunnel mpls tunnel
849 * @param path network path
850 * @param pc pcep client
851 * @param srpId unique id for pcep message
852 * @return list of PcInitiatedLspRequest
853 * @throws PcepParseException while building pcep objects fails
854 */
855 LinkedList<PcInitiatedLspRequest> createPcInitiatedLspReqList(Tunnel tunnel, Path path,
856 PcepClient pc, int srpId)
857 throws PcepParseException {
858 PcepValueType tlv;
859 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
860
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700861 if (llSubObjects == null || llSubObjects.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530862 log.error("There is no link information to create tunnel");
863 return null;
864 }
865
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530866 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530867
868 // set PathSetupTypeTlv of SRP object
869 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)).type());
870 llOptionalTlv.add(tlv);
871
872 // build SRP object
873 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
874 .setOptionalTlv(llOptionalTlv).build();
875
876 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530877 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530878
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530879 // set LSP identifiers TLV
Avantika-Huawei56c11842016-04-28 00:56:56 +0530880 short localLspId = 0;
881 if (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) != WITH_SIGNALLING) {
882 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
883 if (localLspIdString != null) {
884 localLspId = Short.valueOf(localLspIdString);
885 }
886 }
887
888 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
889 localLspId, (short) 0, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
890 .getIp4Address().toInt()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530891 llOptionalTlv.add(tlv);
892 //set SymbolicPathNameTlv of LSP object
893 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
894 llOptionalTlv.add(tlv);
895
896 //build LSP object
897 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setOFlag((byte) 0).setPlspId(0)
898 .setOptionalTlv(llOptionalTlv).build();
899
900 //build ENDPOINTS object
901 PcepEndPointsObject endpointsobj = pc.factory().buildEndPointsObject()
902 .setSourceIpAddress(((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt())
903 .setDestIpAddress(((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt())
904 .setPFlag(true).build();
905
906 //build ERO object
907 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
908
Priyanka Bcdf9b102016-06-07 20:01:38 +0530909 float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530910 if (tunnel.annotations().value(BANDWIDTH) != null) {
Priyanka Bcdf9b102016-06-07 20:01:38 +0530911 iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530912 }
913 // build bandwidth object
914 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
915 // build pcep attribute
916 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
917
918 PcInitiatedLspRequest initiateLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
919 .setLspObject(lspobj).setEndPointsObject(endpointsobj).setEroObject(eroobj)
920 .setPcepAttribute(pcepAttribute).build();
921 llPcInitiatedLspRequestList.add(initiateLspRequest);
922 return llPcInitiatedLspRequestList;
923 }
924
925 /**
926 * To send initiate tunnel message to pcc.
927 *
928 * @param tunnel mpls tunnel info
929 * @param path explicit route for the tunnel
930 * @param pc pcep client to send message
931 */
932 private void pcepSetupTunnel(Tunnel tunnel, Path path, PcepClient pc) {
933 try {
934 int srpId = SrpIdGenerators.create();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530935 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, CREATE);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530936
Jonathan Hart51539b82015-10-29 09:53:04 -0700937 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530938
939 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = createPcInitiatedLspReqList(tunnel, path,
940 pc, srpId);
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700941 if (llPcInitiatedLspRequestList == null || llPcInitiatedLspRequestList.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530942 log.error("Failed to create PcInitiatedLspRequestList");
943 return;
944 }
945
946 //build PCInitiate message
947 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
948 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList)
949 .build();
950
951 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
952
Jonathan Hart51539b82015-10-29 09:53:04 -0700953 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530954 } catch (PcepParseException e) {
955 log.error("PcepParseException occurred while processing setup tunnel {}", e.getMessage());
956 }
957 }
958
959 /**
960 * To send Release tunnel message to pcc.
961 *
962 * @param tunnel mpls tunnel info
963 * @param pc pcep client to send message
964 */
965 private void pcepReleaseTunnel(Tunnel tunnel, PcepClient pc) {
966 try {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530967 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, DELETE);
Jonathan Hart51539b82015-10-29 09:53:04 -0700968 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530969 int srpId = SrpIdGenerators.create();
970 TunnelId tunnelId = tunnel.tunnelId();
971 int plspId = 0;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530972
Jonathan Hart51539b82015-10-29 09:53:04 -0700973 if (!(pcepTunnelApiMapper.checkFromTunnelDBQueue(tunnelId))) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530974 log.error("Tunnel doesnot exists. Tunnel id {}" + tunnelId.toString());
975 return;
976 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -0700977 PcepTunnelData pcepTunnelDbData = pcepTunnelApiMapper.getDataFromTunnelDBQueue(tunnelId);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530978 plspId = pcepTunnelDbData.plspId();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530979 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530980
981 PcepValueType tlv;
982 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530983
984 // set PathSetupTypeTlv of SRP object
985 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))
986 .type());
987 llOptionalTlv.add(tlv);
988
989 // build SRP object
990 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(true)
991 .setOptionalTlv(llOptionalTlv).build();
992
993 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530994 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
995
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530996 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
997 llOptionalTlv.add(tlv);
998 // build lsp object, set r flag as false to delete the tunnel
999 PcepLspObject lspobj = pc.factory().buildLspObject().setRFlag(false).setPlspId(plspId)
1000 .setOptionalTlv(llOptionalTlv).build();
1001
1002 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
1003 .setLspObject(lspobj).build();
1004
1005 llPcInitiatedLspRequestList.add(releaseLspRequest);
1006
1007 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1008 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1009
1010 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1011
Jonathan Hart51539b82015-10-29 09:53:04 -07001012 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301013 } catch (PcepParseException e) {
1014 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1015 }
1016 }
1017
1018 /**
1019 * To send Update tunnel request message to pcc.
1020 *
1021 * @param tunnel mpls tunnel info
1022 * @param path explicit route for the tunnel
1023 * @param pc pcep client to send message
1024 */
1025 private void pcepUpdateTunnel(Tunnel tunnel, Path path, PcepClient pc) {
1026 try {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301027 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, UPDATE);
Jonathan Hart51539b82015-10-29 09:53:04 -07001028 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301029 int srpId = SrpIdGenerators.create();
1030 TunnelId tunnelId = tunnel.tunnelId();
1031 PcepValueType tlv;
1032 int plspId = 0;
1033
1034 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
1035 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
1036 LinkedList<PcepUpdateRequest> llUpdateRequestList = new LinkedList<PcepUpdateRequest>();
1037
Avantika-Huawei56c11842016-04-28 00:56:56 +05301038 // set PathSetupTypeTlv of SRP object
1039 LspType lspSigType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
1040 tlv = new PathSetupTypeTlv(lspSigType.type());
1041 llOptionalTlv.add(tlv);
1042
1043 // build SRP object
1044 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
1045 .setOptionalTlv(llOptionalTlv).build();
1046
1047 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301048
Jonathan Hart51539b82015-10-29 09:53:04 -07001049 if (!(pcepTunnelApiMapper.checkFromTunnelDBQueue(tunnelId))) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301050 log.error("Tunnel doesnot exists in DB");
1051 return;
1052 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -07001053 PcepTunnelData pcepTunnelDBData = pcepTunnelApiMapper.getDataFromTunnelDBQueue(tunnelId);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301054 plspId = pcepTunnelDBData.plspId();
1055 }
1056
Avantika-Huawei56c11842016-04-28 00:56:56 +05301057 if (lspSigType != WITH_SIGNALLING) {
1058 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
1059 String pccTunnelIdString = tunnel.annotations().value(PCC_TUNNEL_ID);
1060 short localLspId = 0;
1061 short pccTunnelId = 0;
1062
1063 if (localLspIdString != null) {
1064 localLspId = Short.valueOf(localLspIdString);
1065 }
1066
1067 if (pccTunnelIdString != null) {
1068 pccTunnelId = Short.valueOf(pccTunnelIdString);
1069 }
1070
1071 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src())
1072 .ip().getIp4Address().toInt()),
1073 localLspId, pccTunnelId, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
1074 .getIp4Address().toInt()));
1075 llOptionalTlv.add(tlv);
1076 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301077
1078 if (tunnel.tunnelName().value() != null) {
1079 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1080 llOptionalTlv.add(tlv);
1081 }
1082
1083 // build lsp object
1084 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setPlspId(plspId)
1085 .setOptionalTlv(llOptionalTlv).build();
1086 // build ero object
1087 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
1088
1089 int iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +05301090 if (tunnel.annotations().value(BANDWIDTH) != null) {
1091 iBandwidth = Integer.parseInt(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301092 }
1093 // build bandwidth object
1094 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
1095 // build pcep attribute
1096 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
1097 // build pcep msg path
1098 PcepMsgPath msgPath = pc.factory().buildPcepMsgPath().setEroObject(eroobj).setPcepAttribute(pcepAttribute)
1099 .build();
1100
1101 PcepUpdateRequest updateRequest = pc.factory().buildPcepUpdateRequest().setSrpObject(srpobj)
1102 .setLspObject(lspobj).setMsgPath(msgPath).build();
1103
1104 llUpdateRequestList.add(updateRequest);
1105
1106 PcepUpdateMsg pcUpdateMsg = pc.factory().buildUpdateMsg().setUpdateRequestList(llUpdateRequestList).build();
1107
1108 pc.sendMessage(Collections.singletonList(pcUpdateMsg));
Jonathan Hart51539b82015-10-29 09:53:04 -07001109 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301110 } catch (PcepParseException e) {
1111 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1112 }
1113 }
1114
chengfan2fff70f2015-08-24 18:20:19 -05001115
1116
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301117 private class InnerTunnelProvider implements PcepTunnelListener, PcepEventListener, PcepClientListener {
cheng fan48e832c2015-05-29 01:54:47 +08001118
1119 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -07001120 public void handlePcepTunnel(PcepTunnel pcepTunnel) {
cheng fan48e832c2015-05-29 01:54:47 +08001121 TunnelDescription tunnel = null;
1122 // instance and id identify a tunnel together
1123 String tunnelKey = String.valueOf(pcepTunnel.getInstance())
1124 + String.valueOf(pcepTunnel.id());
1125
1126 if (tunnelKey == null || "".equals(tunnelKey)) {
1127 log.error("Invalid PCEP tunnel");
1128 return;
1129 }
1130
1131 TunnelId tunnelId = getTunnelId(tunnelKey);
1132
1133 tunnel = buildOpticalTunnel(pcepTunnel, tunnelId);
1134
1135 OperationType operType = pcepTunnel.getOperationType();
1136 switch (operType) {
1137 case ADD:
1138 tunnelId = service.tunnelAdded(tunnel);
1139 tunnelMap.put(tunnelKey, tunnelId);
1140 break;
1141
1142 case UPDATE:
1143 service.tunnelUpdated(tunnel);
1144 break;
1145
1146 case DELETE:
1147 service.tunnelRemoved(tunnel);
1148 tunnelMap.remove(tunnelKey);
1149 break;
1150
1151 default:
1152 log.error("Invalid tunnel operation");
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301153 }
1154 }
cheng fan48e832c2015-05-29 01:54:47 +08001155
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301156 @Override
1157 public void handleMessage(PccId pccId, PcepMessage msg) {
1158 try {
1159 log.debug("tunnel provider handle message {}", msg.getType().toString());
1160 switch (msg.getType()) {
1161 case REPORT:
1162 int srpId = 0;
1163 LinkedList<PcepStateReport> llStateReportList = null;
1164 llStateReportList = ((PcepReportMsg) msg).getStateReportList();
1165 ListIterator<PcepStateReport> listIterator = llStateReportList.listIterator();
1166 PcepSrpObject srpObj = null;
1167 PcepLspObject lspObj = null;
1168 while (listIterator.hasNext()) {
1169 PcepStateReport stateRpt = listIterator.next();
1170 srpObj = stateRpt.getSrpObject();
1171 lspObj = stateRpt.getLspObject();
1172
1173 if (srpObj instanceof PcepSrpObject) {
1174 srpId = srpObj.getSrpID();
1175 }
1176
1177 log.debug("Plsp ID in handle message " + lspObj.getPlspId());
1178 log.debug("SRP ID in handle message " + srpId);
1179
Jonathan Hart51539b82015-10-29 09:53:04 -07001180 if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301181 // For PCRpt without matching SRP id.
1182 handleRptWithoutSrpId(stateRpt, pccId);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301183 continue;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301184 }
1185
Avantika-Huawei56c11842016-04-28 00:56:56 +05301186 handleReportMessage(srpId, lspObj, stateRpt);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301187 }
1188 break;
1189
1190 default:
1191 log.debug("Received unsupported message type {}", msg.getType().toString());
1192 }
1193 } catch (Exception e) {
1194 log.error("Exception occured while processing report message {}", e.getMessage());
1195 }
1196 }
1197
1198 /**
1199 * Handles report message for setup/update/delete tunnel request.
1200 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301201 * @param srpId unique identifier for PCEP message
1202 * @param lspObj LSP object
1203 * @param stateRpt parsed PCEP report msg.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301204 */
Avantika-Huawei56c11842016-04-28 00:56:56 +05301205 private void handleReportMessage(int srpId, PcepLspObject lspObj, PcepStateReport stateRpt) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301206 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Jonathan Hart51539b82015-10-29 09:53:04 -07001207 PcepTunnelData pcepTunnelData = pcepTunnelApiMapper.getDataFromTunnelRequestQueue(srpId);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301208
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301209 // store the values required from report message
1210 pcepTunnelData.setPlspId(lspObj.getPlspId());
1211 pcepTunnelData.setLspAFlag(lspObj.getAFlag());
1212 pcepTunnelData.setLspOFlag(lspObj.getOFlag());
1213 pcepTunnelData.setLspDFlag(lspObj.getDFlag());
1214
Avantika-Huawei56c11842016-04-28 00:56:56 +05301215 StatefulIPv4LspIdentifiersTlv ipv4LspTlv = null;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301216 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1217 while (listTlvIterator.hasNext()) {
1218 PcepValueType tlv = listTlvIterator.next();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301219 if (tlv.getType() == StatefulIPv4LspIdentifiersTlv.TYPE) {
1220 ipv4LspTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301221 break;
1222 }
1223 }
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001224 if (ipv4LspTlv != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301225 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspTlv);
cheng fan48e832c2015-05-29 01:54:47 +08001226 }
1227
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301228 Path path = pcepTunnelData.path();
1229 Tunnel tunnel = pcepTunnelData.tunnel();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301230 Builder annotationBuilder = DefaultAnnotations.builder();
1231 annotationBuilder.putAll(pcepTunnelData.tunnel().annotations());
1232
1233 // PCRpt in response to PCInitate msg will carry PLSP id allocated by PCC.
1234 if (tunnel.annotations().value(PLSP_ID) == null) {
1235 annotationBuilder.set(PLSP_ID, String.valueOf(lspObj.getPlspId()));
1236 }
1237
1238 // Signalled LSPs will carry local LSP id allocated by signalling protocol(PCC).
1239 if (tunnel.annotations().value(LOCAL_LSP_ID) == null) {
1240 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(ipv4LspTlv.getLspId()));
1241 }
1242
1243 SparseAnnotations annotations = annotationBuilder.build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301244 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(),
1245 tunnel.dst(), tunnel.type(), tunnel.groupId(),
1246 providerId, tunnel.tunnelName(), path,
1247 annotations);
1248
Avantika-Huawei56c11842016-04-28 00:56:56 +05301249 if (CREATE == pcepTunnelData.requestType()) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001250 pcepTunnelApiMapper.handleCreateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301251 } else if (DELETE == pcepTunnelData.requestType()) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001252 pcepTunnelApiMapper.handleRemoveFromTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301253 } else if (UPDATE == pcepTunnelData.requestType()) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301254 pcepTunnelData.setRptFlag(true);
Jonathan Hart51539b82015-10-29 09:53:04 -07001255 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1256 pcepTunnelApiMapper.handleUpdateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301257 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301258
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301259 PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
1260
Avantika-Huawei56c11842016-04-28 00:56:56 +05301261 if (lspObj.getRFlag()) {
1262 tunnelRemoved(td);
1263 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301264 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(pcepLspStatus);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301265 tunnelUpdated(td, tunnelState);
1266 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301267
1268 // SR-TE also needs PCUpd msg after receiving PCRpt with status GOING-UP even
1269 // though there are no labels to download for SR-TE.
1270 if ((pcepLspStatus == PcepLspStatus.GOING_UP)
1271 && (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) == SR_WITHOUT_SIGNALLING)) {
1272 updateTunnel(tunnel, tunnel.path());
1273 }
Avantika-Huawei56c11842016-04-28 00:56:56 +05301274 }
1275
Priyanka B413fbe82016-05-26 11:44:45 +05301276 private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301277 float bandwidth, LspType lspType, String costType) {
1278
1279 Builder builder = DefaultAnnotations.builder();
1280
1281 /*
1282 * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
1283 * for which no constraints need be applied to any of the metrics.
1284 */
1285 if (costType != null) {
1286 builder.set(COST_TYPE, costType);
1287 }
1288
1289 SparseAnnotations annotations = builder
Priyanka B413fbe82016-05-26 11:44:45 +05301290 .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
1291 .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
1292 .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
1293 .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
1294 .set(DELEGATE, String.valueOf(lspObj.getDFlag()))
1295 .build();
1296 return annotations;
1297 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301298
Priyanka B413fbe82016-05-26 11:44:45 +05301299 private LspType getLspType(PcepSrpObject srpObj) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301300 LspType lspType = WITH_SIGNALLING;
1301
1302 if (null != srpObj) {
1303 LinkedList<PcepValueType> llOptionalTlv = srpObj.getOptionalTlv();
1304 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
1305
1306 while (listIterator.hasNext()) {
1307 PcepValueType tlv = listIterator.next();
1308
1309 switch (tlv.getType()) {
1310 case PathSetupTypeTlv.TYPE:
1311 lspType = LspType.values()[Integer.valueOf(((PathSetupTypeTlv) tlv).getPst())];
1312 break;
1313
1314 default:
1315 break;
1316 }
1317 }
1318 }
Priyanka B413fbe82016-05-26 11:44:45 +05301319 return lspType;
1320 }
1321
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301322 private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
Priyanka B413fbe82016-05-26 11:44:45 +05301323 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301324 String costType = null;
Priyanka B413fbe82016-05-26 11:44:45 +05301325 PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
1326 checkNotNull(msgPath);
1327 PcepEroObject eroObj = msgPath.getEroObject();
1328 if (eroObj == null) {
1329 log.error("ERO object is null in report message.");
1330 return;
1331 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301332
1333 PcepAttribute attributes = msgPath.getPcepAttribute();
1334 int cost = 0;
1335 if (attributes != null && attributes.getMetricObjectList() != null) {
1336 ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
1337 PcepMetricObject metricObj = iterator.next();
1338
1339 while (metricObj != null) {
1340 if (metricObj.getBType() == IGP_METRIC) {
1341 costType = "COST";
1342 } else if (metricObj.getBType() == TE_METRIC) {
1343 costType = "TE_COST";
1344 }
1345
1346 if (costType != null) {
1347 cost = metricObj.getMetricVal();
1348 log.debug("Path cost {}", cost);
1349 break;
1350 }
1351 metricObj = iterator.next();
1352 }
1353 }
1354
1355 Path path = buildPathFromEroObj(eroObj, providerId, cost);
Priyanka B413fbe82016-05-26 11:44:45 +05301356
1357 float bandwidth = 0;
1358 if (msgPath.getBandwidthObject() != null) {
1359 bandwidth = msgPath.getBandwidthObject().getBandwidth();
1360 }
1361
1362 /*
1363 * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
1364 * from PCE.
1365 */
1366 PcepSrpObject srpObj = stateRpt.getSrpObject();
1367 LspType lspType = getLspType(srpObj);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301368
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301369 PcepLspObject lspObj = stateRpt.getLspObject();
1370 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1371 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
1372 SymbolicPathNameTlv pathNameTlv = null;
1373
1374 while (listTlvIterator.hasNext()) {
1375 PcepValueType tlv = listTlvIterator.next();
1376 switch (tlv.getType()) {
1377 case StatefulIPv4LspIdentifiersTlv.TYPE:
1378 ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
1379 break;
1380
1381 case SymbolicPathNameTlv.TYPE:
1382 pathNameTlv = (SymbolicPathNameTlv) tlv;
1383 break;
1384
1385 default:
1386 break;
1387 }
1388 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301389 /*
1390 * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
1391 * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
1392 */
1393 if (ipv4LspIdenTlv == null) {
1394 log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
1395 return;
1396 }
1397
1398 IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
1399 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
1400 IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
1401 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
1402 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
1403
Priyanka B413fbe82016-05-26 11:44:45 +05301404 // Store delegation flag info and that LSP info because only delegated PCE sends update message
1405 // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
1406 // not present then non-delegated , if present it is delegated.
1407 if (lspObj.getDFlag()) {
1408 pcepClientController.getClient(pccId).setLspAndDelegationInfo(
1409 new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
1410 }
1411
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301412 Tunnel tunnel = null;
1413 // Asynchronous status change message from PCC for LSP reported earlier.
1414 for (Tunnel tunnelObj : tunnelQueryResult) {
1415 if (tunnelObj.annotations().value(PLSP_ID) == null) {
1416 /*
1417 * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
1418 * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
1419 * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
1420 * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
1421 * session an LSP is "first" reported to a PCE.
1422 */
1423 if ((pathNameTlv != null)
1424 && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
1425 tunnel = tunnelObj;
1426 break;
1427 }
1428 continue;
1429 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301430 if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
1431 .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
1432 tunnel = tunnelObj;
1433 break;
1434 }
1435 }
1436
1437 DefaultTunnelDescription td;
Priyanka B413fbe82016-05-26 11:44:45 +05301438 SparseAnnotations annotations = null;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301439 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
1440 if (tunnel == null) {
1441 if (lspObj.getRFlag()) {
1442 /*
1443 * If PCC sends remove message and for any reason PCE does not have that entry, simply discard the
1444 * message. Or if PCRpt for initiated LSP received and PCE doesn't know, then too discard.
1445 */
1446 return;
1447 }
1448
Priyanka B413fbe82016-05-26 11:44:45 +05301449 DeviceId deviceId = getDevice(pccId);
1450 if (deviceId == null) {
1451 log.error("Ingress deviceId not found");
1452 return;
1453 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301454 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301455
Priyanka B413fbe82016-05-26 11:44:45 +05301456 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
1457 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
1458 annotations);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301459
1460 // Do not support PCC initiated LSP after LSP DB sync is completed.
1461 if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
1462 log.error("Received PCC initiated LSP while not in sync.");
1463 return;
1464 }
1465
Priyanka B413fbe82016-05-26 11:44:45 +05301466 /*
1467 * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
1468 * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
1469 * delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
1470 * wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
1471 * updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
1472 * send update message to that client.
1473 *
1474 * 1)Master can 1st get the Rpt message
1475 * a)Master adds the tunnel into core.
1476 * b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
1477 * after master, then runs timer then update the tunnel with D flag set.
1478 * 2)Non-Master can 1st get the Rpt message
1479 * a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
1480 * b)Master would have got the message while the non-master running timer, hence master adds
1481 * tunnel to core
1482 *
1483 * In general always master adds the tunnel to the core
1484 * while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
1485 */
1486 if (mastershipService.isLocalMaster(deviceId)) {
1487 TunnelId tId = tunnelAdded(td, tunnelState);
1488 Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
1489 tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
1490 .getValue())), path, annotations);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301491
Priyanka B413fbe82016-05-26 11:44:45 +05301492 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
1493 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
1494 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1495 } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
1496 //Start timer then update the tunnel with D flag
1497 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1498 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301499 return;
1500 }
1501
Priyanka B413fbe82016-05-26 11:44:45 +05301502 //delegated owner will update can be a master or non-master
1503 if (lspObj.getDFlag()) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301504 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Priyanka B413fbe82016-05-26 11:44:45 +05301505 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
1506 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
1507 annotations);
1508 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1509 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301510 removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
Priyanka B413fbe82016-05-26 11:44:45 +05301511 return;
1512 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301513
Priyanka B413fbe82016-05-26 11:44:45 +05301514 private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301515 State tunnelState) {
Priyanka B413fbe82016-05-26 11:44:45 +05301516 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
1517 tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
1518 (SparseAnnotations) tunnel.annotations());
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301519 if (lspObj.getRFlag()) {
1520 tunnelRemoved(td);
1521 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301522 tunnelUpdated(td, tunnelState);
1523 }
Priyanka B413fbe82016-05-26 11:44:45 +05301524 }
1525
1526 private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
1527 DefaultTunnelDescription td, ProviderId providerId) {
1528 //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
1529
1530 /*
1531 * If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
1532 * master has added the tunnel to the store] then update the tunnel.
1533 */
1534 ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
1535
1536 // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
1537 executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
1538 executor), DELAY, DELAY, TimeUnit.SECONDS);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301539 }
1540
1541 /**
Avantika-Huawei56c11842016-04-28 00:56:56 +05301542 * To build Path in network from ERO object.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301543 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301544 * @param eroObj ERO object
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301545 * @param providerId provider id
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301546 * @param cost cost of path
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301547 * @return path object
1548 */
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301549 private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId, int cost) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301550 checkNotNull(eroObj);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301551 List<Link> links = new ArrayList<Link>();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301552 LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301553 if (0 == llSubObj.size()) {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301554 log.error("ERO in report message does not have hop information");
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301555 }
1556 ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
1557
1558 ConnectPoint src = null;
1559 ConnectPoint dst = null;
1560 boolean isSrcSet = false;
1561 while (tlvIterator.hasNext()) {
1562 PcepValueType subObj = tlvIterator.next();
1563 switch (subObj.getType()) {
1564
1565 case IPv4SubObject.TYPE:
1566
1567 IPv4SubObject ipv4SubObj = (IPv4SubObject) subObj;
1568 if (!isSrcSet) {
1569 IpAddress srcIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1570 src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
1571 isSrcSet = true;
1572 } else {
1573 IpAddress dstIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1574 dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
Ray Milkey2693bda2016-01-22 16:08:14 -08001575 Link link = DefaultLink.builder()
1576 .providerId(providerId)
1577 .src(src)
1578 .dst(dst)
1579 .type(Link.Type.DIRECT)
1580 .build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301581 links.add(link);
1582 src = dst;
1583 }
1584 break;
1585 default:
1586 // the other sub objects are not required
1587 }
1588 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301589
1590 return new DefaultPath(providerId, links, cost, EMPTY);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301591 }
1592
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301593 @Override
1594 public void clientConnected(PccId pccId) {
1595 // TODO
1596 }
1597
1598 @Override
1599 public void clientDisconnected(PccId pccId) {
1600 // TODO
cheng fan48e832c2015-05-29 01:54:47 +08001601 }
chengfan2fff70f2015-08-24 18:20:19 -05001602
chengfan2fff70f2015-08-24 18:20:19 -05001603 @Override
1604 public void handlePcepTunnelStatistics(PcepTunnelStatistics pcepTunnelStatistics) {
1605 TunnelId id = getTunnelId(String.valueOf(pcepTunnelStatistics.id()));
1606 TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
1607 tunnelStatisticsMap.put(id, tunnelStatistics);
1608 }
cheng fan48e832c2015-05-29 01:54:47 +08001609
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301610 @Override
1611 public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301612
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301613 if (endOfSyncAction == SEND_UPDATE) {
1614 updateTunnel(tunnel, tunnel.path());
1615 return;
1616 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301617
1618 TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
1619 tunnel.src(), tunnel.dst(),
1620 tunnel.type(),
1621 tunnel.groupId(),
1622 tunnel.providerId(),
1623 tunnel.tunnelName(),
1624 tunnel.path(),
1625 (SparseAnnotations) tunnel.annotations());
1626
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301627
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301628 if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
1629
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301630 // Send PCInit msg again after global reoptimization.
1631 tunnelUpdated(td, UNSTABLE);
1632
1633 // To remove the old tunnel from store whose PLSPID is not
1634 // recognized by ingress PCC.
1635 tunnelRemoved(td);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301636
1637 } else if (endOfSyncAction == REMOVE) {
1638 tunnelRemoved(td);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301639 }
1640 }
1641
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301642 @Override
1643 public void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction) {
1644 try {
1645 if ((msg instanceof PcepInitiateMsg) && (endOfSyncAction == SEND_DELETE)) {
1646 PcepClient pc = pcepClientController.getClient(pccId);
1647 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = ((PcepInitiateMsg) msg)
1648 .getPcInitiatedLspRequestList();
1649 PcInitiatedLspRequest pcInitMsg = llPcInitiatedLspRequestList.iterator().next();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301650
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301651 if (pcInitMsg != null) {
1652 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
1653 .setRFlag(true).build();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301654
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301655 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
1656 .setLspObject(pcInitMsg.getLspObject()).setSrpObject(srpobj).build();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301657
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301658 llPcInitiatedLspRequestList.remove(pcInitMsg);
1659 llPcInitiatedLspRequestList.add(releaseLspRequest);
1660
1661 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1662 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1663
1664 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1665 }
1666 }
1667 } catch (PcepParseException e) {
1668 log.error("Exception occured while sending initiate delete message {}", e.getMessage());
1669 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301670 }
1671 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301672 @Override
1673 public Tunnel tunnelQueryById(TunnelId tunnelId) {
1674 return service.tunnelQueryById(tunnelId);
1675 }
1676
Priyanka B413fbe82016-05-26 11:44:45 +05301677
1678 private DeviceId getDevice(PccId pccId) {
1679 // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
1680 IpAddress lsrId = pccId.ipAddress();
1681 String lsrIdentifier = String.valueOf(lsrId);
1682
1683 // Find PCC deviceID from lsrId stored as annotations
1684 Iterable<Device> devices = deviceService.getAvailableDevices();
1685 for (Device dev : devices) {
1686 if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
1687 && dev.annotations().value(LSRID).equals(lsrIdentifier)) {
1688 return dev.id();
1689 }
1690 }
1691 return null;
1692 }
1693
1694 /**
1695 * Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
1696 * tunnel is found.
1697 */
1698 private class UpdateDelegation implements Runnable {
1699 DefaultTunnelDescription td;
1700 ProviderId providerId;
1701 SparseAnnotations annotations;
1702 PccId pccId;
1703 ScheduledExecutorService executor;
1704
1705 /**
1706 * Creates an instance of UpdateDelegation.
1707 *
1708 * @param td tunnel description
1709 * @param providerId provider id
1710 * @param annotations tunnel annotations
1711 * @param pccId PCEP client id
1712 * @param executor service of delegated owner
1713 */
1714 public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
1715 PccId pccId, ScheduledExecutorService executor) {
1716 this.td = td;
1717 this.providerId = providerId;
1718 this.annotations = annotations;
1719 this.pccId = pccId;
1720 this.executor = executor;
1721 }
1722
1723 //Temporary using annotations later will use projection/network config service
1724 @Override
1725 public void run() {
1726 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
1727 TunnelId tempTunnelId = null;
1728 for (Tunnel t : tunnelQueryResult) {
1729 if (t.annotations().value(LOCAL_LSP_ID) == null || t.annotations().value(PLSP_ID) == null) {
1730 continue;
1731 }
1732
1733 if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
1734 && t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
1735 && ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
1736 tempTunnelId = t.tunnelId();
1737 break;
1738 }
1739 }
1740
1741 //If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
1742 //periodically
1743 if (tempTunnelId != null) {
1744 Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
1745 tempTunnelId, td.tunnelName(), td.path(), annotations);
1746 tunnelUpdated(tunnel, td.path());
1747 executor.shutdown();
1748 try {
1749 executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
1750 } catch (InterruptedException e) {
1751 log.error("updating delegation failed");
1752 }
1753 }
1754 }
1755 }
cheng fan48e832c2015-05-29 01:54:47 +08001756}