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