blob: 7af0040d803f4242dd4ffffad13692b83236fc89 [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;
MaheshRaju-Huaweibb591072016-06-17 17:47:16 +053086import org.onosproject.pcep.controller.PcepSyncStatus;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053087import org.onosproject.pcepio.exceptions.PcepParseException;
88import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
89import org.onosproject.pcepio.protocol.PcepAttribute;
90import org.onosproject.pcepio.protocol.PcepBandwidthObject;
91import org.onosproject.pcepio.protocol.PcepEndPointsObject;
92import org.onosproject.pcepio.protocol.PcepEroObject;
93import org.onosproject.pcepio.protocol.PcepInitiateMsg;
94import org.onosproject.pcepio.protocol.PcepLspObject;
95import org.onosproject.pcepio.protocol.PcepMessage;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053096import org.onosproject.pcepio.protocol.PcepMetricObject;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053097import org.onosproject.pcepio.protocol.PcepMsgPath;
98import org.onosproject.pcepio.protocol.PcepReportMsg;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053099import org.onosproject.pcepio.protocol.PcepSrpObject;
100import org.onosproject.pcepio.protocol.PcepStateReport;
101import org.onosproject.pcepio.protocol.PcepUpdateMsg;
102import org.onosproject.pcepio.protocol.PcepUpdateRequest;
103import org.onosproject.pcepio.types.IPv4SubObject;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530104import org.onosproject.pcepio.types.PathSetupTypeTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530105import org.onosproject.pcepio.types.PcepValueType;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530106import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530107import org.onosproject.pcepio.types.SymbolicPathNameTlv;
chengfan2fff70f2015-08-24 18:20:19 -0500108import org.osgi.service.component.ComponentContext;
Jonathan Hart51539b82015-10-29 09:53:04 -0700109import org.osgi.service.component.annotations.Modified;
110import org.slf4j.Logger;
111
112import java.util.ArrayList;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530113import java.util.Arrays;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530114import java.util.Collection;
Jonathan Hart51539b82015-10-29 09:53:04 -0700115import java.util.Collections;
116import java.util.Dictionary;
117import java.util.HashMap;
118import java.util.LinkedList;
119import java.util.List;
120import java.util.ListIterator;
121import java.util.Optional;
Priyanka B413fbe82016-05-26 11:44:45 +0530122import java.util.concurrent.Executors;
123import java.util.concurrent.ScheduledExecutorService;
124import java.util.concurrent.TimeUnit;
Jonathan Hart51539b82015-10-29 09:53:04 -0700125
126import static com.google.common.base.Preconditions.checkNotNull;
127import static com.google.common.base.Strings.isNullOrEmpty;
128import static org.onlab.util.Tools.get;
Priyanka B4c3cef02016-06-14 20:27:53 +0530129import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530130import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
Jonathan Hart51539b82015-10-29 09:53:04 -0700131import static org.onosproject.net.DefaultAnnotations.EMPTY;
132import static org.onosproject.net.DeviceId.deviceId;
133import static org.onosproject.net.PortNumber.portNumber;
134import static org.onosproject.pcep.api.PcepDpid.uri;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530135import static org.onosproject.provider.pcep.tunnel.impl.LspType.WITH_SIGNALLING;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530136import static org.onosproject.provider.pcep.tunnel.impl.LspType.SR_WITHOUT_SIGNALLING;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530137import static org.onosproject.pcep.controller.PcepAnnotationKeys.BANDWIDTH;
138import static org.onosproject.pcep.controller.PcepAnnotationKeys.LOCAL_LSP_ID;
139import static org.onosproject.pcep.controller.PcepAnnotationKeys.LSP_SIG_TYPE;
140import static org.onosproject.pcep.controller.PcepAnnotationKeys.PCC_TUNNEL_ID;
Priyanka B4c3cef02016-06-14 20:27:53 +0530141import static org.onosproject.pcep.controller.PcepAnnotationKeys.PCE_INIT;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530142import static org.onosproject.pcep.controller.PcepAnnotationKeys.PLSP_ID;
143import static org.onosproject.pcep.controller.PcepAnnotationKeys.DELEGATE;
144import static org.onosproject.pcep.controller.PcepAnnotationKeys.COST_TYPE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530145import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
146import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
147import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
148import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530149import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530150import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
151import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
152import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_DELETE;
153import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
154import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
Jonathan Hart51539b82015-10-29 09:53:04 -0700155import static org.slf4j.LoggerFactory.getLogger;
cheng fan48e832c2015-05-29 01:54:47 +0800156
157/**
158 * Provider which uses an PCEP controller to detect, update, create network
159 * tunnels.
160 */
161@Component(immediate = true)
162@Service
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530163public class PcepTunnelProvider extends AbstractProvider implements TunnelProvider {
cheng fan48e832c2015-05-29 01:54:47 +0800164
165 private static final Logger log = getLogger(PcepTunnelProvider.class);
166 private static final long MAX_BANDWIDTH = 99999744;
167 private static final long MIN_BANDWIDTH = 64;
cheng fan7716ec92015-05-31 01:53:19 +0800168 private static final String BANDWIDTH_UINT = "kbps";
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530169 static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
Priyanka B413fbe82016-05-26 11:44:45 +0530170 public static final long IDENTIFIER_SET = 0x100000000L;
171 public static final long SET = 0xFFFFFFFFL;
172 private static final int DELAY = 2;
173 private static final int WAIT_TIME = 5;
174 public static final String LSRID = "lsrId";
cheng fan48e832c2015-05-29 01:54:47 +0800175
chengfan2fff70f2015-08-24 18:20:19 -0500176 static final int POLL_INTERVAL = 10;
177 @Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
178 label = "Frequency (in seconds) for polling tunnel statistics")
179 private int tunnelStatsPollFrequency = POLL_INTERVAL;
180
cheng fan48e832c2015-05-29 01:54:47 +0800181 private static final String TUNNLE_NOT_NULL = "Create failed,The given port may be wrong or has been occupied.";
182
183 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
184 protected TunnelProviderRegistry tunnelProviderRegistry;
185
186 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
187 protected PcepController controller;
188
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530189 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
190 protected PcepClientController pcepClientController;
chengfan2fff70f2015-08-24 18:20:19 -0500191
192 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
193 protected TunnelService tunnelService;
194
195 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
196 protected ComponentConfigService cfgService;
197
Priyanka B413fbe82016-05-26 11:44:45 +0530198 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
199 protected TunnelAdminService tunnelAdminService;
200
201 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
202 protected MastershipService mastershipService;
203
204 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
205 protected DeviceService deviceService;
206
cheng fan48e832c2015-05-29 01:54:47 +0800207 TunnelProviderService service;
208
209 HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
chengfan2fff70f2015-08-24 18:20:19 -0500210 HashMap<TunnelId, TunnelStatistics> tunnelStatisticsMap = new HashMap<>();
Brian Stanke9a108972016-04-11 15:25:17 -0400211 private HashMap<String, TunnelStatsCollector> collectors = Maps.newHashMap();
cheng fan48e832c2015-05-29 01:54:47 +0800212
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530213 private InnerTunnelProvider listener = new InnerTunnelProvider();
214
Jonathan Hart51539b82015-10-29 09:53:04 -0700215 protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530216 private static final int DEFAULT_BANDWIDTH_VALUE = 10;
cheng fan48e832c2015-05-29 01:54:47 +0800217
218 /**
219 * Creates a Tunnel provider.
220 */
221 public PcepTunnelProvider() {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530222 super(new ProviderId("pcep", PROVIDER_ID));
cheng fan48e832c2015-05-29 01:54:47 +0800223 }
224
225 @Activate
226 public void activate() {
chengfan2fff70f2015-08-24 18:20:19 -0500227 cfgService.registerProperties(getClass());
cheng fan48e832c2015-05-29 01:54:47 +0800228 service = tunnelProviderRegistry.register(this);
229 controller.addTunnelListener(listener);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530230 pcepClientController.addListener(listener);
231 pcepClientController.addEventListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500232 tunnelService.queryAllTunnels().forEach(tunnel -> {
Jonathan Hart51539b82015-10-29 09:53:04 -0700233 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
chengfan2fff70f2015-08-24 18:20:19 -0500234 TunnelStatsCollector tsc = new TunnelStatsCollector(pcepTunnelId, tunnelStatsPollFrequency);
235 tsc.start();
236 collectors.put(tunnel.tunnelId().id(), tsc);
237
238 });
239
cheng fan48e832c2015-05-29 01:54:47 +0800240 log.info("Started");
241 }
242
243 @Deactivate
244 public void deactivate() {
245 tunnelProviderRegistry.unregister(this);
246 controller.removeTunnelListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500247 collectors.values().forEach(TunnelStatsCollector::stop);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530248 pcepClientController.removeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800249 log.info("Stopped");
250 }
251
chengfan2fff70f2015-08-24 18:20:19 -0500252 @Modified
253 public void modified(ComponentContext context) {
254 Dictionary<?, ?> properties = context.getProperties();
255 int newTunnelStatsPollFrequency;
256 try {
257 String s = get(properties, "tunnelStatsPollFrequency");
258 newTunnelStatsPollFrequency = isNullOrEmpty(s) ? tunnelStatsPollFrequency : Integer.parseInt(s.trim());
259
260 } catch (NumberFormatException | ClassCastException e) {
261 newTunnelStatsPollFrequency = tunnelStatsPollFrequency;
262 }
263
264 if (newTunnelStatsPollFrequency != tunnelStatsPollFrequency) {
265 tunnelStatsPollFrequency = newTunnelStatsPollFrequency;
266 collectors.values().forEach(tsc -> tsc.adjustPollInterval(tunnelStatsPollFrequency));
267 log.info("New setting: tunnelStatsPollFrequency={}", tunnelStatsPollFrequency);
268 }
269
270 }
271
cheng fan48e832c2015-05-29 01:54:47 +0800272 @Override
273 public void setupTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530274 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530275 log.error("Tunnel Type MPLS is only supported");
276 return;
277 }
cheng fan48e832c2015-05-29 01:54:47 +0800278
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530279 // check for tunnel end points
280 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
281 log.error("Tunnel source or destination is not valid");
282 return;
283 }
284
285 // Get the pcc client
286 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
287
288 if (!(pc instanceof PcepClient)) {
289 log.error("There is no PCC connected with ip addresss {}"
chengfan2fff70f2015-08-24 18:20:19 -0500290 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530291 return;
292 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530293
294 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
Priyanka B413fbe82016-05-26 11:44:45 +0530295 //Only master will initiate setup tunnel
296 if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530297 pcepSetupTunnel(tunnel, path, pc);
298 }
cheng fan48e832c2015-05-29 01:54:47 +0800299 }
300
301 @Override
302 public void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800303
Priyanka B4c3cef02016-06-14 20:27:53 +0530304 //TODO: tunnel which is passed doesn't have tunnelID
Avantika-Huawei56c11842016-04-28 00:56:56 +0530305 if (tunnel.annotations().value(PLSP_ID) != null) {
306 updateTunnel(tunnel, path);
307 return;
308 }
309
310 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530311 log.error("Tunnel Type MPLS is only supported");
312 return;
313 }
314
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530315 // check for tunnel end points
316 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
317 log.error("Tunnel source or destination is not valid");
318 return;
319 }
320
Priyanka Bcdf9b102016-06-07 20:01:38 +0530321 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530322
323 if (!(pc instanceof PcepClient)) {
Priyanka B4c3cef02016-06-14 20:27:53 +0530324 log.error("There is no PCC connected with this device {}"
325 + srcElement.toString());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530326 return;
327 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530328
Priyanka B413fbe82016-05-26 11:44:45 +0530329 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
330 //Only master will initiate setup tunnel
331 if (pc.capability().pcInstantiationCapability()
332 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530333 pcepSetupTunnel(tunnel, path, pc);
334 }
cheng fan48e832c2015-05-29 01:54:47 +0800335 }
336
337 @Override
338 public void releaseTunnel(Tunnel tunnel) {
cheng fan48e832c2015-05-29 01:54:47 +0800339
Avantika-Huawei56c11842016-04-28 00:56:56 +0530340 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530341 log.error("Tunnel Type MPLS is only supported");
342 return;
343 }
344
345 // check for tunnel end points
346 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
347 log.error("Tunnel source or destination is not valid");
348 return;
349 }
350
351 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
352
353 if (!(pc instanceof PcepClient)) {
354 log.error("There is no PCC connected with ip addresss {}"
355 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
356 return;
357 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530358
Priyanka B413fbe82016-05-26 11:44:45 +0530359 //Only master will release tunnel
360 if (pc.capability().pcInstantiationCapability()
361 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530362 pcepReleaseTunnel(tunnel, pc);
363 }
cheng fan48e832c2015-05-29 01:54:47 +0800364 }
365
366 @Override
367 public void releaseTunnel(ElementId srcElement, Tunnel tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530368 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530369 log.error("Tunnel Type MPLS is only supported");
370 return;
371 }
cheng fan48e832c2015-05-29 01:54:47 +0800372
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530373 if (!(srcElement instanceof IpElementId)) {
374 log.error("Element id is not valid");
375 return;
376 }
377
378 // check for tunnel end points
379 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
380 log.error("Tunnel source or destination is not valid");
381 return;
382 }
383
384 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
385
386 if (!(pc instanceof PcepClient)) {
387 log.error("There is no PCC connected with ip addresss {}"
388 + ((IpElementId) srcElement).ipAddress().toString());
389 return;
390 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530391
Priyanka B413fbe82016-05-26 11:44:45 +0530392 //Only master will release tunnel
393 if (pc.capability().pcInstantiationCapability()
394 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530395 pcepReleaseTunnel(tunnel, pc);
396 }
cheng fan48e832c2015-05-29 01:54:47 +0800397 }
398
399 @Override
400 public void updateTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530401 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530402 log.error("Tunnel Type MPLS is only supported");
403 return;
404 }
cheng fan48e832c2015-05-29 01:54:47 +0800405
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530406 // check for tunnel end points
407 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
408 log.error("Tunnel source or destination is not valid");
409 return;
410 }
411
Priyanka B4c3cef02016-06-14 20:27:53 +0530412 //To get new tunnel ID (modified tunnel ID)
413 Collection<Tunnel> tunnels = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
414 for (Tunnel t : tunnels) {
415 if (t.state().equals(INIT) && t.tunnelName().equals(tunnel.tunnelName())) {
416 tunnel = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
417 tunnel.dst(), tunnel.type(),
418 t.state(), tunnel.groupId(),
419 t.tunnelId(),
420 tunnel.tunnelName(),
421 tunnel.path(),
422 tunnel.resource(),
423 tunnel.annotations());
424 break;
425 }
426 }
427
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530428 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
429
430 if (!(pc instanceof PcepClient)) {
431 log.error("There is no PCC connected with ip addresss {}"
432 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
433 return;
434 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530435
Priyanka B413fbe82016-05-26 11:44:45 +0530436 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
437 // LSP].If annotation is null D flag is not set else it is set.
Priyanka B4c3cef02016-06-14 20:27:53 +0530438 Short localLspId = 0;
439 for (Tunnel t : tunnels) {
440 if (!t.tunnelId().equals(tunnel.tunnelId()) && t.tunnelName().equals(tunnel.tunnelName())) {
441 localLspId = Short.valueOf(t.annotations().value(LOCAL_LSP_ID));
442 }
443 }
444
445 if (localLspId == 0) {
446 log.error("Local LSP ID for old tunnel not found");
447 return;
448 }
449
450 //PCInitiate tunnels are always have D flag set, else check for tunnels who are delegated via LspKey
451 if (pc.capability().statefulPceCapability()) {
452 if (tunnel.annotations().value(PCE_INIT) != null && tunnel.annotations().value(PCE_INIT).equals("true")) {
453 pcepUpdateTunnel(tunnel, path, pc);
454 } else if (pc.delegationInfo(
455 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)),
456 localLspId.shortValue())) != null) {
457 pcepUpdateTunnel(tunnel, path, pc);
458 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530459 }
cheng fan48e832c2015-05-29 01:54:47 +0800460 }
461
462 @Override
463 public void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800464
Avantika-Huawei56c11842016-04-28 00:56:56 +0530465 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530466 log.error("Tunnel Type MPLS is only supported");
467 return;
468 }
469
470 if (!(srcElement instanceof IpElementId)) {
471 log.error("Element id is not valid");
472 return;
473 }
474
475 // check for tunnel end points
476 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
477 log.error("Tunnel source or destination is not valid");
478 return;
479 }
480
481 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
482
483 if (!(pc instanceof PcepClient)) {
484 log.error("There is no PCC connected with ip addresss {}"
485 + ((IpElementId) srcElement).ipAddress().toString());
486 return;
487 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530488
Priyanka B413fbe82016-05-26 11:44:45 +0530489 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
490 // LSP].If annotation is null D flag is not set else it is set.
491 if (pc.capability().statefulPceCapability()
492 && pc.delegationInfo(
493 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
494 .annotations().value(LOCAL_LSP_ID)))) != null) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530495 pcepUpdateTunnel(tunnel, path, pc);
496 }
cheng fan48e832c2015-05-29 01:54:47 +0800497 }
498
499 @Override
500 public TunnelId tunnelAdded(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530501 return handleTunnelAdded(tunnel, null);
502 }
503
504 public TunnelId tunnelAdded(TunnelDescription tunnel, State tunnelState) {
505 return handleTunnelAdded(tunnel, tunnelState);
506 }
507
508 private TunnelId handleTunnelAdded(TunnelDescription tunnel, State tunnelState) {
509
510 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700511 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530512
513 if (tunnelState == null) {
514 return service.tunnelAdded(tunnel);
515 } else {
516 return service.tunnelAdded(tunnel, tunnelState);
517 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530518 }
cheng fan48e832c2015-05-29 01:54:47 +0800519
Avantika-Huawei56c11842016-04-28 00:56:56 +0530520 long bandwidth = Long.parseLong(tunnel.annotations().value(BANDWIDTH));
cheng fan48e832c2015-05-29 01:54:47 +0800521
522 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800523 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800524 return null;
525 }
526
527 // endpoints
528 OpticalTunnelEndPoint src = (org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint) tunnel
529 .src();
530 OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst();
531 // devices
532 DeviceId srcId = (DeviceId) src.elementId().get();
533 DeviceId dstId = (DeviceId) dst.elementId().get();
534
535 // ports
536 long srcPort = src.portNumber().get().toLong();
537 long dstPort = dst.portNumber().get().toLong();
538
539 // type
540 if (tunnel.type() != Tunnel.Type.VLAN) {
cheng fan7716ec92015-05-31 01:53:19 +0800541 error("Illegal tunnel type. Only support VLAN tunnel creation.");
cheng fan48e832c2015-05-29 01:54:47 +0800542 return null;
543 }
544
545 PcepTunnel pcepTunnel = controller.applyTunnel(srcId, dstId, srcPort,
546 dstPort, bandwidth,
547 tunnel.tunnelName()
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530548 .value());
cheng fan48e832c2015-05-29 01:54:47 +0800549
550 checkNotNull(pcepTunnel, TUNNLE_NOT_NULL);
551 TunnelDescription tunnelAdded = buildOpticalTunnel(pcepTunnel, null);
552 TunnelId tunnelId = service.tunnelAdded(tunnelAdded);
553
554 tunnelMap.put(String.valueOf(pcepTunnel.id()), tunnelId);
555 return tunnelId;
556 }
557
Priyanka B413fbe82016-05-26 11:44:45 +0530558 private void tunnelUpdated(Tunnel tunnel, Path path) {
559 handleTunnelUpdate(tunnel, path);
560 }
561
562 //Handles tunnel updated using tunnel admin service[specially to update annotations].
563 private void handleTunnelUpdate(Tunnel tunnel, Path path) {
564
565 if (tunnel.type() == MPLS) {
566 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
567
568 tunnelAdminService.updateTunnel(tunnel, path);
569
570 return;
571 }
572
573 Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
574 if (tunnelOld.type() != Tunnel.Type.VLAN) {
575 error("Illegal tunnel type. Only support VLAN tunnel update.");
576 return;
577 }
578
579 long bandwidth = Long
580 .parseLong(tunnel.annotations().value("bandwidth"));
581 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
582 error("Update failed, invalid bandwidth.");
583 return;
584 }
585 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
586
587 checkNotNull(pcepTunnelId, "Invalid tunnel id");
588 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
589 error("Update failed,maybe invalid bandwidth.");
590 return;
591 }
592 tunnelAdminService.updateTunnel(tunnel, path);
593 }
594
cheng fan48e832c2015-05-29 01:54:47 +0800595 @Override
596 public void tunnelRemoved(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530597 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700598 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530599 service.tunnelRemoved(tunnel);
600 }
601
cheng fan48e832c2015-05-29 01:54:47 +0800602 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
603 checkNotNull(tunnelOld, "The tunnel id is not exsited.");
604 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800605 error("Illegal tunnel type. Only support VLAN tunnel deletion.");
cheng fan48e832c2015-05-29 01:54:47 +0800606 return;
607 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700608 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800609 checkNotNull(pcepTunnelId, "The tunnel id is not exsited.");
cheng fan7716ec92015-05-31 01:53:19 +0800610 if (!controller.deleteTunnel(pcepTunnelId)) {
611 error("Delete tunnel failed, Maybe some devices have been disconnected.");
612 return;
cheng fan48e832c2015-05-29 01:54:47 +0800613 }
614 tunnelMap.remove(pcepTunnelId);
615 service.tunnelRemoved(tunnel);
cheng fan48e832c2015-05-29 01:54:47 +0800616 }
617
618 @Override
619 public void tunnelUpdated(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530620 handleTunnelUpdate(tunnel, null);
621 }
622
623 public void tunnelUpdated(TunnelDescription tunnel, State tunnelState) {
624 handleTunnelUpdate(tunnel, tunnelState);
625 }
626
627 private void handleTunnelUpdate(TunnelDescription tunnel, State tunnelState) {
628 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700629 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530630
631 if (tunnelState == null) {
632 service.tunnelUpdated(tunnel);
633 } else {
634 service.tunnelUpdated(tunnel, tunnelState);
635 }
636 return;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530637 }
cheng fan48e832c2015-05-29 01:54:47 +0800638
639 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
640 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800641 error("Illegal tunnel type. Only support VLAN tunnel update.");
cheng fan48e832c2015-05-29 01:54:47 +0800642 return;
643 }
cheng fan7716ec92015-05-31 01:53:19 +0800644 long bandwidth = Long
645 .parseLong(tunnel.annotations().value("bandwidth"));
cheng fan48e832c2015-05-29 01:54:47 +0800646 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800647 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800648 return;
649 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700650 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800651
652 checkNotNull(pcepTunnelId, "Invalid tunnel id");
653 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
654
cheng fan7716ec92015-05-31 01:53:19 +0800655 error("Update failed,maybe invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800656 return;
657
658 }
659 service.tunnelUpdated(tunnel);
660 }
661
cheng fan7716ec92015-05-31 01:53:19 +0800662 private void error(String info) {
663 System.err.println(info);
664 }
665
cheng fan48e832c2015-05-29 01:54:47 +0800666 // Short-hand for creating a connection point.
667 private ConnectPoint connectPoint(PcepDpid id, long port) {
668 return new ConnectPoint(deviceId(uri(id)), portNumber(port));
669 }
670
671 // Short-hand for creating a link.
672 private Link link(PcepDpid src, long sp, PcepDpid dst, long dp) {
Ray Milkey2693bda2016-01-22 16:08:14 -0800673 return DefaultLink.builder()
674 .providerId(id())
675 .src(connectPoint(src, sp))
676 .dst(connectPoint(dst, dp))
677 .type(Link.Type.TUNNEL)
678 .build();
cheng fan48e832c2015-05-29 01:54:47 +0800679 }
680
681 // Creates a path that leads through the given devices.
682 private Path createPath(List<PcepHopNodeDescription> hopList,
Jonathan Hart51539b82015-10-29 09:53:04 -0700683 PathType pathtype, PathState pathState) {
cheng fan48e832c2015-05-29 01:54:47 +0800684 if (hopList == null || hopList.size() == 0) {
685 return null;
686 }
687 List<Link> links = new ArrayList<>();
688 for (int i = 1; i < hopList.size() - 1; i = i + 2) {
689 links.add(link(hopList.get(i).getDeviceId(), hopList.get(i)
690 .getPortNum(), hopList.get(i + 1).getDeviceId(), hopList
691 .get(i + 1).getPortNum()));
692 }
693
694 int hopNum = hopList.size() - 2;
695 DefaultAnnotations extendAnnotations = DefaultAnnotations.builder()
696 .set("pathNum", String.valueOf(hopNum))
cheng fan93258c72015-06-02 23:42:32 +0800697 .set("pathState", String.valueOf(pathState))
cheng fan48e832c2015-05-29 01:54:47 +0800698 .set("pathType", String.valueOf(pathtype)).build();
699 return new DefaultPath(id(), links, hopNum, extendAnnotations);
700 }
701
702 // convert the path description to a string.
703 public String pathToString(List<Link> links) {
704 StringBuilder builder = new StringBuilder();
705 builder.append("{");
706 for (Link link : links) {
707 builder.append("(Device:" + link.src().deviceId() + " Port:"
708 + link.src().port().toLong());
709 builder.append(" Device:" + link.dst().deviceId() + " Port:"
710 + link.dst().port().toLong());
711 builder.append(")");
712 }
713 builder.append("}");
714 return builder.toString();
715 }
716
717 // build a TunnelDescription.
718 private TunnelDescription buildOpticalTunnel(PcepTunnel pcepTunnel,
719 TunnelId tunnelId) {
720 TunnelEndPoint srcPoint = null;
721 TunnelEndPoint dstPoint = null;
722 Tunnel.Type tunnelType = null;
723 TunnelName name = TunnelName.tunnelName(pcepTunnel.name());
724
725 // add path after codes of tunnel's path merged
726 Path path = createPath(pcepTunnel.getHopList(),
cheng fan93258c72015-06-02 23:42:32 +0800727 pcepTunnel.getPathType(),
728 pcepTunnel.getPathState());
cheng fan48e832c2015-05-29 01:54:47 +0800729
730 OpticalTunnelEndPoint.Type endPointType = null;
731 switch (pcepTunnel.type()) {
732 case OCH:
733 tunnelType = Tunnel.Type.OCH;
734 endPointType = OpticalTunnelEndPoint.Type.LAMBDA;
735 break;
736
737 case OTN:
738 tunnelType = Tunnel.Type.ODUK;
739 endPointType = OpticalTunnelEndPoint.Type.TIMESLOT;
740 break;
741
742 case UNI:
743 tunnelType = Tunnel.Type.VLAN;
744 endPointType = null;
745 break;
746
747 default:
748 break;
749 }
750 DeviceId srcDid = deviceId(uri(pcepTunnel.srcDeviceID()));
751 DeviceId dstDid = deviceId(uri(pcepTunnel.dstDeviceId()));
752 PortNumber srcPort = PortNumber.portNumber(pcepTunnel.srcPort());
753 PortNumber dstPort = PortNumber.portNumber(pcepTunnel.dstPort());
754
755 srcPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(srcDid),
756 Optional.of(srcPort), null,
757 endPointType,
758 OpticalLogicId.logicId(0),
759 true);
760 dstPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(dstDid),
761 Optional.of(dstPort), null,
762 endPointType,
763 OpticalLogicId.logicId(0),
764 true);
765
766 // basic annotations
cheng fan7716ec92015-05-31 01:53:19 +0800767 DefaultAnnotations annotations = DefaultAnnotations
768 .builder()
cheng fan48e832c2015-05-29 01:54:47 +0800769 .set("SLA", String.valueOf(pcepTunnel.getSla()))
cheng fan7716ec92015-05-31 01:53:19 +0800770 .set("bandwidth",
771 String.valueOf(pcepTunnel.bandWidth()) + BANDWIDTH_UINT)
cheng fan48e832c2015-05-29 01:54:47 +0800772 .set("index", String.valueOf(pcepTunnel.id())).build();
773
cheng fan48e832c2015-05-29 01:54:47 +0800774 // a VLAN tunnel always carry OCH tunnel, this annotation is the index
775 // of a OCH tunnel.
cheng fan93258c72015-06-02 23:42:32 +0800776 if (pcepTunnel.underlayTunnelId() != 0) {
cheng fan48e832c2015-05-29 01:54:47 +0800777 DefaultAnnotations extendAnnotations = DefaultAnnotations
778 .builder()
779 .set("underLayTunnelIndex",
cheng fan93258c72015-06-02 23:42:32 +0800780 String.valueOf(pcepTunnel.underlayTunnelId())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800781 annotations = DefaultAnnotations.merge(annotations,
782 extendAnnotations);
783
784 }
785 TunnelDescription tunnel = new DefaultTunnelDescription(
786 tunnelId,
787 srcPoint,
788 dstPoint,
789 tunnelType,
790 new DefaultGroupId(
791 0),
792 id(), name,
793 path,
794 annotations);
795 return tunnel;
cheng fan48e832c2015-05-29 01:54:47 +0800796 }
797
798 /**
799 * Get the tunnelID according to the tunnel key.
800 *
801 * @param tunnelKey tunnel key
802 * @return corresponding tunnel id of the a tunnel key.
803 */
804 private TunnelId getTunnelId(String tunnelKey) {
cheng fan48e832c2015-05-29 01:54:47 +0800805 for (String key : tunnelMap.keySet()) {
806 if (key.equals(tunnelKey)) {
807 return tunnelMap.get(key);
808 }
809 }
810 return null;
811 }
812
813 /**
814 * Get the tunnel key according to the tunnelID.
815 *
816 * @param tunnelId tunnel id
817 * @return corresponding a tunnel key of the tunnel id.
818 */
Jonathan Hart51539b82015-10-29 09:53:04 -0700819 private String getPcepTunnelKey(TunnelId tunnelId) {
cheng fan48e832c2015-05-29 01:54:47 +0800820 for (String key : tunnelMap.keySet()) {
821 if (tunnelMap.get(key).id() == tunnelId.id()) {
822 return key;
823 }
824 }
825 return null;
826
827 }
828
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530829 /**
chengfan2fff70f2015-08-24 18:20:19 -0500830 * Build a DefaultTunnelStatistics from a PcepTunnelStatistics.
831 *
832 * @param statistics statistics data from a PCEP tunnel
833 * @return TunnelStatistics
834 */
835 private TunnelStatistics buildTunnelStatistics(PcepTunnelStatistics statistics) {
836 DefaultTunnelStatistics.Builder builder = new DefaultTunnelStatistics.Builder();
837 DefaultTunnelStatistics tunnelStatistics = builder.setBwUtilization(statistics.bandwidthUtilization())
838 .setPacketLossRatio(statistics.packetLossRate())
839 .setFlowDelay(statistics.flowDelay())
840 .setAlarms(statistics.alarms())
841 .build();
842 return tunnelStatistics;
843 }
844 /**
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530845 * Creates list of hops for ERO object from Path.
846 *
847 * @param path network path
848 * @return list of ipv4 subobjects
849 */
850 private LinkedList<PcepValueType> createPcepPath(Path path) {
851 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
852 List<Link> listLink = path.links();
853 ConnectPoint source = null;
854 ConnectPoint destination = null;
855 IpAddress ipDstAddress = null;
856 IpAddress ipSrcAddress = null;
857 PcepValueType subObj = null;
Priyanka Bcdf9b102016-06-07 20:01:38 +0530858 long portNo;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530859
860 for (Link link : listLink) {
861 source = link.src();
862 if (!(source.equals(destination))) {
863 //set IPv4SubObject for ERO object
Priyanka Bcdf9b102016-06-07 20:01:38 +0530864 portNo = source.port().toLong();
865 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
866 ipSrcAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530867 subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
868 llSubObjects.add(subObj);
869 }
870
871 destination = link.dst();
Priyanka Bcdf9b102016-06-07 20:01:38 +0530872 portNo = destination.port().toLong();
873 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
874 ipDstAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530875 subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
876 llSubObjects.add(subObj);
877 }
Priyanka Bcdf9b102016-06-07 20:01:38 +0530878
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530879 return llSubObjects;
880 }
881
882 /**
883 * Creates PcInitiated lsp request list for setup tunnel.
884 *
885 * @param tunnel mpls tunnel
886 * @param path network path
887 * @param pc pcep client
888 * @param srpId unique id for pcep message
889 * @return list of PcInitiatedLspRequest
890 * @throws PcepParseException while building pcep objects fails
891 */
892 LinkedList<PcInitiatedLspRequest> createPcInitiatedLspReqList(Tunnel tunnel, Path path,
893 PcepClient pc, int srpId)
894 throws PcepParseException {
895 PcepValueType tlv;
896 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
897
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700898 if (llSubObjects == null || llSubObjects.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530899 log.error("There is no link information to create tunnel");
900 return null;
901 }
902
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530903 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530904
905 // set PathSetupTypeTlv of SRP object
906 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)).type());
907 llOptionalTlv.add(tlv);
908
909 // build SRP object
910 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
911 .setOptionalTlv(llOptionalTlv).build();
912
913 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530914 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530915
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530916 // set LSP identifiers TLV
Avantika-Huawei56c11842016-04-28 00:56:56 +0530917 short localLspId = 0;
918 if (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) != WITH_SIGNALLING) {
919 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
920 if (localLspIdString != null) {
921 localLspId = Short.valueOf(localLspIdString);
922 }
923 }
924
Priyanka B4c3cef02016-06-14 20:27:53 +0530925 tunnel.annotations().value(LSP_SIG_TYPE);
Avantika-Huawei56c11842016-04-28 00:56:56 +0530926 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
927 localLspId, (short) 0, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
928 .getIp4Address().toInt()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530929 llOptionalTlv.add(tlv);
930 //set SymbolicPathNameTlv of LSP object
931 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
932 llOptionalTlv.add(tlv);
933
934 //build LSP object
935 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setOFlag((byte) 0).setPlspId(0)
936 .setOptionalTlv(llOptionalTlv).build();
937
938 //build ENDPOINTS object
939 PcepEndPointsObject endpointsobj = pc.factory().buildEndPointsObject()
940 .setSourceIpAddress(((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt())
941 .setDestIpAddress(((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt())
942 .setPFlag(true).build();
943
944 //build ERO object
945 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
946
Priyanka B4c3cef02016-06-14 20:27:53 +0530947 int iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530948 if (tunnel.annotations().value(BANDWIDTH) != null) {
Priyanka B4c3cef02016-06-14 20:27:53 +0530949 iBandwidth = Float.floatToIntBits(Float.parseFloat(tunnel.annotations().value(BANDWIDTH)));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530950 }
951 // build bandwidth object
952 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
953 // build pcep attribute
954 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
955
956 PcInitiatedLspRequest initiateLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
957 .setLspObject(lspobj).setEndPointsObject(endpointsobj).setEroObject(eroobj)
958 .setPcepAttribute(pcepAttribute).build();
959 llPcInitiatedLspRequestList.add(initiateLspRequest);
960 return llPcInitiatedLspRequestList;
961 }
962
963 /**
964 * To send initiate tunnel message to pcc.
965 *
966 * @param tunnel mpls tunnel info
967 * @param path explicit route for the tunnel
968 * @param pc pcep client to send message
969 */
970 private void pcepSetupTunnel(Tunnel tunnel, Path path, PcepClient pc) {
971 try {
MaheshRaju-Huaweibb591072016-06-17 17:47:16 +0530972 if (!(pc.lspDbSyncStatus().equals(PcepSyncStatus.SYNCED))) {
973 log.error("Setup tunnel has failed as LSP DB sync is not finished");
974 return;
975 }
976
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530977 int srpId = SrpIdGenerators.create();
Priyanka B4c3cef02016-06-14 20:27:53 +0530978 Collection<Tunnel> tunnels = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
979 for (Tunnel t : tunnels) {
980 if (t.tunnelName().equals(tunnel.tunnelName())) {
981 tunnel = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
982 tunnel.dst(), tunnel.type(),
983 t.state(), tunnel.groupId(),
984 t.tunnelId(),
985 tunnel.tunnelName(),
986 tunnel.path(),
987 tunnel.resource(),
988 tunnel.annotations());
989 break;
990 }
991 }
992
993 if (tunnel.tunnelId() == null) {
994 log.error("Tunnel ID not found");
995 return;
996 }
997
Avantika-Huawei56c11842016-04-28 00:56:56 +0530998 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, CREATE);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530999
Jonathan Hart51539b82015-10-29 09:53:04 -07001000 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301001
1002 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = createPcInitiatedLspReqList(tunnel, path,
1003 pc, srpId);
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001004 if (llPcInitiatedLspRequestList == null || llPcInitiatedLspRequestList.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301005 log.error("Failed to create PcInitiatedLspRequestList");
1006 return;
1007 }
1008
1009 //build PCInitiate message
1010 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1011 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList)
1012 .build();
1013
1014 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1015
Jonathan Hart51539b82015-10-29 09:53:04 -07001016 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301017 } catch (PcepParseException e) {
1018 log.error("PcepParseException occurred while processing setup tunnel {}", e.getMessage());
1019 }
1020 }
1021
1022 /**
1023 * To send Release tunnel message to pcc.
1024 *
1025 * @param tunnel mpls tunnel info
1026 * @param pc pcep client to send message
1027 */
1028 private void pcepReleaseTunnel(Tunnel tunnel, PcepClient pc) {
1029 try {
MaheshRaju-Huaweibb591072016-06-17 17:47:16 +05301030 if (!(pc.lspDbSyncStatus().equals(PcepSyncStatus.SYNCED))) {
1031 log.error("Release tunnel has failed as LSP DB sync is not finished");
1032 return;
1033 }
1034
Avantika-Huawei56c11842016-04-28 00:56:56 +05301035 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, DELETE);
Jonathan Hart51539b82015-10-29 09:53:04 -07001036 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301037 int srpId = SrpIdGenerators.create();
1038 TunnelId tunnelId = tunnel.tunnelId();
1039 int plspId = 0;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301040
Jonathan Hart51539b82015-10-29 09:53:04 -07001041 if (!(pcepTunnelApiMapper.checkFromTunnelDBQueue(tunnelId))) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301042 log.error("Tunnel doesnot exists. Tunnel id {}" + tunnelId.toString());
1043 return;
1044 } else {
Jonathan Hart51539b82015-10-29 09:53:04 -07001045 PcepTunnelData pcepTunnelDbData = pcepTunnelApiMapper.getDataFromTunnelDBQueue(tunnelId);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301046 plspId = pcepTunnelDbData.plspId();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301047 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301048
1049 PcepValueType tlv;
1050 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301051
1052 // set PathSetupTypeTlv of SRP object
1053 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))
1054 .type());
1055 llOptionalTlv.add(tlv);
1056
1057 // build SRP object
1058 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(true)
1059 .setOptionalTlv(llOptionalTlv).build();
1060
1061 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301062 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
1063
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301064 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1065 llOptionalTlv.add(tlv);
Priyanka B4c3cef02016-06-14 20:27:53 +05301066
1067 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
1068 String pccTunnelIdString = tunnel.annotations().value(PCC_TUNNEL_ID);
1069 short localLspId = 0;
1070 short pccTunnelId = 0;
1071
1072 if (localLspIdString != null) {
1073 localLspId = Short.valueOf(localLspIdString);
1074 }
1075
1076 if (pccTunnelIdString != null) {
1077 pccTunnelId = Short.valueOf(pccTunnelIdString);
1078 }
1079
1080 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src())
1081 .ip().getIp4Address().toInt()),
1082 localLspId, pccTunnelId, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
1083 .getIp4Address().toInt()));
1084 llOptionalTlv.add(tlv);
1085
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301086 // build lsp object, set r flag as false to delete the tunnel
1087 PcepLspObject lspobj = pc.factory().buildLspObject().setRFlag(false).setPlspId(plspId)
1088 .setOptionalTlv(llOptionalTlv).build();
1089
1090 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
1091 .setLspObject(lspobj).build();
1092
1093 llPcInitiatedLspRequestList.add(releaseLspRequest);
1094
1095 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1096 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1097
1098 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1099
Jonathan Hart51539b82015-10-29 09:53:04 -07001100 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301101 } catch (PcepParseException e) {
1102 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1103 }
1104 }
1105
1106 /**
1107 * To send Update tunnel request message to pcc.
1108 *
1109 * @param tunnel mpls tunnel info
1110 * @param path explicit route for the tunnel
1111 * @param pc pcep client to send message
1112 */
1113 private void pcepUpdateTunnel(Tunnel tunnel, Path path, PcepClient pc) {
1114 try {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301115 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, UPDATE);
Jonathan Hart51539b82015-10-29 09:53:04 -07001116 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301117 int srpId = SrpIdGenerators.create();
1118 TunnelId tunnelId = tunnel.tunnelId();
1119 PcepValueType tlv;
1120 int plspId = 0;
1121
1122 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
1123 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
1124 LinkedList<PcepUpdateRequest> llUpdateRequestList = new LinkedList<PcepUpdateRequest>();
1125
Avantika-Huawei56c11842016-04-28 00:56:56 +05301126 // set PathSetupTypeTlv of SRP object
1127 LspType lspSigType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
1128 tlv = new PathSetupTypeTlv(lspSigType.type());
1129 llOptionalTlv.add(tlv);
1130
1131 // build SRP object
1132 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
1133 .setOptionalTlv(llOptionalTlv).build();
1134
1135 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301136
Avantika-Huawei56c11842016-04-28 00:56:56 +05301137 if (lspSigType != WITH_SIGNALLING) {
1138 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
1139 String pccTunnelIdString = tunnel.annotations().value(PCC_TUNNEL_ID);
1140 short localLspId = 0;
1141 short pccTunnelId = 0;
1142
1143 if (localLspIdString != null) {
1144 localLspId = Short.valueOf(localLspIdString);
1145 }
1146
1147 if (pccTunnelIdString != null) {
1148 pccTunnelId = Short.valueOf(pccTunnelIdString);
1149 }
1150
1151 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src())
1152 .ip().getIp4Address().toInt()),
1153 localLspId, pccTunnelId, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
1154 .getIp4Address().toInt()));
1155 llOptionalTlv.add(tlv);
1156 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301157
1158 if (tunnel.tunnelName().value() != null) {
1159 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1160 llOptionalTlv.add(tlv);
1161 }
1162
1163 // build lsp object
Priyanka B4c3cef02016-06-14 20:27:53 +05301164 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true)
1165 .setPlspId(Integer.valueOf(tunnel.annotations().value(PLSP_ID)))
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301166 .setOptionalTlv(llOptionalTlv).build();
1167 // build ero object
1168 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
1169
Priyanka B4c3cef02016-06-14 20:27:53 +05301170 float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +05301171 if (tunnel.annotations().value(BANDWIDTH) != null) {
Priyanka B4c3cef02016-06-14 20:27:53 +05301172 iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301173 }
1174 // build bandwidth object
1175 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
1176 // build pcep attribute
1177 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
1178 // build pcep msg path
1179 PcepMsgPath msgPath = pc.factory().buildPcepMsgPath().setEroObject(eroobj).setPcepAttribute(pcepAttribute)
1180 .build();
1181
1182 PcepUpdateRequest updateRequest = pc.factory().buildPcepUpdateRequest().setSrpObject(srpobj)
1183 .setLspObject(lspobj).setMsgPath(msgPath).build();
1184
1185 llUpdateRequestList.add(updateRequest);
1186
1187 PcepUpdateMsg pcUpdateMsg = pc.factory().buildUpdateMsg().setUpdateRequestList(llUpdateRequestList).build();
1188
1189 pc.sendMessage(Collections.singletonList(pcUpdateMsg));
Jonathan Hart51539b82015-10-29 09:53:04 -07001190 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301191 } catch (PcepParseException e) {
1192 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1193 }
1194 }
1195
chengfan2fff70f2015-08-24 18:20:19 -05001196
1197
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301198 private class InnerTunnelProvider implements PcepTunnelListener, PcepEventListener, PcepClientListener {
cheng fan48e832c2015-05-29 01:54:47 +08001199
1200 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -07001201 public void handlePcepTunnel(PcepTunnel pcepTunnel) {
cheng fan48e832c2015-05-29 01:54:47 +08001202 TunnelDescription tunnel = null;
1203 // instance and id identify a tunnel together
1204 String tunnelKey = String.valueOf(pcepTunnel.getInstance())
1205 + String.valueOf(pcepTunnel.id());
1206
1207 if (tunnelKey == null || "".equals(tunnelKey)) {
1208 log.error("Invalid PCEP tunnel");
1209 return;
1210 }
1211
1212 TunnelId tunnelId = getTunnelId(tunnelKey);
1213
1214 tunnel = buildOpticalTunnel(pcepTunnel, tunnelId);
1215
1216 OperationType operType = pcepTunnel.getOperationType();
1217 switch (operType) {
1218 case ADD:
1219 tunnelId = service.tunnelAdded(tunnel);
1220 tunnelMap.put(tunnelKey, tunnelId);
1221 break;
1222
1223 case UPDATE:
1224 service.tunnelUpdated(tunnel);
1225 break;
1226
1227 case DELETE:
1228 service.tunnelRemoved(tunnel);
1229 tunnelMap.remove(tunnelKey);
1230 break;
1231
1232 default:
1233 log.error("Invalid tunnel operation");
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301234 }
1235 }
cheng fan48e832c2015-05-29 01:54:47 +08001236
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301237 @Override
1238 public void handleMessage(PccId pccId, PcepMessage msg) {
1239 try {
1240 log.debug("tunnel provider handle message {}", msg.getType().toString());
1241 switch (msg.getType()) {
1242 case REPORT:
1243 int srpId = 0;
1244 LinkedList<PcepStateReport> llStateReportList = null;
1245 llStateReportList = ((PcepReportMsg) msg).getStateReportList();
1246 ListIterator<PcepStateReport> listIterator = llStateReportList.listIterator();
1247 PcepSrpObject srpObj = null;
1248 PcepLspObject lspObj = null;
1249 while (listIterator.hasNext()) {
1250 PcepStateReport stateRpt = listIterator.next();
1251 srpObj = stateRpt.getSrpObject();
1252 lspObj = stateRpt.getLspObject();
1253
1254 if (srpObj instanceof PcepSrpObject) {
1255 srpId = srpObj.getSrpID();
1256 }
1257
1258 log.debug("Plsp ID in handle message " + lspObj.getPlspId());
1259 log.debug("SRP ID in handle message " + srpId);
1260
Jonathan Hart51539b82015-10-29 09:53:04 -07001261 if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301262 // For PCRpt without matching SRP id.
1263 handleRptWithoutSrpId(stateRpt, pccId);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301264 continue;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301265 }
1266
Avantika-Huawei56c11842016-04-28 00:56:56 +05301267 handleReportMessage(srpId, lspObj, stateRpt);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301268 }
1269 break;
1270
1271 default:
1272 log.debug("Received unsupported message type {}", msg.getType().toString());
1273 }
1274 } catch (Exception e) {
1275 log.error("Exception occured while processing report message {}", e.getMessage());
1276 }
1277 }
1278
1279 /**
1280 * Handles report message for setup/update/delete tunnel request.
1281 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301282 * @param srpId unique identifier for PCEP message
1283 * @param lspObj LSP object
1284 * @param stateRpt parsed PCEP report msg.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301285 */
Avantika-Huawei56c11842016-04-28 00:56:56 +05301286 private void handleReportMessage(int srpId, PcepLspObject lspObj, PcepStateReport stateRpt) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301287 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Jonathan Hart51539b82015-10-29 09:53:04 -07001288 PcepTunnelData pcepTunnelData = pcepTunnelApiMapper.getDataFromTunnelRequestQueue(srpId);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301289
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301290 // store the values required from report message
1291 pcepTunnelData.setPlspId(lspObj.getPlspId());
1292 pcepTunnelData.setLspAFlag(lspObj.getAFlag());
1293 pcepTunnelData.setLspOFlag(lspObj.getOFlag());
1294 pcepTunnelData.setLspDFlag(lspObj.getDFlag());
1295
Avantika-Huawei56c11842016-04-28 00:56:56 +05301296 StatefulIPv4LspIdentifiersTlv ipv4LspTlv = null;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301297 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1298 while (listTlvIterator.hasNext()) {
1299 PcepValueType tlv = listTlvIterator.next();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301300 if (tlv.getType() == StatefulIPv4LspIdentifiersTlv.TYPE) {
1301 ipv4LspTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301302 break;
1303 }
1304 }
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001305 if (ipv4LspTlv != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301306 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspTlv);
cheng fan48e832c2015-05-29 01:54:47 +08001307 }
1308
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301309 Path path = pcepTunnelData.path();
1310 Tunnel tunnel = pcepTunnelData.tunnel();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301311 Builder annotationBuilder = DefaultAnnotations.builder();
1312 annotationBuilder.putAll(pcepTunnelData.tunnel().annotations());
1313
1314 // PCRpt in response to PCInitate msg will carry PLSP id allocated by PCC.
1315 if (tunnel.annotations().value(PLSP_ID) == null) {
1316 annotationBuilder.set(PLSP_ID, String.valueOf(lspObj.getPlspId()));
1317 }
1318
1319 // Signalled LSPs will carry local LSP id allocated by signalling protocol(PCC).
1320 if (tunnel.annotations().value(LOCAL_LSP_ID) == null) {
1321 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(ipv4LspTlv.getLspId()));
1322 }
1323
Priyanka B4c3cef02016-06-14 20:27:53 +05301324 if (tunnel.annotations().value(PCC_TUNNEL_ID) == null) {
1325 annotationBuilder.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspTlv.getTunnelId()));
1326 }
1327
Avantika-Huawei56c11842016-04-28 00:56:56 +05301328 SparseAnnotations annotations = annotationBuilder.build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301329 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(),
1330 tunnel.dst(), tunnel.type(), tunnel.groupId(),
1331 providerId, tunnel.tunnelName(), path,
1332 annotations);
1333
Avantika-Huawei56c11842016-04-28 00:56:56 +05301334 if (CREATE == pcepTunnelData.requestType()) {
Priyanka B4c3cef02016-06-14 20:27:53 +05301335 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
Jonathan Hart51539b82015-10-29 09:53:04 -07001336 pcepTunnelApiMapper.handleCreateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301337 } else if (DELETE == pcepTunnelData.requestType()) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001338 pcepTunnelApiMapper.handleRemoveFromTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301339 } else if (UPDATE == pcepTunnelData.requestType()) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301340 pcepTunnelData.setRptFlag(true);
Jonathan Hart51539b82015-10-29 09:53:04 -07001341 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1342 pcepTunnelApiMapper.handleUpdateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301343 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301344
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301345 PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
1346
Avantika-Huawei56c11842016-04-28 00:56:56 +05301347 if (lspObj.getRFlag()) {
1348 tunnelRemoved(td);
1349 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301350 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(pcepLspStatus);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301351 tunnelUpdated(td, tunnelState);
1352 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301353
1354 // SR-TE also needs PCUpd msg after receiving PCRpt with status GOING-UP even
1355 // though there are no labels to download for SR-TE.
1356 if ((pcepLspStatus == PcepLspStatus.GOING_UP)
1357 && (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) == SR_WITHOUT_SIGNALLING)) {
1358 updateTunnel(tunnel, tunnel.path());
1359 }
Avantika-Huawei56c11842016-04-28 00:56:56 +05301360 }
1361
Priyanka B413fbe82016-05-26 11:44:45 +05301362 private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301363 float bandwidth, LspType lspType, String costType) {
1364
1365 Builder builder = DefaultAnnotations.builder();
1366
1367 /*
1368 * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
1369 * for which no constraints need be applied to any of the metrics.
1370 */
1371 if (costType != null) {
1372 builder.set(COST_TYPE, costType);
1373 }
1374
1375 SparseAnnotations annotations = builder
Priyanka B413fbe82016-05-26 11:44:45 +05301376 .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
1377 .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
1378 .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
1379 .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
1380 .set(DELEGATE, String.valueOf(lspObj.getDFlag()))
1381 .build();
1382 return annotations;
1383 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301384
Priyanka B413fbe82016-05-26 11:44:45 +05301385 private LspType getLspType(PcepSrpObject srpObj) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301386 LspType lspType = WITH_SIGNALLING;
1387
1388 if (null != srpObj) {
1389 LinkedList<PcepValueType> llOptionalTlv = srpObj.getOptionalTlv();
1390 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
1391
1392 while (listIterator.hasNext()) {
1393 PcepValueType tlv = listIterator.next();
1394
1395 switch (tlv.getType()) {
1396 case PathSetupTypeTlv.TYPE:
1397 lspType = LspType.values()[Integer.valueOf(((PathSetupTypeTlv) tlv).getPst())];
1398 break;
1399
1400 default:
1401 break;
1402 }
1403 }
1404 }
Priyanka B413fbe82016-05-26 11:44:45 +05301405 return lspType;
1406 }
1407
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301408 private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
Priyanka B413fbe82016-05-26 11:44:45 +05301409 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301410 String costType = null;
Priyanka B413fbe82016-05-26 11:44:45 +05301411 PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
1412 checkNotNull(msgPath);
1413 PcepEroObject eroObj = msgPath.getEroObject();
1414 if (eroObj == null) {
1415 log.error("ERO object is null in report message.");
1416 return;
1417 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301418
1419 PcepAttribute attributes = msgPath.getPcepAttribute();
1420 int cost = 0;
1421 if (attributes != null && attributes.getMetricObjectList() != null) {
1422 ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
1423 PcepMetricObject metricObj = iterator.next();
1424
1425 while (metricObj != null) {
1426 if (metricObj.getBType() == IGP_METRIC) {
1427 costType = "COST";
1428 } else if (metricObj.getBType() == TE_METRIC) {
1429 costType = "TE_COST";
1430 }
1431
1432 if (costType != null) {
1433 cost = metricObj.getMetricVal();
1434 log.debug("Path cost {}", cost);
1435 break;
1436 }
1437 metricObj = iterator.next();
1438 }
1439 }
1440
1441 Path path = buildPathFromEroObj(eroObj, providerId, cost);
Priyanka B413fbe82016-05-26 11:44:45 +05301442
1443 float bandwidth = 0;
1444 if (msgPath.getBandwidthObject() != null) {
1445 bandwidth = msgPath.getBandwidthObject().getBandwidth();
1446 }
1447
1448 /*
1449 * To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
1450 * from PCE.
1451 */
1452 PcepSrpObject srpObj = stateRpt.getSrpObject();
1453 LspType lspType = getLspType(srpObj);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301454
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301455 PcepLspObject lspObj = stateRpt.getLspObject();
1456 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1457 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
1458 SymbolicPathNameTlv pathNameTlv = null;
1459
1460 while (listTlvIterator.hasNext()) {
1461 PcepValueType tlv = listTlvIterator.next();
1462 switch (tlv.getType()) {
1463 case StatefulIPv4LspIdentifiersTlv.TYPE:
1464 ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
1465 break;
1466
1467 case SymbolicPathNameTlv.TYPE:
1468 pathNameTlv = (SymbolicPathNameTlv) tlv;
1469 break;
1470
1471 default:
1472 break;
1473 }
1474 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301475 /*
1476 * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
1477 * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
1478 */
1479 if (ipv4LspIdenTlv == null) {
1480 log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
1481 return;
1482 }
1483
1484 IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
1485 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
1486 IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
1487 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
1488 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
1489
Priyanka B413fbe82016-05-26 11:44:45 +05301490 // Store delegation flag info and that LSP info because only delegated PCE sends update message
1491 // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
1492 // not present then non-delegated , if present it is delegated.
1493 if (lspObj.getDFlag()) {
1494 pcepClientController.getClient(pccId).setLspAndDelegationInfo(
1495 new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
1496 }
1497
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301498 Tunnel tunnel = null;
1499 // Asynchronous status change message from PCC for LSP reported earlier.
1500 for (Tunnel tunnelObj : tunnelQueryResult) {
1501 if (tunnelObj.annotations().value(PLSP_ID) == null) {
1502 /*
1503 * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
1504 * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
1505 * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
1506 * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
1507 * session an LSP is "first" reported to a PCE.
1508 */
1509 if ((pathNameTlv != null)
1510 && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
1511 tunnel = tunnelObj;
1512 break;
1513 }
1514 continue;
1515 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301516 if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
1517 .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
1518 tunnel = tunnelObj;
1519 break;
1520 }
1521 }
1522
1523 DefaultTunnelDescription td;
Priyanka B413fbe82016-05-26 11:44:45 +05301524 SparseAnnotations annotations = null;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301525 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
1526 if (tunnel == null) {
1527 if (lspObj.getRFlag()) {
1528 /*
1529 * If PCC sends remove message and for any reason PCE does not have that entry, simply discard the
1530 * message. Or if PCRpt for initiated LSP received and PCE doesn't know, then too discard.
1531 */
1532 return;
1533 }
1534
Priyanka B413fbe82016-05-26 11:44:45 +05301535 DeviceId deviceId = getDevice(pccId);
1536 if (deviceId == null) {
1537 log.error("Ingress deviceId not found");
1538 return;
1539 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301540 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301541
Priyanka B413fbe82016-05-26 11:44:45 +05301542 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
1543 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
1544 annotations);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301545
1546 // Do not support PCC initiated LSP after LSP DB sync is completed.
1547 if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
1548 log.error("Received PCC initiated LSP while not in sync.");
1549 return;
1550 }
1551
Priyanka B413fbe82016-05-26 11:44:45 +05301552 /*
1553 * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
1554 * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
1555 * delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
1556 * wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
1557 * updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
1558 * send update message to that client.
1559 *
1560 * 1)Master can 1st get the Rpt message
1561 * a)Master adds the tunnel into core.
1562 * b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
1563 * after master, then runs timer then update the tunnel with D flag set.
1564 * 2)Non-Master can 1st get the Rpt message
1565 * a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
1566 * b)Master would have got the message while the non-master running timer, hence master adds
1567 * tunnel to core
1568 *
1569 * In general always master adds the tunnel to the core
1570 * while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
1571 */
1572 if (mastershipService.isLocalMaster(deviceId)) {
1573 TunnelId tId = tunnelAdded(td, tunnelState);
1574 Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
1575 tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
1576 .getValue())), path, annotations);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301577
Priyanka B413fbe82016-05-26 11:44:45 +05301578 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
1579 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
1580 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1581 } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
1582 //Start timer then update the tunnel with D flag
1583 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1584 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301585 return;
1586 }
1587
Priyanka B413fbe82016-05-26 11:44:45 +05301588 //delegated owner will update can be a master or non-master
1589 if (lspObj.getDFlag()) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301590 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Priyanka B413fbe82016-05-26 11:44:45 +05301591 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
1592 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path,
1593 annotations);
1594 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1595 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301596 removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
Priyanka B413fbe82016-05-26 11:44:45 +05301597 return;
1598 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301599
Priyanka B413fbe82016-05-26 11:44:45 +05301600 private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301601 State tunnelState) {
Priyanka B413fbe82016-05-26 11:44:45 +05301602 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
1603 tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
1604 (SparseAnnotations) tunnel.annotations());
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301605 if (lspObj.getRFlag()) {
1606 tunnelRemoved(td);
1607 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301608 tunnelUpdated(td, tunnelState);
1609 }
Priyanka B413fbe82016-05-26 11:44:45 +05301610 }
1611
1612 private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
1613 DefaultTunnelDescription td, ProviderId providerId) {
1614 //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
1615
1616 /*
1617 * If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
1618 * master has added the tunnel to the store] then update the tunnel.
1619 */
1620 ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
1621
1622 // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
1623 executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
1624 executor), DELAY, DELAY, TimeUnit.SECONDS);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301625 }
1626
1627 /**
Avantika-Huawei56c11842016-04-28 00:56:56 +05301628 * To build Path in network from ERO object.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301629 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301630 * @param eroObj ERO object
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301631 * @param providerId provider id
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301632 * @param cost cost of path
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301633 * @return path object
1634 */
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301635 private Path buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId, int cost) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301636 checkNotNull(eroObj);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301637 List<Link> links = new ArrayList<Link>();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301638 LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301639 if (0 == llSubObj.size()) {
Priyanka B4c3cef02016-06-14 20:27:53 +05301640 log.debug("ERO in report message does not have hop information");
1641 return null;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301642 }
1643 ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
1644
1645 ConnectPoint src = null;
1646 ConnectPoint dst = null;
1647 boolean isSrcSet = false;
1648 while (tlvIterator.hasNext()) {
1649 PcepValueType subObj = tlvIterator.next();
1650 switch (subObj.getType()) {
1651
1652 case IPv4SubObject.TYPE:
1653
1654 IPv4SubObject ipv4SubObj = (IPv4SubObject) subObj;
1655 if (!isSrcSet) {
1656 IpAddress srcIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1657 src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
1658 isSrcSet = true;
1659 } else {
1660 IpAddress dstIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1661 dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
Ray Milkey2693bda2016-01-22 16:08:14 -08001662 Link link = DefaultLink.builder()
1663 .providerId(providerId)
1664 .src(src)
1665 .dst(dst)
1666 .type(Link.Type.DIRECT)
1667 .build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301668 links.add(link);
1669 src = dst;
1670 }
1671 break;
1672 default:
1673 // the other sub objects are not required
1674 }
1675 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301676
1677 return new DefaultPath(providerId, links, cost, EMPTY);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301678 }
1679
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301680 @Override
1681 public void clientConnected(PccId pccId) {
1682 // TODO
1683 }
1684
1685 @Override
1686 public void clientDisconnected(PccId pccId) {
1687 // TODO
cheng fan48e832c2015-05-29 01:54:47 +08001688 }
chengfan2fff70f2015-08-24 18:20:19 -05001689
chengfan2fff70f2015-08-24 18:20:19 -05001690 @Override
1691 public void handlePcepTunnelStatistics(PcepTunnelStatistics pcepTunnelStatistics) {
1692 TunnelId id = getTunnelId(String.valueOf(pcepTunnelStatistics.id()));
1693 TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
1694 tunnelStatisticsMap.put(id, tunnelStatistics);
1695 }
cheng fan48e832c2015-05-29 01:54:47 +08001696
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301697 @Override
1698 public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301699
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301700 if (endOfSyncAction == SEND_UPDATE) {
1701 updateTunnel(tunnel, tunnel.path());
1702 return;
1703 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301704
1705 TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
1706 tunnel.src(), tunnel.dst(),
1707 tunnel.type(),
1708 tunnel.groupId(),
1709 tunnel.providerId(),
1710 tunnel.tunnelName(),
1711 tunnel.path(),
1712 (SparseAnnotations) tunnel.annotations());
1713
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301714
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301715 if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
1716
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301717 // Send PCInit msg again after global reoptimization.
1718 tunnelUpdated(td, UNSTABLE);
1719
1720 // To remove the old tunnel from store whose PLSPID is not
1721 // recognized by ingress PCC.
1722 tunnelRemoved(td);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301723
1724 } else if (endOfSyncAction == REMOVE) {
1725 tunnelRemoved(td);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301726 }
1727 }
1728
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301729 @Override
1730 public void handleEndOfSyncAction(PccId pccId, PcepMessage msg, PcepLspSyncAction endOfSyncAction) {
1731 try {
1732 if ((msg instanceof PcepInitiateMsg) && (endOfSyncAction == SEND_DELETE)) {
1733 PcepClient pc = pcepClientController.getClient(pccId);
1734 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = ((PcepInitiateMsg) msg)
1735 .getPcInitiatedLspRequestList();
1736 PcInitiatedLspRequest pcInitMsg = llPcInitiatedLspRequestList.iterator().next();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301737
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301738 if (pcInitMsg != null) {
1739 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
1740 .setRFlag(true).build();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301741
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301742 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
1743 .setLspObject(pcInitMsg.getLspObject()).setSrpObject(srpobj).build();
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301744
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301745 llPcInitiatedLspRequestList.remove(pcInitMsg);
1746 llPcInitiatedLspRequestList.add(releaseLspRequest);
1747
1748 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1749 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1750
1751 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1752 }
1753 }
1754 } catch (PcepParseException e) {
1755 log.error("Exception occured while sending initiate delete message {}", e.getMessage());
1756 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301757 }
1758 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301759 @Override
1760 public Tunnel tunnelQueryById(TunnelId tunnelId) {
1761 return service.tunnelQueryById(tunnelId);
1762 }
1763
Priyanka B413fbe82016-05-26 11:44:45 +05301764
1765 private DeviceId getDevice(PccId pccId) {
1766 // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
1767 IpAddress lsrId = pccId.ipAddress();
1768 String lsrIdentifier = String.valueOf(lsrId);
1769
1770 // Find PCC deviceID from lsrId stored as annotations
1771 Iterable<Device> devices = deviceService.getAvailableDevices();
1772 for (Device dev : devices) {
1773 if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
1774 && dev.annotations().value(LSRID).equals(lsrIdentifier)) {
1775 return dev.id();
1776 }
1777 }
1778 return null;
1779 }
1780
1781 /**
1782 * Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
1783 * tunnel is found.
1784 */
1785 private class UpdateDelegation implements Runnable {
1786 DefaultTunnelDescription td;
1787 ProviderId providerId;
1788 SparseAnnotations annotations;
1789 PccId pccId;
1790 ScheduledExecutorService executor;
1791
1792 /**
1793 * Creates an instance of UpdateDelegation.
1794 *
1795 * @param td tunnel description
1796 * @param providerId provider id
1797 * @param annotations tunnel annotations
1798 * @param pccId PCEP client id
1799 * @param executor service of delegated owner
1800 */
1801 public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
1802 PccId pccId, ScheduledExecutorService executor) {
1803 this.td = td;
1804 this.providerId = providerId;
1805 this.annotations = annotations;
1806 this.pccId = pccId;
1807 this.executor = executor;
1808 }
1809
1810 //Temporary using annotations later will use projection/network config service
1811 @Override
1812 public void run() {
1813 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
1814 TunnelId tempTunnelId = null;
1815 for (Tunnel t : tunnelQueryResult) {
1816 if (t.annotations().value(LOCAL_LSP_ID) == null || t.annotations().value(PLSP_ID) == null) {
1817 continue;
1818 }
1819
1820 if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
1821 && t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
1822 && ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
1823 tempTunnelId = t.tunnelId();
1824 break;
1825 }
1826 }
1827
1828 //If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
1829 //periodically
1830 if (tempTunnelId != null) {
1831 Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
1832 tempTunnelId, td.tunnelName(), td.path(), annotations);
1833 tunnelUpdated(tunnel, td.path());
1834 executor.shutdown();
1835 try {
1836 executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
1837 } catch (InterruptedException e) {
1838 log.error("updating delegation failed");
1839 }
1840 }
1841 }
1842 }
cheng fan48e832c2015-05-29 01:54:47 +08001843}