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