blob: 8d45e08437260b0c26699f76cb52ed9f4e96ea6d [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;
Avantika-Huaweif849aab2016-06-21 22:29:15 +053031import org.onosproject.incubator.net.resource.label.LabelResourceId;
32import org.onosproject.incubator.net.tunnel.DefaultLabelStack;
cheng fan48e832c2015-05-29 01:54:47 +080033import org.onosproject.incubator.net.tunnel.DefaultOpticalTunnelEndPoint;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053034import org.onosproject.incubator.net.tunnel.DefaultTunnel;
cheng fan48e832c2015-05-29 01:54:47 +080035import org.onosproject.incubator.net.tunnel.DefaultTunnelDescription;
chengfan2fff70f2015-08-24 18:20:19 -050036import org.onosproject.incubator.net.tunnel.DefaultTunnelStatistics;
Jonathan Hart51539b82015-10-29 09:53:04 -070037import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
cheng fan48e832c2015-05-29 01:54:47 +080038import org.onosproject.incubator.net.tunnel.OpticalLogicId;
39import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
40import org.onosproject.incubator.net.tunnel.Tunnel;
Avantika-Huawei56c11842016-04-28 00:56:56 +053041import org.onosproject.incubator.net.tunnel.Tunnel.State;
Priyanka B413fbe82016-05-26 11:44:45 +053042import org.onosproject.incubator.net.tunnel.TunnelAdminService;
cheng fan48e832c2015-05-29 01:54:47 +080043import org.onosproject.incubator.net.tunnel.TunnelDescription;
44import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
45import org.onosproject.incubator.net.tunnel.TunnelId;
46import org.onosproject.incubator.net.tunnel.TunnelName;
47import org.onosproject.incubator.net.tunnel.TunnelProvider;
48import org.onosproject.incubator.net.tunnel.TunnelProviderRegistry;
49import org.onosproject.incubator.net.tunnel.TunnelProviderService;
chengfan2fff70f2015-08-24 18:20:19 -050050import org.onosproject.incubator.net.tunnel.TunnelService;
51import org.onosproject.incubator.net.tunnel.TunnelStatistics;
Priyanka B413fbe82016-05-26 11:44:45 +053052import org.onosproject.mastership.MastershipService;
53import org.onosproject.net.AnnotationKeys;
cheng fan48e832c2015-05-29 01:54:47 +080054import org.onosproject.net.ConnectPoint;
55import org.onosproject.net.DefaultAnnotations;
Avantika-Huawei56c11842016-04-28 00:56:56 +053056import org.onosproject.net.DefaultAnnotations.Builder;
cheng fan48e832c2015-05-29 01:54:47 +080057import org.onosproject.net.DefaultLink;
58import org.onosproject.net.DefaultPath;
Priyanka B413fbe82016-05-26 11:44:45 +053059import org.onosproject.net.Device;
cheng fan48e832c2015-05-29 01:54:47 +080060import org.onosproject.net.DeviceId;
61import org.onosproject.net.ElementId;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053062import org.onosproject.net.IpElementId;
cheng fan48e832c2015-05-29 01:54:47 +080063import org.onosproject.net.Link;
Avantika-Huaweif849aab2016-06-21 22:29:15 +053064import org.onosproject.net.NetworkResource;
cheng fan48e832c2015-05-29 01:54:47 +080065import org.onosproject.net.Path;
66import org.onosproject.net.PortNumber;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053067import org.onosproject.net.SparseAnnotations;
Priyanka B413fbe82016-05-26 11:44:45 +053068import org.onosproject.net.device.DeviceService;
Priyanka Bc1e4e4c2016-07-01 14:57:19 +053069import org.onosproject.net.link.LinkService;
cheng fan48e832c2015-05-29 01:54:47 +080070import org.onosproject.net.provider.AbstractProvider;
71import org.onosproject.net.provider.ProviderId;
72import org.onosproject.pcep.api.PcepController;
73import org.onosproject.pcep.api.PcepDpid;
74import org.onosproject.pcep.api.PcepHopNodeDescription;
75import org.onosproject.pcep.api.PcepOperator.OperationType;
76import org.onosproject.pcep.api.PcepTunnel;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053077import org.onosproject.pcep.api.PcepTunnel.PathState;
Jonathan Hart51539b82015-10-29 09:53:04 -070078import org.onosproject.pcep.api.PcepTunnel.PathType;
cheng fan48e832c2015-05-29 01:54:47 +080079import org.onosproject.pcep.api.PcepTunnelListener;
chengfan2fff70f2015-08-24 18:20:19 -050080import org.onosproject.pcep.api.PcepTunnelStatistics;
Priyanka B413fbe82016-05-26 11:44:45 +053081import org.onosproject.pcep.controller.LspKey;
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +053082import org.onosproject.pcep.controller.LspType;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053083import org.onosproject.pcep.controller.PccId;
84import org.onosproject.pcep.controller.PcepClient;
85import org.onosproject.pcep.controller.PcepClientController;
86import org.onosproject.pcep.controller.PcepClientListener;
87import org.onosproject.pcep.controller.PcepEventListener;
Priyanka B259847d2016-06-03 21:28:35 +053088import org.onosproject.pcep.controller.PcepLspStatus;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053089import org.onosproject.pcep.controller.PcepLspSyncAction;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +053090import org.onosproject.pcep.controller.SrpIdGenerators;
MaheshRaju-Huaweibb591072016-06-17 17:47:16 +053091import org.onosproject.pcep.controller.PcepSyncStatus;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053092import org.onosproject.pcepio.exceptions.PcepParseException;
93import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
94import org.onosproject.pcepio.protocol.PcepAttribute;
95import org.onosproject.pcepio.protocol.PcepBandwidthObject;
96import org.onosproject.pcepio.protocol.PcepEndPointsObject;
97import org.onosproject.pcepio.protocol.PcepEroObject;
98import org.onosproject.pcepio.protocol.PcepInitiateMsg;
99import org.onosproject.pcepio.protocol.PcepLspObject;
100import org.onosproject.pcepio.protocol.PcepMessage;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530101import org.onosproject.pcepio.protocol.PcepMetricObject;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530102import org.onosproject.pcepio.protocol.PcepMsgPath;
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530103import org.onosproject.pcepio.protocol.PcepNai;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530104import org.onosproject.pcepio.protocol.PcepReportMsg;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530105import org.onosproject.pcepio.protocol.PcepSrpObject;
106import org.onosproject.pcepio.protocol.PcepStateReport;
107import org.onosproject.pcepio.protocol.PcepUpdateMsg;
108import org.onosproject.pcepio.protocol.PcepUpdateRequest;
109import org.onosproject.pcepio.types.IPv4SubObject;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530110import org.onosproject.pcepio.types.PathSetupTypeTlv;
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530111import org.onosproject.pcepio.types.PcepNaiIpv4Adjacency;
112import org.onosproject.pcepio.types.PcepNaiIpv4NodeId;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530113import org.onosproject.pcepio.types.PcepValueType;
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530114import org.onosproject.pcepio.types.SrEroSubObject;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530115import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530116import org.onosproject.pcepio.types.SymbolicPathNameTlv;
chengfan2fff70f2015-08-24 18:20:19 -0500117import org.osgi.service.component.ComponentContext;
Jonathan Hart51539b82015-10-29 09:53:04 -0700118import org.osgi.service.component.annotations.Modified;
119import org.slf4j.Logger;
120
121import java.util.ArrayList;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530122import java.util.Arrays;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530123import java.util.Collection;
Jonathan Hart51539b82015-10-29 09:53:04 -0700124import java.util.Collections;
125import java.util.Dictionary;
126import java.util.HashMap;
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530127import java.util.Iterator;
Jonathan Hart51539b82015-10-29 09:53:04 -0700128import java.util.LinkedList;
129import java.util.List;
130import java.util.ListIterator;
131import java.util.Optional;
Priyanka B413fbe82016-05-26 11:44:45 +0530132import java.util.concurrent.Executors;
133import java.util.concurrent.ScheduledExecutorService;
134import java.util.concurrent.TimeUnit;
Jonathan Hart51539b82015-10-29 09:53:04 -0700135
136import static com.google.common.base.Preconditions.checkNotNull;
137import static com.google.common.base.Strings.isNullOrEmpty;
138import static org.onlab.util.Tools.get;
Priyanka B4c3cef02016-06-14 20:27:53 +0530139import static org.onosproject.incubator.net.tunnel.Tunnel.State.INIT;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530140import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
Jonathan Hart51539b82015-10-29 09:53:04 -0700141import static org.onosproject.net.DefaultAnnotations.EMPTY;
142import static org.onosproject.net.DeviceId.deviceId;
143import static org.onosproject.net.PortNumber.portNumber;
144import static org.onosproject.pcep.api.PcepDpid.uri;
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530145import static org.onosproject.pcep.controller.LspType.WITH_SIGNALLING;
146import static org.onosproject.pcep.controller.LspType.SR_WITHOUT_SIGNALLING;
147import static org.onosproject.pcep.controller.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530148import static org.onosproject.pcep.controller.PcepAnnotationKeys.BANDWIDTH;
149import static org.onosproject.pcep.controller.PcepAnnotationKeys.LOCAL_LSP_ID;
150import static org.onosproject.pcep.controller.PcepAnnotationKeys.LSP_SIG_TYPE;
151import static org.onosproject.pcep.controller.PcepAnnotationKeys.PCC_TUNNEL_ID;
Priyanka B4c3cef02016-06-14 20:27:53 +0530152import static org.onosproject.pcep.controller.PcepAnnotationKeys.PCE_INIT;
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530153import static org.onosproject.pcep.controller.PcepAnnotationKeys.PLSP_ID;
154import static org.onosproject.pcep.controller.PcepAnnotationKeys.DELEGATE;
155import static org.onosproject.pcep.controller.PcepAnnotationKeys.COST_TYPE;
Avantika-Huawei56c11842016-04-28 00:56:56 +0530156import static org.onosproject.provider.pcep.tunnel.impl.RequestType.CREATE;
157import static org.onosproject.provider.pcep.tunnel.impl.RequestType.DELETE;
158import static org.onosproject.provider.pcep.tunnel.impl.RequestType.LSP_STATE_RPT;
159import static org.onosproject.provider.pcep.tunnel.impl.RequestType.UPDATE;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530160import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530161import static org.onosproject.pcep.controller.PcepLspSyncAction.REMOVE;
162import static org.onosproject.pcep.controller.PcepLspSyncAction.SEND_UPDATE;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530163import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.IGP_METRIC;
164import static org.onosproject.pcepio.protocol.ver1.PcepMetricObjectVer1.TE_METRIC;
Jonathan Hart51539b82015-10-29 09:53:04 -0700165import static org.slf4j.LoggerFactory.getLogger;
cheng fan48e832c2015-05-29 01:54:47 +0800166
167/**
168 * Provider which uses an PCEP controller to detect, update, create network
169 * tunnels.
170 */
171@Component(immediate = true)
172@Service
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530173public class PcepTunnelProvider extends AbstractProvider implements TunnelProvider {
cheng fan48e832c2015-05-29 01:54:47 +0800174
175 private static final Logger log = getLogger(PcepTunnelProvider.class);
176 private static final long MAX_BANDWIDTH = 99999744;
177 private static final long MIN_BANDWIDTH = 64;
cheng fan7716ec92015-05-31 01:53:19 +0800178 private static final String BANDWIDTH_UINT = "kbps";
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530179 static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
Priyanka B413fbe82016-05-26 11:44:45 +0530180 public static final long IDENTIFIER_SET = 0x100000000L;
181 public static final long SET = 0xFFFFFFFFL;
182 private static final int DELAY = 2;
183 private static final int WAIT_TIME = 5;
184 public static final String LSRID = "lsrId";
cheng fan48e832c2015-05-29 01:54:47 +0800185
chengfan2fff70f2015-08-24 18:20:19 -0500186 static final int POLL_INTERVAL = 10;
187 @Property(name = "tunnelStatsPollFrequency", intValue = POLL_INTERVAL,
188 label = "Frequency (in seconds) for polling tunnel statistics")
189 private int tunnelStatsPollFrequency = POLL_INTERVAL;
190
cheng fan48e832c2015-05-29 01:54:47 +0800191 private static final String TUNNLE_NOT_NULL = "Create failed,The given port may be wrong or has been occupied.";
192
193 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
194 protected TunnelProviderRegistry tunnelProviderRegistry;
195
196 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
197 protected PcepController controller;
198
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530199 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
200 protected PcepClientController pcepClientController;
chengfan2fff70f2015-08-24 18:20:19 -0500201
202 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
203 protected TunnelService tunnelService;
204
205 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
206 protected ComponentConfigService cfgService;
207
Priyanka B413fbe82016-05-26 11:44:45 +0530208 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
209 protected TunnelAdminService tunnelAdminService;
210
211 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
212 protected MastershipService mastershipService;
213
214 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
215 protected DeviceService deviceService;
216
Priyanka Bc1e4e4c2016-07-01 14:57:19 +0530217 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
218 protected LinkService linkService;
219
cheng fan48e832c2015-05-29 01:54:47 +0800220 TunnelProviderService service;
221
222 HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
chengfan2fff70f2015-08-24 18:20:19 -0500223 HashMap<TunnelId, TunnelStatistics> tunnelStatisticsMap = new HashMap<>();
Brian Stanke9a108972016-04-11 15:25:17 -0400224 private HashMap<String, TunnelStatsCollector> collectors = Maps.newHashMap();
cheng fan48e832c2015-05-29 01:54:47 +0800225
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530226 private InnerTunnelProvider listener = new InnerTunnelProvider();
227
Jonathan Hart51539b82015-10-29 09:53:04 -0700228 protected PcepTunnelApiMapper pcepTunnelApiMapper = new PcepTunnelApiMapper();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530229 private static final int DEFAULT_BANDWIDTH_VALUE = 10;
cheng fan48e832c2015-05-29 01:54:47 +0800230
231 /**
232 * Creates a Tunnel provider.
233 */
234 public PcepTunnelProvider() {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530235 super(new ProviderId("pcep", PROVIDER_ID));
cheng fan48e832c2015-05-29 01:54:47 +0800236 }
237
238 @Activate
239 public void activate() {
chengfan2fff70f2015-08-24 18:20:19 -0500240 cfgService.registerProperties(getClass());
cheng fan48e832c2015-05-29 01:54:47 +0800241 service = tunnelProviderRegistry.register(this);
242 controller.addTunnelListener(listener);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530243 pcepClientController.addListener(listener);
244 pcepClientController.addEventListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500245 tunnelService.queryAllTunnels().forEach(tunnel -> {
Jonathan Hart51539b82015-10-29 09:53:04 -0700246 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
chengfan2fff70f2015-08-24 18:20:19 -0500247 TunnelStatsCollector tsc = new TunnelStatsCollector(pcepTunnelId, tunnelStatsPollFrequency);
248 tsc.start();
249 collectors.put(tunnel.tunnelId().id(), tsc);
250
251 });
252
cheng fan48e832c2015-05-29 01:54:47 +0800253 log.info("Started");
254 }
255
256 @Deactivate
257 public void deactivate() {
258 tunnelProviderRegistry.unregister(this);
259 controller.removeTunnelListener(listener);
chengfan2fff70f2015-08-24 18:20:19 -0500260 collectors.values().forEach(TunnelStatsCollector::stop);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530261 pcepClientController.removeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800262 log.info("Stopped");
263 }
264
chengfan2fff70f2015-08-24 18:20:19 -0500265 @Modified
266 public void modified(ComponentContext context) {
267 Dictionary<?, ?> properties = context.getProperties();
268 int newTunnelStatsPollFrequency;
269 try {
270 String s = get(properties, "tunnelStatsPollFrequency");
271 newTunnelStatsPollFrequency = isNullOrEmpty(s) ? tunnelStatsPollFrequency : Integer.parseInt(s.trim());
272
273 } catch (NumberFormatException | ClassCastException e) {
274 newTunnelStatsPollFrequency = tunnelStatsPollFrequency;
275 }
276
277 if (newTunnelStatsPollFrequency != tunnelStatsPollFrequency) {
278 tunnelStatsPollFrequency = newTunnelStatsPollFrequency;
279 collectors.values().forEach(tsc -> tsc.adjustPollInterval(tunnelStatsPollFrequency));
280 log.info("New setting: tunnelStatsPollFrequency={}", tunnelStatsPollFrequency);
281 }
282
283 }
284
cheng fan48e832c2015-05-29 01:54:47 +0800285 @Override
286 public void setupTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530287 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530288 log.error("Tunnel Type MPLS is only supported");
289 return;
290 }
cheng fan48e832c2015-05-29 01:54:47 +0800291
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530292 // check for tunnel end points
293 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
294 log.error("Tunnel source or destination is not valid");
295 return;
296 }
297
298 // Get the pcc client
299 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
300
301 if (!(pc instanceof PcepClient)) {
302 log.error("There is no PCC connected with ip addresss {}"
chengfan2fff70f2015-08-24 18:20:19 -0500303 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530304 return;
305 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530306
307 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
Priyanka B413fbe82016-05-26 11:44:45 +0530308 //Only master will initiate setup tunnel
309 if (pc.capability().pcInstantiationCapability() && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530310 pcepSetupTunnel(tunnel, path, pc);
311 }
cheng fan48e832c2015-05-29 01:54:47 +0800312 }
313
314 @Override
315 public void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800316
Priyanka B4c3cef02016-06-14 20:27:53 +0530317 //TODO: tunnel which is passed doesn't have tunnelID
Avantika-Huawei56c11842016-04-28 00:56:56 +0530318 if (tunnel.annotations().value(PLSP_ID) != null) {
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +0530319 if (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) != WITHOUT_SIGNALLING_AND_WITHOUT_SR) {
320 // For CR LSPs, BGP flow provider will send update message after pushing labels.
321 updateTunnel(tunnel, path);
322 }
Avantika-Huawei56c11842016-04-28 00:56:56 +0530323 return;
324 }
325
326 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530327 log.error("Tunnel Type MPLS is only supported");
328 return;
329 }
330
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530331 // check for tunnel end points
332 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
333 log.error("Tunnel source or destination is not valid");
334 return;
335 }
336
Priyanka Bcdf9b102016-06-07 20:01:38 +0530337 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530338
339 if (!(pc instanceof PcepClient)) {
Priyanka B4c3cef02016-06-14 20:27:53 +0530340 log.error("There is no PCC connected with this device {}"
341 + srcElement.toString());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530342 return;
343 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530344
Priyanka B413fbe82016-05-26 11:44:45 +0530345 //If stateful and PC Initiation capability is not supported by client not sending Initiate msg
346 //Only master will initiate setup tunnel
347 if (pc.capability().pcInstantiationCapability()
348 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530349 pcepSetupTunnel(tunnel, path, pc);
350 }
cheng fan48e832c2015-05-29 01:54:47 +0800351 }
352
353 @Override
354 public void releaseTunnel(Tunnel tunnel) {
cheng fan48e832c2015-05-29 01:54:47 +0800355
Avantika-Huawei56c11842016-04-28 00:56:56 +0530356 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530357 log.error("Tunnel Type MPLS is only supported");
358 return;
359 }
360
361 // check for tunnel end points
362 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
363 log.error("Tunnel source or destination is not valid");
364 return;
365 }
366
367 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
368
369 if (!(pc instanceof PcepClient)) {
370 log.error("There is no PCC connected with ip addresss {}"
371 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
372 return;
373 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530374
Priyanka B413fbe82016-05-26 11:44:45 +0530375 //Only master will release tunnel
376 if (pc.capability().pcInstantiationCapability()
377 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530378 pcepReleaseTunnel(tunnel, pc);
379 }
cheng fan48e832c2015-05-29 01:54:47 +0800380 }
381
382 @Override
383 public void releaseTunnel(ElementId srcElement, Tunnel tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530384 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530385 log.error("Tunnel Type MPLS is only supported");
386 return;
387 }
cheng fan48e832c2015-05-29 01:54:47 +0800388
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530389 if (!(srcElement instanceof IpElementId)) {
390 log.error("Element id is not valid");
391 return;
392 }
393
394 // check for tunnel end points
395 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
396 log.error("Tunnel source or destination is not valid");
397 return;
398 }
399
400 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
401
402 if (!(pc instanceof PcepClient)) {
403 log.error("There is no PCC connected with ip addresss {}"
404 + ((IpElementId) srcElement).ipAddress().toString());
405 return;
406 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530407
Priyanka B413fbe82016-05-26 11:44:45 +0530408 //Only master will release tunnel
409 if (pc.capability().pcInstantiationCapability()
410 && mastershipService.isLocalMaster(getDevice(pc.getPccId()))) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530411 pcepReleaseTunnel(tunnel, pc);
412 }
cheng fan48e832c2015-05-29 01:54:47 +0800413 }
414
415 @Override
416 public void updateTunnel(Tunnel tunnel, Path path) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530417 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530418 log.error("Tunnel Type MPLS is only supported");
419 return;
420 }
cheng fan48e832c2015-05-29 01:54:47 +0800421
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530422 // check for tunnel end points
423 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
424 log.error("Tunnel source or destination is not valid");
425 return;
426 }
427
Priyanka B4c3cef02016-06-14 20:27:53 +0530428 //To get new tunnel ID (modified tunnel ID)
429 Collection<Tunnel> tunnels = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
430 for (Tunnel t : tunnels) {
431 if (t.state().equals(INIT) && t.tunnelName().equals(tunnel.tunnelName())) {
432 tunnel = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
433 tunnel.dst(), tunnel.type(),
434 t.state(), tunnel.groupId(),
435 t.tunnelId(),
436 tunnel.tunnelName(),
437 tunnel.path(),
438 tunnel.resource(),
439 tunnel.annotations());
440 break;
441 }
442 }
443
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530444 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
445
446 if (!(pc instanceof PcepClient)) {
447 log.error("There is no PCC connected with ip addresss {}"
448 + ((IpTunnelEndPoint) tunnel.src()).ip().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.
Priyanka B4c3cef02016-06-14 20:27:53 +0530454 Short localLspId = 0;
455 for (Tunnel t : tunnels) {
456 if (!t.tunnelId().equals(tunnel.tunnelId()) && t.tunnelName().equals(tunnel.tunnelName())) {
457 localLspId = Short.valueOf(t.annotations().value(LOCAL_LSP_ID));
458 }
459 }
460
461 if (localLspId == 0) {
462 log.error("Local LSP ID for old tunnel not found");
463 return;
464 }
465
466 //PCInitiate tunnels are always have D flag set, else check for tunnels who are delegated via LspKey
467 if (pc.capability().statefulPceCapability()) {
468 if (tunnel.annotations().value(PCE_INIT) != null && tunnel.annotations().value(PCE_INIT).equals("true")) {
469 pcepUpdateTunnel(tunnel, path, pc);
470 } else if (pc.delegationInfo(
471 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)),
472 localLspId.shortValue())) != null) {
473 pcepUpdateTunnel(tunnel, path, pc);
474 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530475 }
cheng fan48e832c2015-05-29 01:54:47 +0800476 }
477
478 @Override
479 public void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800480
Avantika-Huawei56c11842016-04-28 00:56:56 +0530481 if (tunnel.type() != MPLS) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530482 log.error("Tunnel Type MPLS is only supported");
483 return;
484 }
485
486 if (!(srcElement instanceof IpElementId)) {
487 log.error("Element id is not valid");
488 return;
489 }
490
491 // check for tunnel end points
492 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
493 log.error("Tunnel source or destination is not valid");
494 return;
495 }
496
497 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
498
499 if (!(pc instanceof PcepClient)) {
500 log.error("There is no PCC connected with ip addresss {}"
501 + ((IpElementId) srcElement).ipAddress().toString());
502 return;
503 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530504
Priyanka B413fbe82016-05-26 11:44:45 +0530505 // If delegation flag is set then only send update message[means delegated PCE can send update msg for that
506 // LSP].If annotation is null D flag is not set else it is set.
507 if (pc.capability().statefulPceCapability()
508 && pc.delegationInfo(
509 new LspKey(Integer.valueOf(tunnel.annotations().value(PLSP_ID)), Short.valueOf(tunnel
510 .annotations().value(LOCAL_LSP_ID)))) != null) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530511 pcepUpdateTunnel(tunnel, path, pc);
512 }
cheng fan48e832c2015-05-29 01:54:47 +0800513 }
514
515 @Override
516 public TunnelId tunnelAdded(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530517 return handleTunnelAdded(tunnel, null);
518 }
519
520 public TunnelId tunnelAdded(TunnelDescription tunnel, State tunnelState) {
521 return handleTunnelAdded(tunnel, tunnelState);
522 }
523
524 private TunnelId handleTunnelAdded(TunnelDescription tunnel, State tunnelState) {
525
526 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700527 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530528
529 if (tunnelState == null) {
530 return service.tunnelAdded(tunnel);
531 } else {
532 return service.tunnelAdded(tunnel, tunnelState);
533 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530534 }
cheng fan48e832c2015-05-29 01:54:47 +0800535
Avantika-Huawei56c11842016-04-28 00:56:56 +0530536 long bandwidth = Long.parseLong(tunnel.annotations().value(BANDWIDTH));
cheng fan48e832c2015-05-29 01:54:47 +0800537
538 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800539 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800540 return null;
541 }
542
543 // endpoints
544 OpticalTunnelEndPoint src = (org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint) tunnel
545 .src();
546 OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst();
547 // devices
548 DeviceId srcId = (DeviceId) src.elementId().get();
549 DeviceId dstId = (DeviceId) dst.elementId().get();
550
551 // ports
552 long srcPort = src.portNumber().get().toLong();
553 long dstPort = dst.portNumber().get().toLong();
554
555 // type
556 if (tunnel.type() != Tunnel.Type.VLAN) {
cheng fan7716ec92015-05-31 01:53:19 +0800557 error("Illegal tunnel type. Only support VLAN tunnel creation.");
cheng fan48e832c2015-05-29 01:54:47 +0800558 return null;
559 }
560
561 PcepTunnel pcepTunnel = controller.applyTunnel(srcId, dstId, srcPort,
562 dstPort, bandwidth,
563 tunnel.tunnelName()
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530564 .value());
cheng fan48e832c2015-05-29 01:54:47 +0800565
566 checkNotNull(pcepTunnel, TUNNLE_NOT_NULL);
567 TunnelDescription tunnelAdded = buildOpticalTunnel(pcepTunnel, null);
568 TunnelId tunnelId = service.tunnelAdded(tunnelAdded);
569
570 tunnelMap.put(String.valueOf(pcepTunnel.id()), tunnelId);
571 return tunnelId;
572 }
573
Priyanka B413fbe82016-05-26 11:44:45 +0530574 private void tunnelUpdated(Tunnel tunnel, Path path) {
575 handleTunnelUpdate(tunnel, path);
576 }
577
578 //Handles tunnel updated using tunnel admin service[specially to update annotations].
579 private void handleTunnelUpdate(Tunnel tunnel, Path path) {
580
581 if (tunnel.type() == MPLS) {
582 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.tunnelId());
583
584 tunnelAdminService.updateTunnel(tunnel, path);
585
586 return;
587 }
588
589 Tunnel tunnelOld = tunnelQueryById(tunnel.tunnelId());
590 if (tunnelOld.type() != Tunnel.Type.VLAN) {
591 error("Illegal tunnel type. Only support VLAN tunnel update.");
592 return;
593 }
594
595 long bandwidth = Long
596 .parseLong(tunnel.annotations().value("bandwidth"));
597 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
598 error("Update failed, invalid bandwidth.");
599 return;
600 }
601 String pcepTunnelId = getPcepTunnelKey(tunnel.tunnelId());
602
603 checkNotNull(pcepTunnelId, "Invalid tunnel id");
604 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
605 error("Update failed,maybe invalid bandwidth.");
606 return;
607 }
608 tunnelAdminService.updateTunnel(tunnel, path);
609 }
610
cheng fan48e832c2015-05-29 01:54:47 +0800611 @Override
612 public void tunnelRemoved(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530613 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700614 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530615 service.tunnelRemoved(tunnel);
Priyanka Bc1e4e4c2016-07-01 14:57:19 +0530616 return;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530617 }
618
cheng fan48e832c2015-05-29 01:54:47 +0800619 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
620 checkNotNull(tunnelOld, "The tunnel id is not exsited.");
621 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800622 error("Illegal tunnel type. Only support VLAN tunnel deletion.");
cheng fan48e832c2015-05-29 01:54:47 +0800623 return;
624 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700625 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800626 checkNotNull(pcepTunnelId, "The tunnel id is not exsited.");
cheng fan7716ec92015-05-31 01:53:19 +0800627 if (!controller.deleteTunnel(pcepTunnelId)) {
628 error("Delete tunnel failed, Maybe some devices have been disconnected.");
629 return;
cheng fan48e832c2015-05-29 01:54:47 +0800630 }
631 tunnelMap.remove(pcepTunnelId);
632 service.tunnelRemoved(tunnel);
cheng fan48e832c2015-05-29 01:54:47 +0800633 }
634
635 @Override
636 public void tunnelUpdated(TunnelDescription tunnel) {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530637 handleTunnelUpdate(tunnel, null);
638 }
639
640 public void tunnelUpdated(TunnelDescription tunnel, State tunnelState) {
641 handleTunnelUpdate(tunnel, tunnelState);
642 }
643
644 private void handleTunnelUpdate(TunnelDescription tunnel, State tunnelState) {
645 if (tunnel.type() == MPLS) {
Jonathan Hart51539b82015-10-29 09:53:04 -0700646 pcepTunnelApiMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
Avantika-Huawei56c11842016-04-28 00:56:56 +0530647
648 if (tunnelState == null) {
649 service.tunnelUpdated(tunnel);
650 } else {
651 service.tunnelUpdated(tunnel, tunnelState);
652 }
653 return;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530654 }
cheng fan48e832c2015-05-29 01:54:47 +0800655
656 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
657 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800658 error("Illegal tunnel type. Only support VLAN tunnel update.");
cheng fan48e832c2015-05-29 01:54:47 +0800659 return;
660 }
cheng fan7716ec92015-05-31 01:53:19 +0800661 long bandwidth = Long
662 .parseLong(tunnel.annotations().value("bandwidth"));
cheng fan48e832c2015-05-29 01:54:47 +0800663 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800664 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800665 return;
666 }
Jonathan Hart51539b82015-10-29 09:53:04 -0700667 String pcepTunnelId = getPcepTunnelKey(tunnel.id());
cheng fan48e832c2015-05-29 01:54:47 +0800668
669 checkNotNull(pcepTunnelId, "Invalid tunnel id");
670 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
671
cheng fan7716ec92015-05-31 01:53:19 +0800672 error("Update failed,maybe invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800673 return;
674
675 }
676 service.tunnelUpdated(tunnel);
677 }
678
cheng fan7716ec92015-05-31 01:53:19 +0800679 private void error(String info) {
680 System.err.println(info);
681 }
682
cheng fan48e832c2015-05-29 01:54:47 +0800683 // Short-hand for creating a connection point.
684 private ConnectPoint connectPoint(PcepDpid id, long port) {
685 return new ConnectPoint(deviceId(uri(id)), portNumber(port));
686 }
687
688 // Short-hand for creating a link.
689 private Link link(PcepDpid src, long sp, PcepDpid dst, long dp) {
Ray Milkey2693bda2016-01-22 16:08:14 -0800690 return DefaultLink.builder()
691 .providerId(id())
692 .src(connectPoint(src, sp))
693 .dst(connectPoint(dst, dp))
694 .type(Link.Type.TUNNEL)
695 .build();
cheng fan48e832c2015-05-29 01:54:47 +0800696 }
697
698 // Creates a path that leads through the given devices.
699 private Path createPath(List<PcepHopNodeDescription> hopList,
Jonathan Hart51539b82015-10-29 09:53:04 -0700700 PathType pathtype, PathState pathState) {
cheng fan48e832c2015-05-29 01:54:47 +0800701 if (hopList == null || hopList.size() == 0) {
702 return null;
703 }
704 List<Link> links = new ArrayList<>();
705 for (int i = 1; i < hopList.size() - 1; i = i + 2) {
706 links.add(link(hopList.get(i).getDeviceId(), hopList.get(i)
707 .getPortNum(), hopList.get(i + 1).getDeviceId(), hopList
708 .get(i + 1).getPortNum()));
709 }
710
711 int hopNum = hopList.size() - 2;
712 DefaultAnnotations extendAnnotations = DefaultAnnotations.builder()
713 .set("pathNum", String.valueOf(hopNum))
cheng fan93258c72015-06-02 23:42:32 +0800714 .set("pathState", String.valueOf(pathState))
cheng fan48e832c2015-05-29 01:54:47 +0800715 .set("pathType", String.valueOf(pathtype)).build();
716 return new DefaultPath(id(), links, hopNum, extendAnnotations);
717 }
718
719 // convert the path description to a string.
720 public String pathToString(List<Link> links) {
721 StringBuilder builder = new StringBuilder();
722 builder.append("{");
723 for (Link link : links) {
724 builder.append("(Device:" + link.src().deviceId() + " Port:"
725 + link.src().port().toLong());
726 builder.append(" Device:" + link.dst().deviceId() + " Port:"
727 + link.dst().port().toLong());
728 builder.append(")");
729 }
730 builder.append("}");
731 return builder.toString();
732 }
733
734 // build a TunnelDescription.
735 private TunnelDescription buildOpticalTunnel(PcepTunnel pcepTunnel,
736 TunnelId tunnelId) {
737 TunnelEndPoint srcPoint = null;
738 TunnelEndPoint dstPoint = null;
739 Tunnel.Type tunnelType = null;
740 TunnelName name = TunnelName.tunnelName(pcepTunnel.name());
741
742 // add path after codes of tunnel's path merged
743 Path path = createPath(pcepTunnel.getHopList(),
cheng fan93258c72015-06-02 23:42:32 +0800744 pcepTunnel.getPathType(),
745 pcepTunnel.getPathState());
cheng fan48e832c2015-05-29 01:54:47 +0800746
747 OpticalTunnelEndPoint.Type endPointType = null;
748 switch (pcepTunnel.type()) {
749 case OCH:
750 tunnelType = Tunnel.Type.OCH;
751 endPointType = OpticalTunnelEndPoint.Type.LAMBDA;
752 break;
753
754 case OTN:
755 tunnelType = Tunnel.Type.ODUK;
756 endPointType = OpticalTunnelEndPoint.Type.TIMESLOT;
757 break;
758
759 case UNI:
760 tunnelType = Tunnel.Type.VLAN;
761 endPointType = null;
762 break;
763
764 default:
765 break;
766 }
767 DeviceId srcDid = deviceId(uri(pcepTunnel.srcDeviceID()));
768 DeviceId dstDid = deviceId(uri(pcepTunnel.dstDeviceId()));
769 PortNumber srcPort = PortNumber.portNumber(pcepTunnel.srcPort());
770 PortNumber dstPort = PortNumber.portNumber(pcepTunnel.dstPort());
771
772 srcPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(srcDid),
773 Optional.of(srcPort), null,
774 endPointType,
775 OpticalLogicId.logicId(0),
776 true);
777 dstPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(dstDid),
778 Optional.of(dstPort), null,
779 endPointType,
780 OpticalLogicId.logicId(0),
781 true);
782
783 // basic annotations
cheng fan7716ec92015-05-31 01:53:19 +0800784 DefaultAnnotations annotations = DefaultAnnotations
785 .builder()
cheng fan48e832c2015-05-29 01:54:47 +0800786 .set("SLA", String.valueOf(pcepTunnel.getSla()))
cheng fan7716ec92015-05-31 01:53:19 +0800787 .set("bandwidth",
788 String.valueOf(pcepTunnel.bandWidth()) + BANDWIDTH_UINT)
cheng fan48e832c2015-05-29 01:54:47 +0800789 .set("index", String.valueOf(pcepTunnel.id())).build();
790
cheng fan48e832c2015-05-29 01:54:47 +0800791 // a VLAN tunnel always carry OCH tunnel, this annotation is the index
792 // of a OCH tunnel.
cheng fan93258c72015-06-02 23:42:32 +0800793 if (pcepTunnel.underlayTunnelId() != 0) {
cheng fan48e832c2015-05-29 01:54:47 +0800794 DefaultAnnotations extendAnnotations = DefaultAnnotations
795 .builder()
796 .set("underLayTunnelIndex",
cheng fan93258c72015-06-02 23:42:32 +0800797 String.valueOf(pcepTunnel.underlayTunnelId())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800798 annotations = DefaultAnnotations.merge(annotations,
799 extendAnnotations);
800
801 }
802 TunnelDescription tunnel = new DefaultTunnelDescription(
803 tunnelId,
804 srcPoint,
805 dstPoint,
806 tunnelType,
807 new DefaultGroupId(
808 0),
809 id(), name,
810 path,
811 annotations);
812 return tunnel;
cheng fan48e832c2015-05-29 01:54:47 +0800813 }
814
815 /**
816 * Get the tunnelID according to the tunnel key.
817 *
818 * @param tunnelKey tunnel key
819 * @return corresponding tunnel id of the a tunnel key.
820 */
821 private TunnelId getTunnelId(String tunnelKey) {
cheng fan48e832c2015-05-29 01:54:47 +0800822 for (String key : tunnelMap.keySet()) {
823 if (key.equals(tunnelKey)) {
824 return tunnelMap.get(key);
825 }
826 }
827 return null;
828 }
829
830 /**
831 * Get the tunnel key according to the tunnelID.
832 *
833 * @param tunnelId tunnel id
834 * @return corresponding a tunnel key of the tunnel id.
835 */
Jonathan Hart51539b82015-10-29 09:53:04 -0700836 private String getPcepTunnelKey(TunnelId tunnelId) {
cheng fan48e832c2015-05-29 01:54:47 +0800837 for (String key : tunnelMap.keySet()) {
838 if (tunnelMap.get(key).id() == tunnelId.id()) {
839 return key;
840 }
841 }
842 return null;
843
844 }
845
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530846 /**
chengfan2fff70f2015-08-24 18:20:19 -0500847 * Build a DefaultTunnelStatistics from a PcepTunnelStatistics.
848 *
849 * @param statistics statistics data from a PCEP tunnel
850 * @return TunnelStatistics
851 */
852 private TunnelStatistics buildTunnelStatistics(PcepTunnelStatistics statistics) {
853 DefaultTunnelStatistics.Builder builder = new DefaultTunnelStatistics.Builder();
854 DefaultTunnelStatistics tunnelStatistics = builder.setBwUtilization(statistics.bandwidthUtilization())
855 .setPacketLossRatio(statistics.packetLossRate())
856 .setFlowDelay(statistics.flowDelay())
857 .setAlarms(statistics.alarms())
858 .build();
859 return tunnelStatistics;
860 }
861 /**
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530862 * Creates list of hops for ERO object from Path.
863 *
864 * @param path network path
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530865 * @return list of ERO subobjects
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530866 */
867 private LinkedList<PcepValueType> createPcepPath(Path path) {
868 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
869 List<Link> listLink = path.links();
870 ConnectPoint source = null;
871 ConnectPoint destination = null;
872 IpAddress ipDstAddress = null;
873 IpAddress ipSrcAddress = null;
874 PcepValueType subObj = null;
Priyanka Bcdf9b102016-06-07 20:01:38 +0530875 long portNo;
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530876
877 for (Link link : listLink) {
878 source = link.src();
879 if (!(source.equals(destination))) {
880 //set IPv4SubObject for ERO object
Priyanka Bcdf9b102016-06-07 20:01:38 +0530881 portNo = source.port().toLong();
882 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
883 ipSrcAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530884 subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
885 llSubObjects.add(subObj);
886 }
887
888 destination = link.dst();
Priyanka Bcdf9b102016-06-07 20:01:38 +0530889 portNo = destination.port().toLong();
890 portNo = ((portNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? portNo & SET : portNo;
891 ipDstAddress = Ip4Address.valueOf((int) portNo);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530892 subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
893 llSubObjects.add(subObj);
894 }
Priyanka Bcdf9b102016-06-07 20:01:38 +0530895
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530896 return llSubObjects;
897 }
898
899 /**
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530900 * Creates label stack for ERO object from network resource.
901 *
902 * @param labelStack
903 * @param path (hop list)
904 * @return list of ERO subobjects
905 */
906 private LinkedList<PcepValueType> createPcepLabelStack(DefaultLabelStack labelStack, Path path) {
907 checkNotNull(labelStack);
908
909 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
910 Iterator<Link> links = path.links().iterator();
911 LabelResourceId label = null;
912 Link link = null;
913 PcepValueType subObj = null;
914 PcepNai nai = null;
915 Device dstNode = null;
916 long srcPortNo, dstPortNo;
917
918 ListIterator<LabelResourceId> labelListIterator = labelStack.labelResources().listIterator();
919 while (labelListIterator.hasNext()) {
920 label = labelListIterator.next();
921 link = links.next();
922
923 srcPortNo = link.src().port().toLong();
924 srcPortNo = ((srcPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? srcPortNo & SET : srcPortNo;
925
926 dstPortNo = link.dst().port().toLong();
927 dstPortNo = ((dstPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? dstPortNo & SET : dstPortNo;
928
929 nai = new PcepNaiIpv4Adjacency((int) srcPortNo, (int) dstPortNo);
930 subObj = new SrEroSubObject(PcepNaiIpv4Adjacency.ST_TYPE, false, false, false, true, (int) label.labelId(),
931 nai);
932 llSubObjects.add(subObj);
933
934 dstNode = deviceService.getDevice(link.dst().deviceId());
935 nai = new PcepNaiIpv4NodeId(Ip4Address.valueOf(dstNode.annotations().value(LSRID)).toInt());
936
937 if (!labelListIterator.hasNext()) {
938 log.error("Malformed label stack.");
939 }
940 label = labelListIterator.next();
941 subObj = new SrEroSubObject(PcepNaiIpv4NodeId.ST_TYPE, false, false, false, true, (int) label.labelId(),
942 nai);
943 llSubObjects.add(subObj);
944 }
945 return llSubObjects;
946 }
947
948 /**
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530949 * Creates PcInitiated lsp request list for setup tunnel.
950 *
951 * @param tunnel mpls tunnel
952 * @param path network path
953 * @param pc pcep client
954 * @param srpId unique id for pcep message
955 * @return list of PcInitiatedLspRequest
956 * @throws PcepParseException while building pcep objects fails
957 */
958 LinkedList<PcInitiatedLspRequest> createPcInitiatedLspReqList(Tunnel tunnel, Path path,
959 PcepClient pc, int srpId)
960 throws PcepParseException {
961 PcepValueType tlv;
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530962 LinkedList<PcepValueType> llSubObjects = null;
963
964 NetworkResource labelStack = tunnel.resource();
965 if (labelStack != null && labelStack instanceof DefaultLabelStack) {
966 llSubObjects = createPcepLabelStack((DefaultLabelStack) labelStack, path);
967 } else {
968 llSubObjects = createPcepPath(path);
969 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530970
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700971 if (llSubObjects == null || llSubObjects.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530972 log.error("There is no link information to create tunnel");
973 return null;
974 }
975
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530976 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530977
978 // set PathSetupTypeTlv of SRP object
979 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)).type());
980 llOptionalTlv.add(tlv);
981
982 // build SRP object
983 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
984 .setOptionalTlv(llOptionalTlv).build();
985
986 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530987 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530988
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530989 // set LSP identifiers TLV
Avantika-Huawei56c11842016-04-28 00:56:56 +0530990 short localLspId = 0;
991 if (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) != WITH_SIGNALLING) {
992 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
993 if (localLspIdString != null) {
994 localLspId = Short.valueOf(localLspIdString);
995 }
996 }
997
Priyanka B4c3cef02016-06-14 20:27:53 +0530998 tunnel.annotations().value(LSP_SIG_TYPE);
Avantika-Huawei56c11842016-04-28 00:56:56 +0530999 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
1000 localLspId, (short) 0, 0, (((IpTunnelEndPoint) tunnel.dst()).ip()
1001 .getIp4Address().toInt()));
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301002 llOptionalTlv.add(tlv);
1003 //set SymbolicPathNameTlv of LSP object
1004 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1005 llOptionalTlv.add(tlv);
1006
1007 //build LSP object
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301008 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setDFlag(true).setOFlag((byte) 0)
1009 .setPlspId(0).setOptionalTlv(llOptionalTlv).build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301010
1011 //build ENDPOINTS object
1012 PcepEndPointsObject endpointsobj = pc.factory().buildEndPointsObject()
1013 .setSourceIpAddress(((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt())
1014 .setDestIpAddress(((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt())
1015 .setPFlag(true).build();
1016
1017 //build ERO object
1018 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
1019
Priyanka Bc1e4e4c2016-07-01 14:57:19 +05301020 float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +05301021 if (tunnel.annotations().value(BANDWIDTH) != null) {
Priyanka Bc1e4e4c2016-07-01 14:57:19 +05301022 iBandwidth = Float.valueOf(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301023 }
1024 // build bandwidth object
1025 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
1026 // build pcep attribute
1027 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
1028
1029 PcInitiatedLspRequest initiateLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
1030 .setLspObject(lspobj).setEndPointsObject(endpointsobj).setEroObject(eroobj)
1031 .setPcepAttribute(pcepAttribute).build();
1032 llPcInitiatedLspRequestList.add(initiateLspRequest);
1033 return llPcInitiatedLspRequestList;
1034 }
1035
1036 /**
1037 * To send initiate tunnel message to pcc.
1038 *
1039 * @param tunnel mpls tunnel info
1040 * @param path explicit route for the tunnel
1041 * @param pc pcep client to send message
1042 */
1043 private void pcepSetupTunnel(Tunnel tunnel, Path path, PcepClient pc) {
1044 try {
MaheshRaju-Huaweibb591072016-06-17 17:47:16 +05301045 if (!(pc.lspDbSyncStatus().equals(PcepSyncStatus.SYNCED))) {
1046 log.error("Setup tunnel has failed as LSP DB sync is not finished");
1047 return;
1048 }
1049
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301050 int srpId = SrpIdGenerators.create();
Priyanka B4c3cef02016-06-14 20:27:53 +05301051 Collection<Tunnel> tunnels = tunnelService.queryTunnel(tunnel.src(), tunnel.dst());
1052 for (Tunnel t : tunnels) {
1053 if (t.tunnelName().equals(tunnel.tunnelName())) {
1054 tunnel = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
1055 tunnel.dst(), tunnel.type(),
1056 t.state(), tunnel.groupId(),
1057 t.tunnelId(),
1058 tunnel.tunnelName(),
1059 tunnel.path(),
1060 tunnel.resource(),
1061 tunnel.annotations());
1062 break;
1063 }
1064 }
1065
1066 if (tunnel.tunnelId() == null) {
1067 log.error("Tunnel ID not found");
1068 return;
1069 }
1070
Avantika-Huawei56c11842016-04-28 00:56:56 +05301071 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, CREATE);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301072
Jonathan Hart51539b82015-10-29 09:53:04 -07001073 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301074
1075 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = createPcInitiatedLspReqList(tunnel, path,
1076 pc, srpId);
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001077 if (llPcInitiatedLspRequestList == null || llPcInitiatedLspRequestList.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301078 log.error("Failed to create PcInitiatedLspRequestList");
1079 return;
1080 }
1081
1082 //build PCInitiate message
1083 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1084 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList)
1085 .build();
1086
1087 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1088
Jonathan Hart51539b82015-10-29 09:53:04 -07001089 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301090 } catch (PcepParseException e) {
1091 log.error("PcepParseException occurred while processing setup tunnel {}", e.getMessage());
1092 }
1093 }
1094
1095 /**
1096 * To send Release tunnel message to pcc.
1097 *
1098 * @param tunnel mpls tunnel info
1099 * @param pc pcep client to send message
1100 */
1101 private void pcepReleaseTunnel(Tunnel tunnel, PcepClient pc) {
1102 try {
MaheshRaju-Huaweibb591072016-06-17 17:47:16 +05301103 if (!(pc.lspDbSyncStatus().equals(PcepSyncStatus.SYNCED))) {
1104 log.error("Release tunnel has failed as LSP DB sync is not finished");
1105 return;
1106 }
1107
Avantika-Huawei56c11842016-04-28 00:56:56 +05301108 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, DELETE);
Jonathan Hart51539b82015-10-29 09:53:04 -07001109 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301110 int srpId = SrpIdGenerators.create();
1111 TunnelId tunnelId = tunnel.tunnelId();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301112
1113 PcepValueType tlv;
1114 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301115
1116 // set PathSetupTypeTlv of SRP object
1117 tlv = new PathSetupTypeTlv(LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))
1118 .type());
1119 llOptionalTlv.add(tlv);
1120
1121 // build SRP object
1122 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(true)
1123 .setOptionalTlv(llOptionalTlv).build();
1124
1125 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301126 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
1127
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301128 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1129 llOptionalTlv.add(tlv);
Priyanka B4c3cef02016-06-14 20:27:53 +05301130
1131 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
1132 String pccTunnelIdString = tunnel.annotations().value(PCC_TUNNEL_ID);
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301133 String pLspIdString = tunnel.annotations().value(PLSP_ID);
1134
Priyanka B4c3cef02016-06-14 20:27:53 +05301135 short localLspId = 0;
1136 short pccTunnelId = 0;
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301137 int plspId = 0;
Priyanka B4c3cef02016-06-14 20:27:53 +05301138
1139 if (localLspIdString != null) {
1140 localLspId = Short.valueOf(localLspIdString);
1141 }
1142
1143 if (pccTunnelIdString != null) {
1144 pccTunnelId = Short.valueOf(pccTunnelIdString);
1145 }
1146
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301147 if (pLspIdString != null) {
1148 plspId = Integer.valueOf(pLspIdString);
1149 }
1150
Priyanka B4c3cef02016-06-14 20:27:53 +05301151 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 // build lsp object, set r flag as false to delete the tunnel
1158 PcepLspObject lspobj = pc.factory().buildLspObject().setRFlag(false).setPlspId(plspId)
1159 .setOptionalTlv(llOptionalTlv).build();
1160
1161 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
1162 .setLspObject(lspobj).build();
1163
1164 llPcInitiatedLspRequestList.add(releaseLspRequest);
1165
1166 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1167 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1168
1169 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
1170
Jonathan Hart51539b82015-10-29 09:53:04 -07001171 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301172 } catch (PcepParseException e) {
1173 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1174 }
1175 }
1176
1177 /**
1178 * To send Update tunnel request message to pcc.
1179 *
1180 * @param tunnel mpls tunnel info
1181 * @param path explicit route for the tunnel
1182 * @param pc pcep client to send message
1183 */
1184 private void pcepUpdateTunnel(Tunnel tunnel, Path path, PcepClient pc) {
1185 try {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301186 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, UPDATE);
Jonathan Hart51539b82015-10-29 09:53:04 -07001187 pcepTunnelApiMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301188 int srpId = SrpIdGenerators.create();
1189 TunnelId tunnelId = tunnel.tunnelId();
1190 PcepValueType tlv;
1191 int plspId = 0;
1192
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301193 LinkedList<PcepValueType> llSubObjects = null;
1194 NetworkResource labelStack = tunnel.resource();
1195 if (labelStack != null && labelStack instanceof DefaultLabelStack) {
1196 llSubObjects = createPcepLabelStack((DefaultLabelStack) labelStack, path);
1197 } else {
1198 llSubObjects = createPcepPath(path);
1199 }
1200
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301201 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
1202 LinkedList<PcepUpdateRequest> llUpdateRequestList = new LinkedList<PcepUpdateRequest>();
1203
Avantika-Huawei56c11842016-04-28 00:56:56 +05301204 // set PathSetupTypeTlv of SRP object
1205 LspType lspSigType = LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE));
1206 tlv = new PathSetupTypeTlv(lspSigType.type());
1207 llOptionalTlv.add(tlv);
1208
1209 // build SRP object
1210 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false)
1211 .setOptionalTlv(llOptionalTlv).build();
1212
1213 llOptionalTlv = new LinkedList<PcepValueType>();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301214
Avantika-Huawei56c11842016-04-28 00:56:56 +05301215 if (lspSigType != WITH_SIGNALLING) {
1216 String localLspIdString = tunnel.annotations().value(LOCAL_LSP_ID);
1217 String pccTunnelIdString = tunnel.annotations().value(PCC_TUNNEL_ID);
1218 short localLspId = 0;
1219 short pccTunnelId = 0;
1220
1221 if (localLspIdString != null) {
1222 localLspId = Short.valueOf(localLspIdString);
1223 }
1224
1225 if (pccTunnelIdString != null) {
1226 pccTunnelId = Short.valueOf(pccTunnelIdString);
1227 }
1228
1229 tlv = new StatefulIPv4LspIdentifiersTlv((((IpTunnelEndPoint) tunnel.src())
1230 .ip().getIp4Address().toInt()),
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301231 localLspId, pccTunnelId,
1232 ((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt(),
1233 (((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt()));
Avantika-Huawei56c11842016-04-28 00:56:56 +05301234 llOptionalTlv.add(tlv);
1235 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301236
1237 if (tunnel.tunnelName().value() != null) {
1238 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
1239 llOptionalTlv.add(tlv);
1240 }
1241
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301242 boolean delegated = (tunnel.annotations().value(DELEGATE) == null) ? false
1243 : Boolean.valueOf(tunnel.annotations()
1244 .value(DELEGATE));
1245 boolean initiated = (tunnel.annotations().value(PCE_INIT) == null) ? false
1246 : Boolean.valueOf(tunnel.annotations()
1247 .value(PCE_INIT));
1248
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301249 // build lsp object
Priyanka B4c3cef02016-06-14 20:27:53 +05301250 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true)
1251 .setPlspId(Integer.valueOf(tunnel.annotations().value(PLSP_ID)))
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301252 .setDFlag(delegated)
1253 .setCFlag(initiated)
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301254 .setOptionalTlv(llOptionalTlv).build();
1255 // build ero object
1256 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
1257
Priyanka B4c3cef02016-06-14 20:27:53 +05301258 float iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Avantika-Huawei56c11842016-04-28 00:56:56 +05301259 if (tunnel.annotations().value(BANDWIDTH) != null) {
Priyanka B4c3cef02016-06-14 20:27:53 +05301260 iBandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301261 }
1262 // build bandwidth object
1263 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
1264 // build pcep attribute
1265 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
1266 // build pcep msg path
1267 PcepMsgPath msgPath = pc.factory().buildPcepMsgPath().setEroObject(eroobj).setPcepAttribute(pcepAttribute)
1268 .build();
1269
1270 PcepUpdateRequest updateRequest = pc.factory().buildPcepUpdateRequest().setSrpObject(srpobj)
1271 .setLspObject(lspobj).setMsgPath(msgPath).build();
1272
1273 llUpdateRequestList.add(updateRequest);
1274
1275 PcepUpdateMsg pcUpdateMsg = pc.factory().buildUpdateMsg().setUpdateRequestList(llUpdateRequestList).build();
1276
1277 pc.sendMessage(Collections.singletonList(pcUpdateMsg));
Jonathan Hart51539b82015-10-29 09:53:04 -07001278 pcepTunnelApiMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301279 } catch (PcepParseException e) {
1280 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
1281 }
1282 }
1283
chengfan2fff70f2015-08-24 18:20:19 -05001284
1285
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301286 private class InnerTunnelProvider implements PcepTunnelListener, PcepEventListener, PcepClientListener {
cheng fan48e832c2015-05-29 01:54:47 +08001287
1288 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -07001289 public void handlePcepTunnel(PcepTunnel pcepTunnel) {
cheng fan48e832c2015-05-29 01:54:47 +08001290 TunnelDescription tunnel = null;
1291 // instance and id identify a tunnel together
1292 String tunnelKey = String.valueOf(pcepTunnel.getInstance())
1293 + String.valueOf(pcepTunnel.id());
1294
1295 if (tunnelKey == null || "".equals(tunnelKey)) {
1296 log.error("Invalid PCEP tunnel");
1297 return;
1298 }
1299
1300 TunnelId tunnelId = getTunnelId(tunnelKey);
1301
1302 tunnel = buildOpticalTunnel(pcepTunnel, tunnelId);
1303
1304 OperationType operType = pcepTunnel.getOperationType();
1305 switch (operType) {
1306 case ADD:
1307 tunnelId = service.tunnelAdded(tunnel);
1308 tunnelMap.put(tunnelKey, tunnelId);
1309 break;
1310
1311 case UPDATE:
1312 service.tunnelUpdated(tunnel);
1313 break;
1314
1315 case DELETE:
1316 service.tunnelRemoved(tunnel);
1317 tunnelMap.remove(tunnelKey);
1318 break;
1319
1320 default:
1321 log.error("Invalid tunnel operation");
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301322 }
1323 }
cheng fan48e832c2015-05-29 01:54:47 +08001324
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301325 @Override
1326 public void handleMessage(PccId pccId, PcepMessage msg) {
1327 try {
1328 log.debug("tunnel provider handle message {}", msg.getType().toString());
1329 switch (msg.getType()) {
1330 case REPORT:
1331 int srpId = 0;
1332 LinkedList<PcepStateReport> llStateReportList = null;
1333 llStateReportList = ((PcepReportMsg) msg).getStateReportList();
1334 ListIterator<PcepStateReport> listIterator = llStateReportList.listIterator();
1335 PcepSrpObject srpObj = null;
1336 PcepLspObject lspObj = null;
1337 while (listIterator.hasNext()) {
1338 PcepStateReport stateRpt = listIterator.next();
1339 srpObj = stateRpt.getSrpObject();
1340 lspObj = stateRpt.getLspObject();
1341
1342 if (srpObj instanceof PcepSrpObject) {
1343 srpId = srpObj.getSrpID();
1344 }
1345
1346 log.debug("Plsp ID in handle message " + lspObj.getPlspId());
1347 log.debug("SRP ID in handle message " + srpId);
1348
Jonathan Hart51539b82015-10-29 09:53:04 -07001349 if (!(pcepTunnelApiMapper.checkFromTunnelRequestQueue(srpId))) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301350 // For PCRpt without matching SRP id.
1351 handleRptWithoutSrpId(stateRpt, pccId);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301352 continue;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301353 }
1354
Avantika-Huawei56c11842016-04-28 00:56:56 +05301355 handleReportMessage(srpId, lspObj, stateRpt);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301356 }
1357 break;
1358
1359 default:
1360 log.debug("Received unsupported message type {}", msg.getType().toString());
1361 }
1362 } catch (Exception e) {
1363 log.error("Exception occured while processing report message {}", e.getMessage());
1364 }
1365 }
1366
1367 /**
1368 * Handles report message for setup/update/delete tunnel request.
1369 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301370 * @param srpId unique identifier for PCEP message
1371 * @param lspObj LSP object
1372 * @param stateRpt parsed PCEP report msg.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301373 */
Avantika-Huawei56c11842016-04-28 00:56:56 +05301374 private void handleReportMessage(int srpId, PcepLspObject lspObj, PcepStateReport stateRpt) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301375 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Jonathan Hart51539b82015-10-29 09:53:04 -07001376 PcepTunnelData pcepTunnelData = pcepTunnelApiMapper.getDataFromTunnelRequestQueue(srpId);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301377
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301378 // store the values required from report message
1379 pcepTunnelData.setPlspId(lspObj.getPlspId());
1380 pcepTunnelData.setLspAFlag(lspObj.getAFlag());
1381 pcepTunnelData.setLspOFlag(lspObj.getOFlag());
1382 pcepTunnelData.setLspDFlag(lspObj.getDFlag());
1383
Avantika-Huawei56c11842016-04-28 00:56:56 +05301384 StatefulIPv4LspIdentifiersTlv ipv4LspTlv = null;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301385 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1386 while (listTlvIterator.hasNext()) {
1387 PcepValueType tlv = listTlvIterator.next();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301388 if (tlv.getType() == StatefulIPv4LspIdentifiersTlv.TYPE) {
1389 ipv4LspTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301390 break;
1391 }
1392 }
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001393 if (ipv4LspTlv != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301394 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspTlv);
cheng fan48e832c2015-05-29 01:54:47 +08001395 }
1396
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301397 Path path = pcepTunnelData.path();
1398 Tunnel tunnel = pcepTunnelData.tunnel();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301399 Builder annotationBuilder = DefaultAnnotations.builder();
1400 annotationBuilder.putAll(pcepTunnelData.tunnel().annotations());
1401
1402 // PCRpt in response to PCInitate msg will carry PLSP id allocated by PCC.
1403 if (tunnel.annotations().value(PLSP_ID) == null) {
1404 annotationBuilder.set(PLSP_ID, String.valueOf(lspObj.getPlspId()));
1405 }
1406
1407 // Signalled LSPs will carry local LSP id allocated by signalling protocol(PCC).
1408 if (tunnel.annotations().value(LOCAL_LSP_ID) == null) {
1409 annotationBuilder.set(LOCAL_LSP_ID, String.valueOf(ipv4LspTlv.getLspId()));
1410 }
1411
Priyanka B4c3cef02016-06-14 20:27:53 +05301412 if (tunnel.annotations().value(PCC_TUNNEL_ID) == null) {
1413 annotationBuilder.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspTlv.getTunnelId()));
1414 }
1415
Avantika-Huawei56c11842016-04-28 00:56:56 +05301416 SparseAnnotations annotations = annotationBuilder.build();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301417 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(),
1418 tunnel.dst(), tunnel.type(), tunnel.groupId(),
1419 providerId, tunnel.tunnelName(), path,
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301420 tunnel.resource(), annotations);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301421
Avantika-Huawei56c11842016-04-28 00:56:56 +05301422 if (CREATE == pcepTunnelData.requestType()) {
Priyanka B4c3cef02016-06-14 20:27:53 +05301423 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
Jonathan Hart51539b82015-10-29 09:53:04 -07001424 pcepTunnelApiMapper.handleCreateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301425 } else if (DELETE == pcepTunnelData.requestType()) {
Jonathan Hart51539b82015-10-29 09:53:04 -07001426 pcepTunnelApiMapper.handleRemoveFromTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301427 } else if (UPDATE == pcepTunnelData.requestType()) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301428 pcepTunnelData.setRptFlag(true);
Jonathan Hart51539b82015-10-29 09:53:04 -07001429 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1430 pcepTunnelApiMapper.handleUpdateTunnelRequestQueue(srpId, pcepTunnelData);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301431 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301432
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301433 PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
1434
Avantika-Huawei56c11842016-04-28 00:56:56 +05301435 if (lspObj.getRFlag()) {
1436 tunnelRemoved(td);
1437 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301438 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(pcepLspStatus);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301439 tunnelUpdated(td, tunnelState);
1440 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301441
1442 // SR-TE also needs PCUpd msg after receiving PCRpt with status GOING-UP even
1443 // though there are no labels to download for SR-TE.
1444 if ((pcepLspStatus == PcepLspStatus.GOING_UP)
1445 && (LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE)) == SR_WITHOUT_SIGNALLING)) {
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301446 // Query again to get latest tunnel updated with protocol values from PCRpt msg.
1447 updateTunnel(service.tunnelQueryById(tunnel.tunnelId()), tunnel.path());
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301448 }
Avantika-Huawei56c11842016-04-28 00:56:56 +05301449 }
1450
Priyanka B413fbe82016-05-26 11:44:45 +05301451 private SparseAnnotations getAnnotations(PcepLspObject lspObj, StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301452 float bandwidth, LspType lspType, String costType) {
1453
1454 Builder builder = DefaultAnnotations.builder();
1455
1456 /*
1457 * [RFC 5440] The absence of the METRIC object MUST be interpreted by the PCE as a path computation request
1458 * for which no constraints need be applied to any of the metrics.
1459 */
1460 if (costType != null) {
1461 builder.set(COST_TYPE, costType);
1462 }
1463
1464 SparseAnnotations annotations = builder
Priyanka B413fbe82016-05-26 11:44:45 +05301465 .set(BANDWIDTH, (new Float(bandwidth)).toString()).set(LSP_SIG_TYPE, lspType.name())
1466 .set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()))
1467 .set(PLSP_ID, String.valueOf(lspObj.getPlspId()))
1468 .set(LOCAL_LSP_ID, String.valueOf(ipv4LspIdenTlv.getLspId()))
1469 .set(DELEGATE, String.valueOf(lspObj.getDFlag()))
1470 .build();
1471 return annotations;
1472 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301473
Priyanka B413fbe82016-05-26 11:44:45 +05301474 private LspType getLspType(PcepSrpObject srpObj) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301475 LspType lspType = WITH_SIGNALLING;
1476
1477 if (null != srpObj) {
1478 LinkedList<PcepValueType> llOptionalTlv = srpObj.getOptionalTlv();
1479 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
1480
1481 while (listIterator.hasNext()) {
1482 PcepValueType tlv = listIterator.next();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301483 switch (tlv.getType()) {
1484 case PathSetupTypeTlv.TYPE:
1485 lspType = LspType.values()[Integer.valueOf(((PathSetupTypeTlv) tlv).getPst())];
1486 break;
Avantika-Huawei56c11842016-04-28 00:56:56 +05301487 default:
1488 break;
1489 }
1490 }
1491 }
Priyanka B413fbe82016-05-26 11:44:45 +05301492 return lspType;
1493 }
1494
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301495 private void handleRptWithoutSrpId(PcepStateReport stateRpt, PccId pccId) {
Priyanka B413fbe82016-05-26 11:44:45 +05301496 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301497 String costType = null;
Priyanka B413fbe82016-05-26 11:44:45 +05301498 PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
1499 checkNotNull(msgPath);
1500 PcepEroObject eroObj = msgPath.getEroObject();
1501 if (eroObj == null) {
1502 log.error("ERO object is null in report message.");
1503 return;
1504 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301505
1506 PcepAttribute attributes = msgPath.getPcepAttribute();
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301507 float bandwidth = 0;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301508 int cost = 0;
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301509 if (attributes != null) {
1510 if (attributes.getMetricObjectList() != null) {
1511 ListIterator<PcepMetricObject> iterator = attributes.getMetricObjectList().listIterator();
1512 PcepMetricObject metricObj = iterator.next();
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301513
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301514 while (metricObj != null) {
1515 if (metricObj.getBType() == IGP_METRIC) {
1516 costType = "COST";
1517 } else if (metricObj.getBType() == TE_METRIC) {
1518 costType = "TE_COST";
1519 }
1520 if (costType != null) {
1521 cost = metricObj.getMetricVal();
1522 log.debug("Path cost {}", cost);
1523 break;
1524 }
1525 metricObj = iterator.next();
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301526 }
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301527 }
1528 if (attributes.getBandwidthObject() != null) {
1529 bandwidth = attributes.getBandwidthObject().getBandwidth();
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301530 }
1531 }
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301532 List<Object> eroSubObjList = buildPathFromEroObj(eroObj, providerId);
1533 List<Link> links = new ArrayList<>();
1534 List<LabelResourceId> labels = new ArrayList<>();
1535 for (Object linkOrLabel : eroSubObjList) {
1536 if (linkOrLabel instanceof Link) {
1537 links.add((Link) linkOrLabel);
1538 } else if (linkOrLabel instanceof Integer) {
1539 labels.add(LabelResourceId.labelResourceId(((Integer) linkOrLabel).longValue()));
1540 }
Priyanka B413fbe82016-05-26 11:44:45 +05301541 }
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301542 Path path = new DefaultPath(providerId, links, cost, EMPTY);
1543 NetworkResource labelStack = new DefaultLabelStack(labels);
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301544 // To carry PST TLV, SRP object can be present with value 0 even when PCRpt is not in response to any action
1545 // from PCE.
Priyanka B413fbe82016-05-26 11:44:45 +05301546 PcepSrpObject srpObj = stateRpt.getSrpObject();
1547 LspType lspType = getLspType(srpObj);
Avantika-Huawei56c11842016-04-28 00:56:56 +05301548
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301549 PcepLspObject lspObj = stateRpt.getLspObject();
1550 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
1551 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
1552 SymbolicPathNameTlv pathNameTlv = null;
1553
1554 while (listTlvIterator.hasNext()) {
1555 PcepValueType tlv = listTlvIterator.next();
1556 switch (tlv.getType()) {
1557 case StatefulIPv4LspIdentifiersTlv.TYPE:
1558 ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
1559 break;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301560 case SymbolicPathNameTlv.TYPE:
1561 pathNameTlv = (SymbolicPathNameTlv) tlv;
1562 break;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301563 default:
1564 break;
1565 }
1566 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301567 /*
1568 * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
1569 * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
1570 */
1571 if (ipv4LspIdenTlv == null) {
1572 log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
1573 return;
1574 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301575 IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
1576 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
1577 IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
1578 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
1579 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
1580
Priyanka B413fbe82016-05-26 11:44:45 +05301581 // Store delegation flag info and that LSP info because only delegated PCE sends update message
1582 // Storing if D flag is set, if not dont store. while checking whether delegation if annotation for D flag
1583 // not present then non-delegated , if present it is delegated.
1584 if (lspObj.getDFlag()) {
1585 pcepClientController.getClient(pccId).setLspAndDelegationInfo(
1586 new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId()), lspObj.getDFlag());
1587 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301588 Tunnel tunnel = null;
1589 // Asynchronous status change message from PCC for LSP reported earlier.
1590 for (Tunnel tunnelObj : tunnelQueryResult) {
1591 if (tunnelObj.annotations().value(PLSP_ID) == null) {
1592 /*
1593 * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
1594 * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
1595 * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
1596 * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
1597 * session an LSP is "first" reported to a PCE.
1598 */
1599 if ((pathNameTlv != null)
1600 && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
1601 tunnel = tunnelObj;
1602 break;
1603 }
1604 continue;
1605 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301606 if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId()) && (Integer
1607 .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
1608 tunnel = tunnelObj;
1609 break;
1610 }
1611 }
1612
1613 DefaultTunnelDescription td;
Priyanka B413fbe82016-05-26 11:44:45 +05301614 SparseAnnotations annotations = null;
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301615 State tunnelState = PcepLspStatus.getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
1616 if (tunnel == null) {
1617 if (lspObj.getRFlag()) {
1618 /*
1619 * If PCC sends remove message and for any reason PCE does not have that entry, simply discard the
1620 * message. Or if PCRpt for initiated LSP received and PCE doesn't know, then too discard.
1621 */
1622 return;
1623 }
1624
Priyanka B413fbe82016-05-26 11:44:45 +05301625 DeviceId deviceId = getDevice(pccId);
1626 if (deviceId == null) {
1627 log.error("Ingress deviceId not found");
1628 return;
1629 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301630 annotations = getAnnotations(lspObj, ipv4LspIdenTlv, bandwidth, lspType, costType);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301631
Priyanka B413fbe82016-05-26 11:44:45 +05301632 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301633 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())), path, labelStack,
Priyanka B413fbe82016-05-26 11:44:45 +05301634 annotations);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301635
1636 // Do not support PCC initiated LSP after LSP DB sync is completed.
1637 if (!lspObj.getSFlag() && !lspObj.getCFlag()) {
1638 log.error("Received PCC initiated LSP while not in sync.");
1639 return;
1640 }
1641
Priyanka B413fbe82016-05-26 11:44:45 +05301642 /*
1643 * If ONOS instance is master for PCC then set delegated flag as annotation and add the tunnel to store.
1644 * Because all LSPs need not be delegated, hence mastership for the PCC is confirmed whereas not the
1645 * delegation set to all LSPs.If ONOS is not the master for that PCC then check if D flag is set, if yes
1646 * wait for 2 seconds [while master has added the tunnel to the store] then update the tunnel. Tunnel is
1647 * updated because in case of resilency only delegated LSPs are recomputed and only delegated PCE can
1648 * send update message to that client.
1649 *
1650 * 1)Master can 1st get the Rpt message
1651 * a)Master adds the tunnel into core.
1652 * b)If a non-master for ingress gets Rpt message with D flag set[as delegation owner]
1653 * after master, then runs timer then update the tunnel with D flag set.
1654 * 2)Non-Master can 1st get the Rpt message
1655 * a)Non-Master runs the timer check for the tunnel then updates the tunnel with D flag set
1656 * b)Master would have got the message while the non-master running timer, hence master adds
1657 * tunnel to core
1658 *
1659 * In general always master adds the tunnel to the core
1660 * while delegated owner [master or non-master with D flag set] always updates the tunnel running timer
1661 */
1662 if (mastershipService.isLocalMaster(deviceId)) {
1663 TunnelId tId = tunnelAdded(td, tunnelState);
1664 Tunnel tunnelInserted = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, MPLS,
1665 tunnelState, new DefaultGroupId(0), tId, TunnelName.tunnelName(String.valueOf(pathNameTlv
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301666 .getValue())), path, labelStack, annotations);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301667
Priyanka B413fbe82016-05-26 11:44:45 +05301668 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnelInserted, path, LSP_STATE_RPT);
1669 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspIdenTlv);
1670 pcepTunnelApiMapper.addToTunnelIdMap(pcepTunnelData);
1671 } else if (!mastershipService.isLocalMaster(deviceId) && lspObj.getDFlag()) {
1672 //Start timer then update the tunnel with D flag
1673 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1674 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301675 return;
1676 }
1677
Priyanka B413fbe82016-05-26 11:44:45 +05301678 //delegated owner will update can be a master or non-master
1679 if (lspObj.getDFlag()) {
Priyanka B7e48cb22016-07-01 16:17:58 +05301680
1681 if (tunnel.annotations().value(BANDWIDTH) != null) {
1682 bandwidth = Float.parseFloat(tunnel.annotations().value(BANDWIDTH));
1683 }
1684 annotations = getAnnotations(lspObj, ipv4LspIdenTlv,
1685 bandwidth, lspType,
1686 tunnel.annotations().value(COST_TYPE));
Priyanka B413fbe82016-05-26 11:44:45 +05301687 td = new DefaultTunnelDescription(null, tunnelEndPointSrc, tunnelEndPointDst, MPLS, new DefaultGroupId(
Priyanka Bc1e4e4c2016-07-01 14:57:19 +05301688 0), providerId, TunnelName.tunnelName(new String(pathNameTlv.getValue())),
1689 tunnel.path(), labelStack, annotations);
Priyanka B413fbe82016-05-26 11:44:45 +05301690 tunnelUpdateInDelegatedCase(pccId, annotations, td, providerId);
1691 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301692 removeOrUpdatetunnel(tunnel, pccId, lspObj, providerId, tunnelState);
Priyanka B413fbe82016-05-26 11:44:45 +05301693 return;
1694 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301695
Priyanka B413fbe82016-05-26 11:44:45 +05301696 private void removeOrUpdatetunnel(Tunnel tunnel, PccId pccId, PcepLspObject lspObj, ProviderId providerId,
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301697 State tunnelState) {
Priyanka B413fbe82016-05-26 11:44:45 +05301698 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(), tunnel.dst(),
1699 tunnel.type(), tunnel.groupId(), providerId, tunnel.tunnelName(), tunnel.path(),
1700 (SparseAnnotations) tunnel.annotations());
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301701 if (lspObj.getRFlag()) {
1702 tunnelRemoved(td);
1703 } else {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301704 tunnelUpdated(td, tunnelState);
1705 }
Priyanka B413fbe82016-05-26 11:44:45 +05301706 }
1707
1708 private void tunnelUpdateInDelegatedCase(PccId pccId, SparseAnnotations annotations,
1709 DefaultTunnelDescription td, ProviderId providerId) {
1710 //Wait for 2sec then query tunnel based on ingress PLSP-ID and local LSP-ID
1711
1712 /*
1713 * If ONOS is not the master for that PCC then check if D flag is set, if yes wait [while
1714 * master has added the tunnel to the store] then update the tunnel.
1715 */
1716 ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
1717
1718 // Thread is started after 2 seconds first time later periodically after 2 seconds to update the tunnel
1719 executor.scheduleAtFixedRate(new UpdateDelegation(td, providerId, annotations, pccId,
1720 executor), DELAY, DELAY, TimeUnit.SECONDS);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301721 }
1722
1723 /**
Avantika-Huawei56c11842016-04-28 00:56:56 +05301724 * To build Path in network from ERO object.
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301725 *
Avantika-Huawei56c11842016-04-28 00:56:56 +05301726 * @param eroObj ERO object
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301727 * @param providerId provider id
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301728 * @return list of links and labels
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301729 */
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301730 private List<Object> buildPathFromEroObj(PcepEroObject eroObj, ProviderId providerId) {
Avantika-Huawei56c11842016-04-28 00:56:56 +05301731 checkNotNull(eroObj);
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301732 List<Object> subObjList = new ArrayList<>();
Avantika-Huawei56c11842016-04-28 00:56:56 +05301733 LinkedList<PcepValueType> llSubObj = eroObj.getSubObjects();
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301734 if (0 == llSubObj.size()) {
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301735 log.error("ERO in report message does not have hop information");
Priyanka B4c3cef02016-06-14 20:27:53 +05301736 return null;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301737 }
1738 ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
1739
1740 ConnectPoint src = null;
1741 ConnectPoint dst = null;
1742 boolean isSrcSet = false;
1743 while (tlvIterator.hasNext()) {
1744 PcepValueType subObj = tlvIterator.next();
1745 switch (subObj.getType()) {
1746
1747 case IPv4SubObject.TYPE:
1748
1749 IPv4SubObject ipv4SubObj = (IPv4SubObject) subObj;
1750 if (!isSrcSet) {
Priyanka Bc1e4e4c2016-07-01 14:57:19 +05301751 Iterable<Link> links = linkService.getActiveLinks();
1752 for (Link l : links) {
1753 if (l.src().port().equals(PortNumber.portNumber(ipv4SubObj.getIpAddress()))) {
1754 src = l.src();
1755 isSrcSet = true;
1756 break;
1757 } else if (l.dst().port().equals(PortNumber.portNumber(ipv4SubObj.getIpAddress()))) {
1758 src = l.dst();
1759 isSrcSet = true;
1760 break;
1761 }
1762 }
1763 } else {
1764 Iterable<Link> links = linkService.getActiveLinks();
1765 for (Link l : links) {
1766 if (l.src().port().equals(PortNumber.portNumber(ipv4SubObj.getIpAddress()))) {
1767 dst = l.src();
1768 break;
1769 } else if (l.dst().port().equals(PortNumber.portNumber(ipv4SubObj.getIpAddress()))) {
1770 dst = l.dst();
1771 break;
1772 }
1773 }
Ray Milkey2693bda2016-01-22 16:08:14 -08001774 Link link = DefaultLink.builder()
1775 .providerId(providerId)
1776 .src(src)
1777 .dst(dst)
1778 .type(Link.Type.DIRECT)
1779 .build();
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301780 subObjList.add(link);
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301781 src = dst;
1782 }
1783 break;
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301784 case SrEroSubObject.TYPE:
1785 SrEroSubObject srEroSubObj = (SrEroSubObject) subObj;
1786 subObjList.add(srEroSubObj.getSid());
1787
1788 if (srEroSubObj.getSt() == PcepNaiIpv4Adjacency.ST_TYPE) {
1789 PcepNaiIpv4Adjacency nai = (PcepNaiIpv4Adjacency) (srEroSubObj.getNai());
1790 IpAddress srcIp = IpAddress.valueOf(nai.getLocalIpv4Addr());
1791 src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
1792 IpAddress dstIp = IpAddress.valueOf(nai.getRemoteIpv4Addr());
1793 dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
1794 Link link = DefaultLink.builder()
1795 .providerId(providerId)
1796 .src(src)
1797 .dst(dst)
1798 .type(Link.Type.DIRECT)
1799 .build();
1800 subObjList.add(link);
1801 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301802 default:
1803 // the other sub objects are not required
1804 }
1805 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301806
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301807 return subObjList;
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301808 }
1809
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301810 @Override
1811 public void clientConnected(PccId pccId) {
1812 // TODO
1813 }
1814
1815 @Override
1816 public void clientDisconnected(PccId pccId) {
1817 // TODO
cheng fan48e832c2015-05-29 01:54:47 +08001818 }
chengfan2fff70f2015-08-24 18:20:19 -05001819
chengfan2fff70f2015-08-24 18:20:19 -05001820 @Override
1821 public void handlePcepTunnelStatistics(PcepTunnelStatistics pcepTunnelStatistics) {
1822 TunnelId id = getTunnelId(String.valueOf(pcepTunnelStatistics.id()));
1823 TunnelStatistics tunnelStatistics = buildTunnelStatistics(pcepTunnelStatistics);
1824 tunnelStatisticsMap.put(id, tunnelStatistics);
1825 }
cheng fan48e832c2015-05-29 01:54:47 +08001826
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301827 @Override
1828 public void handleEndOfSyncAction(Tunnel tunnel, PcepLspSyncAction endOfSyncAction) {
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301829
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301830 if (endOfSyncAction == SEND_UPDATE) {
1831 updateTunnel(tunnel, tunnel.path());
1832 return;
1833 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301834
1835 TunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(),
1836 tunnel.src(), tunnel.dst(),
1837 tunnel.type(),
1838 tunnel.groupId(),
1839 tunnel.providerId(),
1840 tunnel.tunnelName(),
1841 tunnel.path(),
1842 (SparseAnnotations) tunnel.annotations());
1843
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301844
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301845 if (endOfSyncAction == PcepLspSyncAction.UNSTABLE) {
1846
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301847 // Send PCInit msg again after global reoptimization.
1848 tunnelUpdated(td, UNSTABLE);
1849
1850 // To remove the old tunnel from store whose PLSPID is not
1851 // recognized by ingress PCC.
1852 tunnelRemoved(td);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301853
1854 } else if (endOfSyncAction == REMOVE) {
1855 tunnelRemoved(td);
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301856 }
1857 }
Avantika-Huawei7f7376a2016-05-11 17:07:50 +05301858 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301859 @Override
1860 public Tunnel tunnelQueryById(TunnelId tunnelId) {
1861 return service.tunnelQueryById(tunnelId);
1862 }
1863
Priyanka B413fbe82016-05-26 11:44:45 +05301864
1865 private DeviceId getDevice(PccId pccId) {
1866 // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
1867 IpAddress lsrId = pccId.ipAddress();
1868 String lsrIdentifier = String.valueOf(lsrId);
1869
1870 // Find PCC deviceID from lsrId stored as annotations
1871 Iterable<Device> devices = deviceService.getAvailableDevices();
1872 for (Device dev : devices) {
1873 if (dev.annotations().value(AnnotationKeys.TYPE).equals("L3")
1874 && dev.annotations().value(LSRID).equals(lsrIdentifier)) {
1875 return dev.id();
1876 }
1877 }
1878 return null;
1879 }
1880
1881 /**
1882 * Updates the tunnel with updated tunnel annotation after a delay of two seconds and checks it till
1883 * tunnel is found.
1884 */
1885 private class UpdateDelegation implements Runnable {
1886 DefaultTunnelDescription td;
1887 ProviderId providerId;
1888 SparseAnnotations annotations;
1889 PccId pccId;
1890 ScheduledExecutorService executor;
1891
1892 /**
1893 * Creates an instance of UpdateDelegation.
1894 *
1895 * @param td tunnel description
1896 * @param providerId provider id
1897 * @param annotations tunnel annotations
1898 * @param pccId PCEP client id
1899 * @param executor service of delegated owner
1900 */
1901 public UpdateDelegation(DefaultTunnelDescription td, ProviderId providerId, SparseAnnotations annotations,
1902 PccId pccId, ScheduledExecutorService executor) {
1903 this.td = td;
1904 this.providerId = providerId;
1905 this.annotations = annotations;
1906 this.pccId = pccId;
1907 this.executor = executor;
1908 }
1909
1910 //Temporary using annotations later will use projection/network config service
1911 @Override
1912 public void run() {
1913 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(td.src(), td.dst());
1914 TunnelId tempTunnelId = null;
1915 for (Tunnel t : tunnelQueryResult) {
1916 if (t.annotations().value(LOCAL_LSP_ID) == null || t.annotations().value(PLSP_ID) == null) {
1917 continue;
1918 }
1919
1920 if (t.annotations().value(LOCAL_LSP_ID).equals(td.annotations().value(LOCAL_LSP_ID))
1921 && t.annotations().value(PLSP_ID).equals(td.annotations().value(PLSP_ID))
1922 && ((IpTunnelEndPoint) t.src()).ip().equals(pccId.id())) {
1923 tempTunnelId = t.tunnelId();
1924 break;
1925 }
1926 }
1927
1928 //If tunnel is found update the tunnel and shutdown the thread otherwise thread will be executing
1929 //periodically
1930 if (tempTunnelId != null) {
1931 Tunnel tunnel = new DefaultTunnel(providerId, td.src(), td.dst(), MPLS, new DefaultGroupId(0),
1932 tempTunnelId, td.tunnelName(), td.path(), annotations);
1933 tunnelUpdated(tunnel, td.path());
1934 executor.shutdown();
1935 try {
1936 executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
1937 } catch (InterruptedException e) {
1938 log.error("updating delegation failed");
1939 }
1940 }
1941 }
1942 }
cheng fan48e832c2015-05-29 01:54:47 +08001943}