blob: 2ddc819f91b3b2af9e569743c94a6185768cb8b4 [file] [log] [blame]
SureshBR25058b72015-08-13 13:05:06 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
SureshBR25058b72015-08-13 13:05:06 +05303 *
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 */
harikrushna-Huaweia2c7c202017-04-10 18:22:00 +053016package org.onosproject.pcep.server.impl;
SureshBR25058b72015-08-13 13:05:06 +053017
mohamedrahil00f6f262016-11-24 20:20:41 +053018import java.util.Map;
19import java.util.TreeMap;
20import java.util.List;
21import java.util.LinkedList;
22import java.util.Set;
23import java.util.HashSet;
24import java.util.HashMap;
SureshBR25058b72015-08-13 13:05:06 +053025import java.util.Collection;
26import java.util.Collections;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053027import java.util.ListIterator;
mohamedrahil00f6f262016-11-24 20:20:41 +053028import java.util.Arrays;
29import java.util.Iterator;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053030import java.util.Map.Entry;
SureshBR25058b72015-08-13 13:05:06 +053031import java.util.concurrent.ConcurrentHashMap;
SureshBR25058b72015-08-13 13:05:06 +053032
33import org.apache.felix.scr.annotations.Activate;
34import org.apache.felix.scr.annotations.Component;
35import org.apache.felix.scr.annotations.Deactivate;
Priyanka B94395bf2016-05-21 18:39:46 +053036import org.apache.felix.scr.annotations.Reference;
37import org.apache.felix.scr.annotations.ReferenceCardinality;
SureshBR25058b72015-08-13 13:05:06 +053038import org.apache.felix.scr.annotations.Service;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053039import org.onlab.packet.Ip4Address;
40import org.onlab.packet.IpAddress;
41import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
42import org.onosproject.incubator.net.resource.label.LabelResourceId;
43import org.onosproject.incubator.net.resource.label.LabelResourceService;
44import org.onosproject.incubator.net.tunnel.DefaultLabelStack;
45import org.onosproject.incubator.net.tunnel.DefaultTunnel;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053046import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053047import org.onosproject.incubator.net.tunnel.LabelStack;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053048import org.onosproject.incubator.net.tunnel.Tunnel;
49import org.onosproject.incubator.net.tunnel.TunnelService;
50import org.onosproject.incubator.net.tunnel.Tunnel.State;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053051import org.onosproject.mastership.MastershipService;
52import org.onosproject.net.DefaultAnnotations;
53import org.onosproject.net.DefaultAnnotations.Builder;
54import org.onosproject.net.Device;
55import org.onosproject.net.DeviceId;
56import org.onosproject.net.Link;
57import org.onosproject.net.MastershipRole;
58import org.onosproject.net.Path;
59import org.onosproject.net.config.NetworkConfigEvent;
60import org.onosproject.net.config.NetworkConfigListener;
61import org.onosproject.net.config.NetworkConfigService;
62import org.onosproject.net.device.DeviceEvent;
63import org.onosproject.net.device.DeviceListener;
Priyanka B94395bf2016-05-21 18:39:46 +053064import org.onosproject.net.device.DeviceService;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053065import org.onosproject.net.link.LinkEvent;
66import org.onosproject.net.link.LinkListener;
67import org.onosproject.net.link.LinkService;
68import org.onosproject.pcelabelstore.PcepLabelOp;
69import org.onosproject.pcelabelstore.api.PceLabelStore;
70import org.onosproject.pcep.api.DeviceCapability;
harikrushna-Huaweia2c7c202017-04-10 18:22:00 +053071import org.onosproject.pcep.server.LspKey;
72import org.onosproject.pcep.server.LspType;
73import org.onosproject.pcep.server.PccId;
74import org.onosproject.pcep.server.PcepClient;
75import org.onosproject.pcep.server.PcepClientController;
76import org.onosproject.pcep.server.PcepClientListener;
77import org.onosproject.pcep.server.PcepEventListener;
78import org.onosproject.pcep.server.PcepLspStatus;
79import org.onosproject.pcep.server.PcepNodeListener;
80import org.onosproject.pcep.server.SrpIdGenerators;
81import org.onosproject.pcep.server.driver.PcepAgent;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053082import org.onosproject.pcepio.exceptions.PcepParseException;
83import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
Priyanka Bd2b28882016-04-04 16:57:04 +053084import org.onosproject.pcepio.protocol.PcepError;
85import org.onosproject.pcepio.protocol.PcepErrorInfo;
86import org.onosproject.pcepio.protocol.PcepErrorMsg;
87import org.onosproject.pcepio.protocol.PcepErrorObject;
88import org.onosproject.pcepio.protocol.PcepFactory;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053089import org.onosproject.pcepio.protocol.PcepInitiateMsg;
90import org.onosproject.pcepio.protocol.PcepLspObject;
SureshBR25058b72015-08-13 13:05:06 +053091import org.onosproject.pcepio.protocol.PcepMessage;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053092import org.onosproject.pcepio.protocol.PcepNai;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053093import org.onosproject.pcepio.protocol.PcepReportMsg;
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +053094import org.onosproject.pcepio.protocol.PcepSrpObject;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053095import org.onosproject.pcepio.protocol.PcepStateReport;
Avantika-Huawei9e848e82016-09-01 12:12:42 +053096import org.onosproject.pcepio.types.PathSetupTypeTlv;
97import org.onosproject.pcepio.types.PcepNaiIpv4Adjacency;
98import org.onosproject.pcepio.types.PcepNaiIpv4NodeId;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +053099import org.onosproject.pcepio.types.PcepValueType;
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530100import org.onosproject.pcepio.types.SrEroSubObject;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530101import org.onosproject.pcepio.types.StatefulIPv4LspIdentifiersTlv;
102import org.onosproject.pcepio.types.SymbolicPathNameTlv;
SureshBR25058b72015-08-13 13:05:06 +0530103import org.slf4j.Logger;
104import org.slf4j.LoggerFactory;
105
106import com.google.common.collect.Sets;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530107import static com.google.common.base.Preconditions.checkNotNull;
SureshBR25058b72015-08-13 13:05:06 +0530108
harikrushna-Huaweia2c7c202017-04-10 18:22:00 +0530109import static org.onosproject.pcep.server.PcepSyncStatus.IN_SYNC;
110import static org.onosproject.pcep.server.LspType.WITHOUT_SIGNALLING_AND_WITHOUT_SR;
111import static org.onosproject.pcep.server.LspType.WITH_SIGNALLING;
112import static org.onosproject.pcep.server.PcepLspSyncAction.REMOVE;
113import static org.onosproject.pcep.server.PcepLspSyncAction.SEND_UPDATE;
114import static org.onosproject.pcep.server.PcepLspSyncAction.UNSTABLE;
Priyanka Bd2b28882016-04-04 16:57:04 +0530115import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
116import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
harikrushna-Huaweia2c7c202017-04-10 18:22:00 +0530117import static org.onosproject.pcep.server.PcepAnnotationKeys.BANDWIDTH;
118import static org.onosproject.pcep.server.PcepAnnotationKeys.LOCAL_LSP_ID;
119import static org.onosproject.pcep.server.PcepAnnotationKeys.LSP_SIG_TYPE;
120import static org.onosproject.pcep.server.PcepAnnotationKeys.PCC_TUNNEL_ID;
121import static org.onosproject.pcep.server.PcepAnnotationKeys.PCE_INIT;
122import static org.onosproject.pcep.server.PcepAnnotationKeys.PLSP_ID;
123import static org.onosproject.pcep.server.PcepAnnotationKeys.DELEGATE;
124import static org.onosproject.pcep.server.PcepAnnotationKeys.COST_TYPE;
125import static org.onosproject.pcep.server.PcepSyncStatus.SYNCED;
126import static org.onosproject.pcep.server.PcepSyncStatus.NOT_SYNCED;
Priyanka Bd2b28882016-04-04 16:57:04 +0530127
Phanendra Manda51fb9c22015-09-01 16:17:41 +0530128/**
129 * Implementation of PCEP client controller.
130 */
SureshBR25058b72015-08-13 13:05:06 +0530131@Component(immediate = true)
132@Service
133public class PcepClientControllerImpl implements PcepClientController {
134
135 private static final Logger log = LoggerFactory.getLogger(PcepClientControllerImpl.class);
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530136 private static final long IDENTIFIER_SET = 0x100000000L;
137 private static final long SET = 0xFFFFFFFFL;
SureshBR25058b72015-08-13 13:05:06 +0530138
Priyanka B94395bf2016-05-21 18:39:46 +0530139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
140 protected DeviceService deviceService;
141
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
143 protected LinkService linkService;
144
145 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
146 protected TunnelService tunnelService;
147
148 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
149 protected NetworkConfigService netCfgService;
150
151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
152 protected MastershipService mastershipService;
153
154 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
155 protected LabelResourceAdminService labelRsrcAdminService;
156
157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
158 protected LabelResourceService labelRsrcService;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
161 protected PceLabelStore pceStore;
162
SureshBR25058b72015-08-13 13:05:06 +0530163 protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700164 new ConcurrentHashMap<>();
SureshBR25058b72015-08-13 13:05:06 +0530165
166 protected PcepClientAgent agent = new PcepClientAgent();
167 protected Set<PcepClientListener> pcepClientListener = new HashSet<>();
168
169 protected Set<PcepEventListener> pcepEventListener = Sets.newHashSet();
Priyanka B94395bf2016-05-21 18:39:46 +0530170 protected Set<PcepNodeListener> pcepNodeListener = Sets.newHashSet();
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530171
172 // LSR-id and device-id mapping for checking capability if L3 device is not
173 // having its capability
174 private Map<String, DeviceId> lsrIdDeviceIdMap = new HashMap<>();
SureshBR25058b72015-08-13 13:05:06 +0530175
176 private final Controller ctrl = new Controller();
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530177 public static final long GLOBAL_LABEL_SPACE_MIN = 4097;
178 public static final long GLOBAL_LABEL_SPACE_MAX = 5121;
179 private static final String LSRID = "lsrId";
180 private static final String DEVICE_NULL = "Device-cannot be null";
181 private static final String LINK_NULL = "Link-cannot be null";
SureshBR25058b72015-08-13 13:05:06 +0530182
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530183 private BasicPceccHandler crHandler;
184 private PceccSrTeBeHandler srTeHandler;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530185
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530186 private DeviceListener deviceListener = new InternalDeviceListener();
187 private LinkListener linkListener = new InternalLinkListener();
188 private InternalConfigListener cfgListener = new InternalConfigListener();
mohamedrahil00f6f262016-11-24 20:20:41 +0530189 private Map<Integer, Integer> pcepErrorMsg = new TreeMap<>();
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530190
SureshBR25058b72015-08-13 13:05:06 +0530191 @Activate
192 public void activate() {
193 ctrl.start(agent);
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530194 crHandler = BasicPceccHandler.getInstance();
195 crHandler.initialize(labelRsrcService, deviceService, pceStore, this);
196
197 srTeHandler = PceccSrTeBeHandler.getInstance();
198 srTeHandler.initialize(labelRsrcAdminService, labelRsrcService, this, pceStore,
199 deviceService);
200
201 deviceService.addListener(deviceListener);
202 linkService.addListener(linkListener);
203 netCfgService.addListener(cfgListener);
204
205 // Reserve global node pool
206 if (!srTeHandler.reserveGlobalPool(GLOBAL_LABEL_SPACE_MIN, GLOBAL_LABEL_SPACE_MAX)) {
207 log.debug("Global node pool was already reserved.");
208 }
209
SureshBR25058b72015-08-13 13:05:06 +0530210 log.info("Started");
211 }
212
213 @Deactivate
214 public void deactivate() {
215 // Close all connected clients
216 closeConnectedClients();
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530217 deviceService.removeListener(deviceListener);
218 linkService.removeListener(linkListener);
219 netCfgService.removeListener(cfgListener);
SureshBR25058b72015-08-13 13:05:06 +0530220 ctrl.stop();
221 log.info("Stopped");
222 }
223
224 @Override
mohamedrahil00f6f262016-11-24 20:20:41 +0530225 public void peerErrorMsg(String peerId, Integer errorType, Integer errValue) {
226 if (peerId == null) {
227 pcepErrorMsg.put(errorType, errValue);
228 } else {
229 if (pcepErrorMsg.size() > 10) {
230 pcepErrorMsg.clear();
231 }
232 pcepErrorMsg.put(errorType, errValue);
233 }
234 }
235
236 @Override
237 public Map<String, List<String>> getPcepExceptions() {
238 return this.ctrl.exceptionsMap();
239 }
240
241 @Override
242 public Map<Integer, Integer> getPcepErrorMsg() {
243 return pcepErrorMsg;
244 }
245
246
247 @Override
248 public Map<String, String> getPcepSessionMap() {
249 return this.ctrl.mapPeer();
250 }
251
252 @Override
253 public Map<String, Byte> getPcepSessionIdMap() {
254 return this.ctrl.mapSession();
255 }
256
257 @Override
SureshBR25058b72015-08-13 13:05:06 +0530258 public Collection<PcepClient> getClients() {
259 return connectedClients.values();
260 }
261
262 @Override
263 public PcepClient getClient(PccId pccId) {
264 return connectedClients.get(pccId);
265 }
266
267 @Override
268 public void addListener(PcepClientListener listener) {
269 if (!pcepClientListener.contains(listener)) {
270 this.pcepClientListener.add(listener);
271 }
272 }
273
274 @Override
275 public void removeListener(PcepClientListener listener) {
276 this.pcepClientListener.remove(listener);
277 }
278
279 @Override
280 public void addEventListener(PcepEventListener listener) {
281 pcepEventListener.add(listener);
282 }
283
284 @Override
285 public void removeEventListener(PcepEventListener listener) {
286 pcepEventListener.remove(listener);
287 }
288
289 @Override
290 public void writeMessage(PccId pccId, PcepMessage msg) {
291 this.getClient(pccId).sendMessage(msg);
292 }
293
294 @Override
Priyanka B94395bf2016-05-21 18:39:46 +0530295 public void addNodeListener(PcepNodeListener listener) {
296 pcepNodeListener.add(listener);
297 }
298
299 @Override
300 public void removeNodeListener(PcepNodeListener listener) {
301 pcepNodeListener.remove(listener);
302 }
303
304 @Override
SureshBR25058b72015-08-13 13:05:06 +0530305 public void processClientMessage(PccId pccId, PcepMessage msg) {
306 PcepClient pc = getClient(pccId);
307
308 switch (msg.getType()) {
309 case NONE:
310 break;
311 case OPEN:
312 break;
313 case KEEP_ALIVE:
314 break;
315 case PATH_COMPUTATION_REQUEST:
316 break;
317 case PATH_COMPUTATION_REPLY:
318 break;
319 case NOTIFICATION:
320 break;
321 case ERROR:
322 break;
Priyanka Bd2b28882016-04-04 16:57:04 +0530323 case INITIATE:
324 if (!pc.capability().pcInstantiationCapability()) {
325 pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
326 ERROR_VALUE_5)));
327 }
328 break;
329 case UPDATE:
330 if (!pc.capability().statefulPceCapability()) {
331 pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
332 ERROR_VALUE_5)));
333 }
334 break;
335 case LABEL_UPDATE:
336 if (!pc.capability().pceccCapability()) {
337 pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(), ERROR_TYPE_19,
338 ERROR_VALUE_5)));
339 }
340 break;
SureshBR25058b72015-08-13 13:05:06 +0530341 case CLOSE:
342 log.info("Sending Close Message to {" + pccId.toString() + "}");
343 pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
344 //now disconnect client
345 pc.disconnectClient();
346 break;
347 case REPORT:
Priyanka Bd2b28882016-04-04 16:57:04 +0530348 //Only update the listener if respective capability is supported else send PCEP-ERR msg
349 if (pc.capability().statefulPceCapability()) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530350
351 ListIterator<PcepStateReport> listIterator = ((PcepReportMsg) msg).getStateReportList().listIterator();
352 while (listIterator.hasNext()) {
353 PcepStateReport stateRpt = listIterator.next();
Avantika-Huawei3524d852016-06-04 20:44:13 +0530354 PcepLspObject lspObj = stateRpt.getLspObject();
355 if (lspObj.getSFlag()) {
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530356 if (pc.lspDbSyncStatus() != IN_SYNC) {
Avantika-Huawei3524d852016-06-04 20:44:13 +0530357 log.debug("LSP DB sync started for PCC {}", pc.getPccId().id().toString());
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530358 // Initialize LSP DB sync and temporary cache.
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530359 pc.setLspDbSyncStatus(IN_SYNC);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530360 pc.initializeSyncMsgList(pccId);
361 }
362 // Store stateRpt in temporary cache.
363 pc.addSyncMsgToList(pccId, stateRpt);
364
365 // Don't send to provider as of now.
366 continue;
Avantika-Huawei3524d852016-06-04 20:44:13 +0530367 } else if (lspObj.getPlspId() == 0) {
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530368 if (pc.lspDbSyncStatus() == IN_SYNC
369 || pc.lspDbSyncStatus() == NOT_SYNCED) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530370 // Set end of LSPDB sync.
Avantika-Huawei3524d852016-06-04 20:44:13 +0530371 log.debug("LSP DB sync completed for PCC {}", pc.getPccId().id().toString());
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530372 pc.setLspDbSyncStatus(SYNCED);
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530373
374 // Call packet provider to initiate label DB sync (only if PCECC capable).
375 if (pc.capability().pceccCapability()) {
Avantika-Huawei3524d852016-06-04 20:44:13 +0530376 log.debug("Trigger label DB sync for PCC {}", pc.getPccId().id().toString());
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530377 pc.setLabelDbSyncStatus(IN_SYNC);
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530378 // Get lsrId of the PCEP client from the PCC ID. Session info is based on lsrID.
379 String lsrId = String.valueOf(pccId.ipAddress());
380 DeviceId pccDeviceId = DeviceId.deviceId(lsrId);
381 try {
382 syncLabelDb(pccDeviceId);
383 pc.setLabelDbSyncStatus(SYNCED);
384 } catch (PcepParseException e) {
385 log.error("Exception caught in sending label masg to PCC while in sync.");
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530386 }
387 } else {
388 // If label db sync is not to be done, handle end of LSPDB sync actions.
389 agent.analyzeSyncMsgList(pccId);
390 }
391 continue;
392 }
393 }
394
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530395 PcepLspStatus pcepLspStatus = PcepLspStatus.values()[lspObj.getOFlag()];
396 LspType lspType = getLspType(stateRpt.getSrpObject());
397
398 // Download (or remove) labels for basic PCECC LSPs.
399 if (lspType.equals(WITHOUT_SIGNALLING_AND_WITHOUT_SR)) {
400 boolean isRemove = lspObj.getRFlag();
401 Tunnel tunnel = null;
402
403 if (isRemove || pcepLspStatus.equals(PcepLspStatus.GOING_UP)) {
404 tunnel = getTunnel(lspObj);
405 }
406
407 if (tunnel != null) {
408 if (isRemove) {
409 crHandler.releaseLabel(tunnel);
410 } else {
411 crHandler.allocateLabel(tunnel);
412 }
413 }
414 }
415
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530416 // It's a usual report message while sync is not undergoing. So process it immediately.
417 LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
418 llPcRptList.add(stateRpt);
419 PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
420 .build();
421 for (PcepEventListener l : pcepEventListener) {
422 l.handleMessage(pccId, pcReportMsg);
423 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530424 }
425 } else {
426 // Send PCEP-ERROR message.
427 pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
428 ERROR_TYPE_19, ERROR_VALUE_5)));
SureshBR25058b72015-08-13 13:05:06 +0530429 }
430 break;
Priyanka Bd2b28882016-04-04 16:57:04 +0530431 case LABEL_RANGE_RESERV:
SureshBR25058b72015-08-13 13:05:06 +0530432 break;
Priyanka B94395bf2016-05-21 18:39:46 +0530433 case LS_REPORT: //TODO: need to handle LS report to add or remove node
434 break;
SureshBR25058b72015-08-13 13:05:06 +0530435 case MAX:
436 break;
437 case END:
438 break;
439 default:
440 break;
441 }
442 }
443
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530444 private LspType getLspType(PcepSrpObject srpObj) {
445 LspType lspType = WITH_SIGNALLING;
446
447 if (null != srpObj) {
448 LinkedList<PcepValueType> llOptionalTlv = srpObj.getOptionalTlv();
449 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
450
451 while (listIterator.hasNext()) {
452 PcepValueType tlv = listIterator.next();
453 switch (tlv.getType()) {
454 case PathSetupTypeTlv.TYPE:
455 lspType = LspType.values()[Integer.valueOf(((PathSetupTypeTlv) tlv).getPst())];
456 break;
457 default:
458 break;
459 }
460 }
461 }
462 return lspType;
463 }
464
465 private Tunnel getTunnel(PcepLspObject lspObj) {
466 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
467 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
468 SymbolicPathNameTlv pathNameTlv = null;
469 Tunnel tunnel = null;
470 while (listTlvIterator.hasNext()) {
471 PcepValueType tlv = listTlvIterator.next();
472 switch (tlv.getType()) {
473 case StatefulIPv4LspIdentifiersTlv.TYPE:
474 ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
475 break;
476 case SymbolicPathNameTlv.TYPE:
477 pathNameTlv = (SymbolicPathNameTlv) tlv;
478 break;
479 default:
480 break;
481 }
482 }
483 /*
484 * Draft says: The LSP-IDENTIFIERS TLV MUST be included in the LSP object in PCRpt messages for
485 * RSVP-signaled LSPs. For ONOS PCECC implementation, it is mandatory.
486 */
487 if (ipv4LspIdenTlv == null) {
488 log.error("Stateful IPv4 identifier TLV is null in PCRpt msg.");
489 return null;
490 }
491 IpTunnelEndPoint tunnelEndPointSrc = IpTunnelEndPoint
492 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4IngressAddress()));
493 IpTunnelEndPoint tunnelEndPointDst = IpTunnelEndPoint
494 .ipTunnelPoint(IpAddress.valueOf(ipv4LspIdenTlv.getIpv4EgressAddress()));
495 Collection<Tunnel> tunnelQueryResult = tunnelService.queryTunnel(tunnelEndPointSrc, tunnelEndPointDst);
496
497 for (Tunnel tunnelObj : tunnelQueryResult) {
498 if (tunnelObj.annotations().value(PLSP_ID) == null) {
499 /*
500 * PLSP_ID is null while Tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by
501 * PCC and in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic
502 * path name must be carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be
503 * included in the LSP object in the LSP State Report (PCRpt) message when during a given PCEP
504 * session an LSP is "first" reported to a PCE.
505 */
506 if ((pathNameTlv != null)
507 && Arrays.equals(tunnelObj.tunnelName().value().getBytes(), pathNameTlv.getValue())) {
508 tunnel = tunnelObj;
509 break;
510 }
511 continue;
512 }
513 if ((Integer.valueOf(tunnelObj.annotations().value(PLSP_ID)) == lspObj.getPlspId())) {
514 if ((Integer
515 .valueOf(tunnelObj.annotations().value(LOCAL_LSP_ID)) == ipv4LspIdenTlv.getLspId())) {
516 tunnel = tunnelObj;
517 break;
518 }
519 }
520 }
521
522 if (tunnel == null || tunnel.annotations().value(PLSP_ID) != null) {
523 return tunnel;
524 }
525
526 // The returned tunnel is used just for filling values in Label message. So manipulate locally
527 // and return so that to allocate label, we don't need to wait for the tunnel in the "core"
528 // to be updated, as that depends on listener mechanism and there may be timing/multi-threading issues.
529 Builder annotationBuilder = DefaultAnnotations.builder();
530 annotationBuilder.set(BANDWIDTH, tunnel.annotations().value(BANDWIDTH));
531 annotationBuilder.set(COST_TYPE, tunnel.annotations().value(COST_TYPE));
532 annotationBuilder.set(LSP_SIG_TYPE, tunnel.annotations().value(LSP_SIG_TYPE));
533 annotationBuilder.set(PCE_INIT, tunnel.annotations().value(PCE_INIT));
534 annotationBuilder.set(DELEGATE, tunnel.annotations().value(DELEGATE));
535 annotationBuilder.set(PLSP_ID, String.valueOf(lspObj.getPlspId()));
536 annotationBuilder.set(PCC_TUNNEL_ID, String.valueOf(ipv4LspIdenTlv.getTunnelId()));
537 annotationBuilder.set(LOCAL_LSP_ID, tunnel.annotations().value(LOCAL_LSP_ID));
538
539 Tunnel updatedTunnel = new DefaultTunnel(tunnel.providerId(), tunnel.src(),
540 tunnel.dst(), tunnel.type(),
541 tunnel.state(), tunnel.groupId(),
542 tunnel.tunnelId(),
543 tunnel.tunnelName(),
544 tunnel.path(),
545 tunnel.resource(),
546 annotationBuilder.build());
547
548 return updatedTunnel;
549 }
550
SureshBR25058b72015-08-13 13:05:06 +0530551 @Override
552 public void closeConnectedClients() {
553 PcepClient pc;
554 for (PccId id : connectedClients.keySet()) {
555 pc = getClient(id);
556 pc.disconnectClient();
557 }
558 }
559
560 /**
Priyanka Bd2b28882016-04-04 16:57:04 +0530561 * Returns pcep error message with specific error type and value.
562 *
563 * @param factory represents pcep factory
564 * @param errorType pcep error type
565 * @param errorValue pcep error value
566 * @return pcep error message
567 */
568 public PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
569 LinkedList<PcepError> llPcepErr = new LinkedList<>();
570
571 LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
572 PcepErrorMsg errMsg;
573
574 PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
575 .build();
576
577 llerrObj.add(errObj);
578 PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
579
580 llPcepErr.add(pcepErr);
581
582 PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
583
584 errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
585 return errMsg;
586 }
587
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530588 private boolean syncLabelDb(DeviceId deviceId) throws PcepParseException {
589 checkNotNull(deviceId);
590
591 DeviceId actualDevcieId = pceStore.getLsrIdDevice(deviceId.toString());
592 if (actualDevcieId == null) {
593 log.error("Device not available {}.", deviceId.toString());
594 pceStore.addPccLsr(deviceId);
595 return false;
596 }
597 PcepClient pc = connectedClients.get(PccId.pccId(IpAddress.valueOf(deviceId.toString())));
598
599 Device specificDevice = deviceService.getDevice(actualDevcieId);
600 if (specificDevice == null) {
601 log.error("Unable to find device for specific device id {}.", actualDevcieId.toString());
602 return false;
603 }
604
605 if (pceStore.getGlobalNodeLabel(actualDevcieId) != null) {
606 Map<DeviceId, LabelResourceId> globalNodeLabelMap = pceStore.getGlobalNodeLabels();
607
608 for (Entry<DeviceId, LabelResourceId> entry : globalNodeLabelMap.entrySet()) {
609
610 // Convert from DeviceId to TunnelEndPoint
611 Device srcDevice = deviceService.getDevice(entry.getKey());
612
613 /*
614 * If there is a slight difference in timing such that if device subsystem has removed the device but
615 * PCE store still has it, just ignore such devices.
616 */
617 if (srcDevice == null) {
618 continue;
619 }
620
621 String srcLsrId = srcDevice.annotations().value(LSRID);
622 if (srcLsrId == null) {
623 continue;
624 }
625
626 srTeHandler.pushGlobalNodeLabel(pc, entry.getValue(),
627 IpAddress.valueOf(srcLsrId).getIp4Address().toInt(),
628 PcepLabelOp.ADD, false);
629 }
630
631 Map<Link, LabelResourceId> adjLabelMap = pceStore.getAdjLabels();
632 for (Entry<Link, LabelResourceId> entry : adjLabelMap.entrySet()) {
633 if (entry.getKey().src().deviceId().equals(actualDevcieId)) {
634 srTeHandler.pushAdjacencyLabel(pc,
635 entry.getValue(),
636 (int) entry.getKey().src().port().toLong(),
637 (int) entry.getKey().dst().port().toLong(),
638 PcepLabelOp.ADD
639 );
640 }
641 }
642 }
643
644 srTeHandler.pushGlobalNodeLabel(pc, LabelResourceId.labelResourceId(0),
645 0, PcepLabelOp.ADD, true);
646
647 log.debug("End of label DB sync for device {}", actualDevcieId);
648
649 if (mastershipService.getLocalRole(specificDevice.id()) == MastershipRole.MASTER) {
650 // Allocate node-label to this specific device.
651 allocateNodeLabel(specificDevice);
652
653 // Allocate adjacency label
654 Set<Link> links = linkService.getDeviceEgressLinks(specificDevice.id());
655 if (links != null) {
656 for (Link link : links) {
657 allocateAdjacencyLabel(link);
658 }
659 }
660 }
661 return true;
662 }
663
664 /**
665 * Allocates node label to specific device.
666 *
667 * @param specificDevice device to which node label needs to be allocated
668 */
669 public void allocateNodeLabel(Device specificDevice) {
670 checkNotNull(specificDevice, DEVICE_NULL);
671
672 DeviceId deviceId = specificDevice.id();
673
674 // Retrieve lsrId of a specific device
675 if (specificDevice.annotations() == null) {
676 log.debug("Device {} does not have annotations.", specificDevice.toString());
677 return;
678 }
679
680 String lsrId = specificDevice.annotations().value(LSRID);
681 if (lsrId == null) {
682 log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
683 return;
684 }
685
686 // Get capability config from netconfig
687 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
688 if (cfg == null) {
689 log.error("Unable to find corresponding capability for a lsrd {} from NetConfig.", lsrId);
690 // Save info. When PCEP session is comes up then allocate node-label
691 lsrIdDeviceIdMap.put(lsrId, specificDevice.id());
692 return;
693 }
694
695 // Check whether device has SR-TE Capability
696 if (cfg.labelStackCap()) {
697 srTeHandler.allocateNodeLabel(deviceId, lsrId);
698 }
699 }
700
701 /**
702 * Releases node label of a specific device.
703 *
704 * @param specificDevice this device label and lsr-id information will be
705 * released in other existing devices
706 */
707 public void releaseNodeLabel(Device specificDevice) {
708 checkNotNull(specificDevice, DEVICE_NULL);
709
710 DeviceId deviceId = specificDevice.id();
711
712 // Retrieve lsrId of a specific device
713 if (specificDevice.annotations() == null) {
714 log.debug("Device {} does not have annotations.", specificDevice.toString());
715 return;
716 }
717
718 String lsrId = specificDevice.annotations().value(LSRID);
719 if (lsrId == null) {
720 log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
721 return;
722 }
723
724 // Get capability config from netconfig
725 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
726 if (cfg == null) {
727 log.error("Unable to find corresponding capabilty for a lsrd {} from NetConfig.", lsrId);
728 return;
729 }
730
731 // Check whether device has SR-TE Capability
732 if (cfg.labelStackCap()) {
733 if (!srTeHandler.releaseNodeLabel(deviceId, lsrId)) {
734 log.error("Unable to release node label for a device id {}.", deviceId.toString());
735 }
736 }
737 }
738
739 /**
740 * Allocates adjacency label for a link.
741 *
742 * @param link link
743 */
744 public void allocateAdjacencyLabel(Link link) {
745 checkNotNull(link, LINK_NULL);
746
747 Device specificDevice = deviceService.getDevice(link.src().deviceId());
748
749 // Retrieve lsrId of a specific device
750 if (specificDevice.annotations() == null) {
751 log.debug("Device {} does not have annotations.", specificDevice.toString());
752 return;
753 }
754
755 String lsrId = specificDevice.annotations().value(LSRID);
756 if (lsrId == null) {
757 log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
758 return;
759 }
760
761 // Get capability config from netconfig
762 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
763 if (cfg == null) {
764 log.error("Unable to find corresponding capabilty for a lsrd {} from NetConfig.", lsrId);
765 // Save info. When PCEP session comes up then allocate adjacency
766 // label
767 if (lsrIdDeviceIdMap.get(lsrId) != null) {
768 lsrIdDeviceIdMap.put(lsrId, specificDevice.id());
769 }
770 return;
771 }
772
773 // Check whether device has SR-TE Capability
774 if (cfg.labelStackCap()) {
775 srTeHandler.allocateAdjacencyLabel(link);
776 }
777 }
778
779 /**
780 * Releases allocated adjacency label of a link.
781 *
782 * @param link link
783 */
784 public void releaseAdjacencyLabel(Link link) {
785 checkNotNull(link, LINK_NULL);
786
787 Device specificDevice = deviceService.getDevice(link.src().deviceId());
788
789 // Retrieve lsrId of a specific device
790 if (specificDevice.annotations() == null) {
791 log.debug("Device {} does not have annotations.", specificDevice.toString());
792 return;
793 }
794
795 String lsrId = specificDevice.annotations().value(LSRID);
796 if (lsrId == null) {
797 log.debug("Unable to retrieve lsr-id of a device {}.", specificDevice.toString());
798 return;
799 }
800
801 // Get capability config from netconfig
802 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
803 if (cfg == null) {
804 log.error("Unable to find corresponding capabilty for a lsrd {} from NetConfig.", lsrId);
805 return;
806 }
807
808 // Check whether device has SR-TE Capability
809 if (cfg.labelStackCap()) {
810 if (!srTeHandler.releaseAdjacencyLabel(link)) {
811 log.error("Unable to release adjacency labels for a link {}.", link.toString());
812 }
813 }
814 }
815
816 @Override
817 public LabelStack computeLabelStack(Path path) {
818 return srTeHandler.computeLabelStack(path);
819 }
820
821 @Override
822 public boolean allocateLocalLabel(Tunnel tunnel) {
823 return crHandler.allocateLabel(tunnel);
824 }
825
826 /**
827 * Creates label stack for ERO object from network resource.
828 *
Ray Milkeyef794342016-11-09 16:20:29 -0800829 * @param labelStack label stack
Avantika-Huawei9e848e82016-09-01 12:12:42 +0530830 * @param path (hop list)
831 * @return list of ERO subobjects
832 */
833 @Override
834 public LinkedList<PcepValueType> createPcepLabelStack(DefaultLabelStack labelStack, Path path) {
835 checkNotNull(labelStack);
836
837 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
838 Iterator<Link> links = path.links().iterator();
839 LabelResourceId label = null;
840 Link link = null;
841 PcepValueType subObj = null;
842 PcepNai nai = null;
843 Device dstNode = null;
844 long srcPortNo, dstPortNo;
845
846 ListIterator<LabelResourceId> labelListIterator = labelStack.labelResources().listIterator();
847 while (labelListIterator.hasNext()) {
848 label = labelListIterator.next();
849 link = links.next();
850
851 srcPortNo = link.src().port().toLong();
852 srcPortNo = ((srcPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? srcPortNo & SET : srcPortNo;
853
854 dstPortNo = link.dst().port().toLong();
855 dstPortNo = ((dstPortNo & IDENTIFIER_SET) == IDENTIFIER_SET) ? dstPortNo & SET : dstPortNo;
856
857 nai = new PcepNaiIpv4Adjacency((int) srcPortNo, (int) dstPortNo);
858 subObj = new SrEroSubObject(PcepNaiIpv4Adjacency.ST_TYPE, false, false, false, true, (int) label.labelId(),
859 nai);
860 llSubObjects.add(subObj);
861
862 dstNode = deviceService.getDevice(link.dst().deviceId());
863 nai = new PcepNaiIpv4NodeId(Ip4Address.valueOf(dstNode.annotations().value(LSRID)).toInt());
864
865 if (!labelListIterator.hasNext()) {
866 log.error("Malformed label stack.");
867 }
868 label = labelListIterator.next();
869 subObj = new SrEroSubObject(PcepNaiIpv4NodeId.ST_TYPE, false, false, false, true, (int) label.labelId(),
870 nai);
871 llSubObjects.add(subObj);
872 }
873 return llSubObjects;
874 }
875
Priyanka Bd2b28882016-04-04 16:57:04 +0530876 /**
SureshBR25058b72015-08-13 13:05:06 +0530877 * Implementation of an Pcep Agent which is responsible for
878 * keeping track of connected clients and the state in which
879 * they are.
880 */
881 public class PcepClientAgent implements PcepAgent {
882
883 private final Logger log = LoggerFactory.getLogger(PcepClientAgent.class);
SureshBR25058b72015-08-13 13:05:06 +0530884
885 @Override
886 public boolean addConnectedClient(PccId pccId, PcepClient pc) {
887
888 if (connectedClients.get(pccId) != null) {
889 log.error("Trying to add connectedClient but found a previous "
890 + "value for pcc ip: {}", pccId.toString());
891 return false;
892 } else {
893 log.debug("Added Client {}", pccId.toString());
894 connectedClients.put(pccId, pc);
895 for (PcepClientListener l : pcepClientListener) {
896 l.clientConnected(pccId);
897 }
898 return true;
899 }
900 }
901
902 @Override
903 public boolean validActivation(PccId pccId) {
904 if (connectedClients.get(pccId) == null) {
905 log.error("Trying to activate client but is not in "
906 + "connected client: pccIp {}. Aborting ..", pccId.toString());
907 return false;
908 }
SureshBR25058b72015-08-13 13:05:06 +0530909 return true;
910 }
911
912 @Override
913 public void removeConnectedClient(PccId pccId) {
914
915 connectedClients.remove(pccId);
916 for (PcepClientListener l : pcepClientListener) {
mohamedrahil00f6f262016-11-24 20:20:41 +0530917 log.warn("Removal for {}", pccId.toString());
SureshBR25058b72015-08-13 13:05:06 +0530918 l.clientDisconnected(pccId);
919 }
920 }
921
922 @Override
923 public void processPcepMessage(PccId pccId, PcepMessage m) {
924 processClientMessage(pccId, m);
925 }
Priyanka B94395bf2016-05-21 18:39:46 +0530926
927 @Override
928 public void addNode(PcepClient pc) {
929 for (PcepNodeListener l : pcepNodeListener) {
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530930 l.addDevicePcepConfig(pc);
Priyanka B94395bf2016-05-21 18:39:46 +0530931 }
932 }
933
934 @Override
935 public void deleteNode(PccId pccId) {
936 for (PcepNodeListener l : pcepNodeListener) {
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530937 l.deleteDevicePcepConfig(pccId);
Priyanka B94395bf2016-05-21 18:39:46 +0530938 }
939 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530940
941 @SuppressWarnings({ "unchecked", "rawtypes" })
942 @Override
943 public boolean analyzeSyncMsgList(PccId pccId) {
944 PcepClient pc = getClient(pccId);
945 /*
946 * PLSP_ID is null while tunnel is created at PCE and PCInit msg carries it as 0. It is allocated by PCC and
947 * in that case it becomes the first PCRpt msg from PCC for this LSP, and hence symbolic path name must be
948 * carried in the PCRpt msg. Draft says: The SYMBOLIC-PATH-NAME TLV "MUST" be included in the LSP object in
949 * the LSP State Report (PCRpt) message when during a given PCEP session an LSP is "first" reported to a
950 * PCE. So two separate lists with separate keys are maintained.
951 */
952 Map<LspKey, Tunnel> preSyncLspDbByKey = new HashMap<>();
953 Map<String, Tunnel> preSyncLspDbByName = new HashMap<>();
954
955 // Query tunnel service and fetch all the tunnels with this PCC as ingress.
956 // Organize into two maps, with LSP key if known otherwise with symbolic path name, for quick search.
957 Collection<Tunnel> queriedTunnels = tunnelService.queryTunnel(Tunnel.Type.MPLS);
958 for (Tunnel tunnel : queriedTunnels) {
959 if (((IpTunnelEndPoint) tunnel.src()).ip().equals(pccId.ipAddress())) {
960 String pLspId = tunnel.annotations().value(PLSP_ID);
961 if (pLspId != null) {
962 String localLspId = tunnel.annotations().value(LOCAL_LSP_ID);
963 checkNotNull(localLspId);
964 LspKey lspKey = new LspKey(Integer.valueOf(pLspId), Short.valueOf(localLspId));
965 preSyncLspDbByKey.put(lspKey, tunnel);
966 } else {
967 preSyncLspDbByName.put(tunnel.tunnelName().value(), tunnel);
968 }
969 }
970 }
971
972 List<PcepStateReport> syncStateRptList = pc.getSyncMsgList(pccId);
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530973 if (syncStateRptList == null) {
974 // When there are no LSPs to sync, directly end-of-sync PCRpt will come and the
975 // list will be null.
976 syncStateRptList = Collections.EMPTY_LIST;
Avantika-Huaweif849aab2016-06-21 22:29:15 +0530977 log.debug("No LSPs reported from PCC during sync.");
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530978 }
979
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530980 Iterator<PcepStateReport> stateRptListIterator = syncStateRptList.iterator();
981
982 // For every report, fetch PLSP id, local LSP id and symbolic path name from the message.
Avantika-Huaweifc10dca2016-06-10 16:13:55 +0530983 while (stateRptListIterator.hasNext()) {
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +0530984 PcepStateReport stateRpt = stateRptListIterator.next();
985 Tunnel tunnel = null;
986
987 PcepLspObject lspObj = stateRpt.getLspObject();
988 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
989 StatefulIPv4LspIdentifiersTlv ipv4LspIdenTlv = null;
990 SymbolicPathNameTlv pathNameTlv = null;
991
992 while (listTlvIterator.hasNext()) {
993 PcepValueType tlv = listTlvIterator.next();
994 switch (tlv.getType()) {
995 case StatefulIPv4LspIdentifiersTlv.TYPE:
996 ipv4LspIdenTlv = (StatefulIPv4LspIdentifiersTlv) tlv;
997 break;
998
999 case SymbolicPathNameTlv.TYPE:
1000 pathNameTlv = (SymbolicPathNameTlv) tlv;
1001 break;
1002
1003 default:
1004 break;
1005 }
1006 }
1007
1008 LspKey lspKeyOfRpt = new LspKey(lspObj.getPlspId(), ipv4LspIdenTlv.getLspId());
1009 tunnel = preSyncLspDbByKey.get(lspKeyOfRpt);
1010 // PCE tunnel is matched with PCRpt LSP. Now delete it from the preSyncLspDb list as the residual
1011 // non-matching list will be processed at the end.
1012 if (tunnel != null) {
1013 preSyncLspDbByKey.remove(lspKeyOfRpt);
1014 } else if (pathNameTlv != null) {
1015 tunnel = preSyncLspDbByName.get(Arrays.toString(pathNameTlv.getValue()));
1016 if (tunnel != null) {
Avantika-Huawei9e848e82016-09-01 12:12:42 +05301017 preSyncLspDbByName.remove(tunnel.tunnelName().value());
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301018 }
1019 }
1020
1021 if (tunnel == null) {
1022 // If remove flag is set, and tunnel is not known to PCE, ignore it.
1023 if (lspObj.getCFlag() && !lspObj.getRFlag()) {
1024 // For initiated LSP, need to send PCInit delete msg.
1025 try {
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301026 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(SrpIdGenerators.create())
1027 .setRFlag(true).build();
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301028 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest()
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301029 .setLspObject(lspObj).setSrpObject(srpobj).build();
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301030 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList
1031 = new LinkedList<PcInitiatedLspRequest>();
1032 llPcInitiatedLspRequestList.add(releaseLspRequest);
1033
1034 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
1035 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
1036
Avantika-Huawei3c2d3eb2016-06-22 09:34:00 +05301037 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301038 } catch (PcepParseException e) {
1039 log.error("Exception occured while sending initiate delete message {}", e.getMessage());
1040 }
Avantika-Huaweif849aab2016-06-21 22:29:15 +05301041 continue;
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301042 }
Avantika-Huaweid1e36bd2016-05-26 12:47:16 +05301043 }
1044
1045 if (!lspObj.getCFlag()) {
1046 // For learned LSP process both add/update PCRpt.
1047 LinkedList<PcepStateReport> llPcRptList = new LinkedList<>();
1048 llPcRptList.add(stateRpt);
1049 PcepMessage pcReportMsg = pc.factory().buildReportMsg().setStateReportList((llPcRptList))
1050 .build();
1051
1052 for (PcepEventListener l : pcepEventListener) {
1053 l.handleMessage(pccId, pcReportMsg);
1054 }
1055 continue;
1056 }
1057
1058 // Implied that tunnel != null and lspObj.getCFlag() is set
1059 // State different for PCC sent LSP and PCE known LSP, send PCUpd msg.
1060 State tunnelState = PcepLspStatus
1061 .getTunnelStatusFromLspStatus(PcepLspStatus.values()[lspObj.getOFlag()]);
1062 if (tunnelState != tunnel.state()) {
1063 for (PcepEventListener l : pcepEventListener) {
1064 l.handleEndOfSyncAction(tunnel, SEND_UPDATE);
1065 }
1066 }
1067 }
1068
1069 // Check which tunnels are extra at PCE that were not reported by PCC.
1070 Map<Object, Tunnel> preSyncLspDb = (Map) preSyncLspDbByKey;
1071 handleResidualTunnels(preSyncLspDb);
1072 preSyncLspDbByKey = null;
1073
1074 preSyncLspDb = (Map) preSyncLspDbByName;
1075 handleResidualTunnels(preSyncLspDb);
1076 preSyncLspDbByName = null;
1077 preSyncLspDb = null;
1078
1079 pc.removeSyncMsgList(pccId);
1080 return true;
1081 }
1082
1083 /*
1084 * Go through the tunnels which are known by PCE but were not reported by PCC during LSP DB sync and take
1085 * appropriate actions.
1086 */
1087 private void handleResidualTunnels(Map<Object, Tunnel> preSyncLspDb) {
1088 for (Tunnel pceExtraTunnel : preSyncLspDb.values()) {
1089 if (pceExtraTunnel.annotations().value(PCE_INIT) == null
1090 || "false".equalsIgnoreCase(pceExtraTunnel.annotations().value(PCE_INIT))) {
1091 // PCC initiated tunnels should be removed from tunnel store.
1092 for (PcepEventListener l : pcepEventListener) {
1093 l.handleEndOfSyncAction(pceExtraTunnel, REMOVE);
1094 }
1095 } else {
1096 // PCE initiated tunnels should be initiated again.
1097 for (PcepEventListener l : pcepEventListener) {
1098 l.handleEndOfSyncAction(pceExtraTunnel, UNSTABLE);
1099 }
1100 }
1101 }
1102 }
SureshBR25058b72015-08-13 13:05:06 +05301103 }
Avantika-Huawei9e848e82016-09-01 12:12:42 +05301104
1105 /*
1106 * Handle device events.
1107 */
1108 private class InternalDeviceListener implements DeviceListener {
1109 @Override
1110 public void event(DeviceEvent event) {
1111 Device specificDevice = event.subject();
1112 if (specificDevice == null) {
1113 log.error("Unable to find device from device event.");
1114 return;
1115 }
1116
1117 switch (event.type()) {
1118
1119 case DEVICE_ADDED:
1120 // Node-label allocation is being done during Label DB Sync.
1121 // So, when device is detected, no need to do node-label
1122 // allocation.
1123 String lsrId = specificDevice.annotations().value(LSRID);
1124 if (lsrId != null) {
1125 pceStore.addLsrIdDevice(lsrId, specificDevice.id());
1126
1127 // Search in failed DB sync store. If found, trigger label DB sync.
1128 DeviceId pccDeviceId = DeviceId.deviceId(lsrId);
1129 if (pceStore.hasPccLsr(pccDeviceId)) {
1130 log.debug("Continue to perform label DB sync for device {}.", pccDeviceId.toString());
1131 try {
1132 syncLabelDb(pccDeviceId);
1133 } catch (PcepParseException e) {
1134 log.error("Exception caught in sending label masg to PCC while in sync.");
1135 }
1136 pceStore.removePccLsr(pccDeviceId);
1137 }
1138 }
1139 break;
1140
1141 case DEVICE_REMOVED:
1142 // Release node-label
1143 if (mastershipService.getLocalRole(specificDevice.id()) == MastershipRole.MASTER) {
1144 releaseNodeLabel(specificDevice);
1145 }
1146
1147 if (specificDevice.annotations().value(LSRID) != null) {
1148 pceStore.removeLsrIdDevice(specificDevice.annotations().value(LSRID));
1149 }
1150 break;
1151
1152 default:
1153 break;
1154 }
1155 }
1156 }
1157
1158 /*
1159 * Handle link events.
1160 */
1161 private class InternalLinkListener implements LinkListener {
1162 @Override
1163 public void event(LinkEvent event) {
1164 Link link = event.subject();
1165
1166 switch (event.type()) {
1167
1168 case LINK_ADDED:
1169 // Allocate adjacency label
1170 if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
1171 allocateAdjacencyLabel(link);
1172 }
1173 break;
1174
1175 case LINK_REMOVED:
1176 // Release adjacency label
1177 if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
1178 releaseAdjacencyLabel(link);
1179 }
1180 break;
1181
1182 default:
1183 break;
1184 }
1185 }
1186 }
1187
1188 private class InternalConfigListener implements NetworkConfigListener {
1189
1190 @Override
1191 public void event(NetworkConfigEvent event) {
1192
1193 if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED)
1194 && event.configClass().equals(DeviceCapability.class)) {
1195
1196 DeviceId deviceIdLsrId = (DeviceId) event.subject();
1197 String lsrId = deviceIdLsrId.toString();
1198 DeviceId deviceId = lsrIdDeviceIdMap.get(lsrId);
1199 if (deviceId == null) {
1200 log.debug("Unable to find device id for a lsr-id {} from lsr-id and device-id map.", lsrId);
1201 return;
1202 }
1203
1204 DeviceCapability cfg = netCfgService.getConfig(DeviceId.deviceId(lsrId), DeviceCapability.class);
1205 if (cfg == null) {
1206 log.error("Unable to find corresponding capabilty for a lsrd {}.", lsrId);
1207 return;
1208 }
1209
1210 if (cfg.labelStackCap()) {
1211 if (mastershipService.getLocalRole(deviceId) == MastershipRole.MASTER) {
1212 // Allocate node-label
1213 srTeHandler.allocateNodeLabel(deviceId, lsrId);
1214
1215 // Allocate adjacency label to links which are
1216 // originated from this specific device id
1217 Set<Link> links = linkService.getDeviceEgressLinks(deviceId);
1218 for (Link link : links) {
1219 if (!srTeHandler.allocateAdjacencyLabel(link)) {
1220 return;
1221 }
1222 }
1223 }
1224 }
1225 // Remove lsrId info from map
1226 lsrIdDeviceIdMap.remove(lsrId);
1227 }
1228 }
1229 }
SureshBR25058b72015-08-13 13:05:06 +05301230}