blob: 152a3882743b3996b3d8b804adb738198860f4c8 [file] [log] [blame]
cheng fan48e832c2015-05-29 01:54:47 +08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.provider.pcep.tunnel.impl;
17
18import static com.google.common.base.Preconditions.checkNotNull;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053019import static org.onosproject.net.DefaultAnnotations.EMPTY;
cheng fan48e832c2015-05-29 01:54:47 +080020import static org.onosproject.net.DeviceId.deviceId;
21import static org.onosproject.net.PortNumber.portNumber;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053022import static org.onosproject.pcep.api.PcepDpid.uri;
cheng fan48e832c2015-05-29 01:54:47 +080023import static org.slf4j.LoggerFactory.getLogger;
24
25import java.util.ArrayList;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053026import java.util.Collections;
cheng fan48e832c2015-05-29 01:54:47 +080027import java.util.HashMap;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053028import java.util.LinkedList;
cheng fan48e832c2015-05-29 01:54:47 +080029import java.util.List;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053030import java.util.ListIterator;
cheng fan48e832c2015-05-29 01:54:47 +080031import java.util.Optional;
32
33import org.apache.felix.scr.annotations.Activate;
34import org.apache.felix.scr.annotations.Component;
35import org.apache.felix.scr.annotations.Deactivate;
36import org.apache.felix.scr.annotations.Reference;
37import org.apache.felix.scr.annotations.ReferenceCardinality;
38import org.apache.felix.scr.annotations.Service;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053039import org.onlab.packet.IpAddress;
cheng fan48e832c2015-05-29 01:54:47 +080040import org.onosproject.core.DefaultGroupId;
41import org.onosproject.incubator.net.tunnel.DefaultOpticalTunnelEndPoint;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053042import org.onosproject.incubator.net.tunnel.DefaultTunnel;
cheng fan48e832c2015-05-29 01:54:47 +080043import org.onosproject.incubator.net.tunnel.DefaultTunnelDescription;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053044import org.onosproject.incubator.net.tunnel.IpTunnelEndPoint;
cheng fan48e832c2015-05-29 01:54:47 +080045import org.onosproject.incubator.net.tunnel.OpticalLogicId;
46import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint;
47import org.onosproject.incubator.net.tunnel.Tunnel;
48import org.onosproject.incubator.net.tunnel.TunnelDescription;
49import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
50import org.onosproject.incubator.net.tunnel.TunnelId;
51import org.onosproject.incubator.net.tunnel.TunnelName;
52import org.onosproject.incubator.net.tunnel.TunnelProvider;
53import org.onosproject.incubator.net.tunnel.TunnelProviderRegistry;
54import org.onosproject.incubator.net.tunnel.TunnelProviderService;
55import org.onosproject.net.ConnectPoint;
56import org.onosproject.net.DefaultAnnotations;
57import org.onosproject.net.DefaultLink;
58import org.onosproject.net.DefaultPath;
59import org.onosproject.net.DeviceId;
60import org.onosproject.net.ElementId;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053061import org.onosproject.net.IpElementId;
cheng fan48e832c2015-05-29 01:54:47 +080062import org.onosproject.net.Link;
63import org.onosproject.net.Path;
64import org.onosproject.net.PortNumber;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053065import org.onosproject.net.SparseAnnotations;
cheng fan48e832c2015-05-29 01:54:47 +080066import org.onosproject.net.provider.AbstractProvider;
67import org.onosproject.net.provider.ProviderId;
68import org.onosproject.pcep.api.PcepController;
69import org.onosproject.pcep.api.PcepDpid;
70import org.onosproject.pcep.api.PcepHopNodeDescription;
71import org.onosproject.pcep.api.PcepOperator.OperationType;
72import org.onosproject.pcep.api.PcepTunnel;
73import org.onosproject.pcep.api.PcepTunnel.PATHTYPE;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053074import org.onosproject.pcep.api.PcepTunnel.PathState;
cheng fan48e832c2015-05-29 01:54:47 +080075import org.onosproject.pcep.api.PcepTunnelListener;
Phanendra Manda37b97fb2015-08-15 02:04:24 +053076import org.onosproject.pcep.controller.PccId;
77import org.onosproject.pcep.controller.PcepClient;
78import org.onosproject.pcep.controller.PcepClientController;
79import org.onosproject.pcep.controller.PcepClientListener;
80import org.onosproject.pcep.controller.PcepEventListener;
81import org.onosproject.pcepio.exceptions.PcepParseException;
82import org.onosproject.pcepio.protocol.PcInitiatedLspRequest;
83import org.onosproject.pcepio.protocol.PcepAttribute;
84import org.onosproject.pcepio.protocol.PcepBandwidthObject;
85import org.onosproject.pcepio.protocol.PcepEndPointsObject;
86import org.onosproject.pcepio.protocol.PcepEroObject;
87import org.onosproject.pcepio.protocol.PcepInitiateMsg;
88import org.onosproject.pcepio.protocol.PcepLspObject;
89import org.onosproject.pcepio.protocol.PcepMessage;
90import org.onosproject.pcepio.protocol.PcepMsgPath;
91import org.onosproject.pcepio.protocol.PcepReportMsg;
92import org.onosproject.pcepio.protocol.PcepRroObject;
93import org.onosproject.pcepio.protocol.PcepSrpObject;
94import org.onosproject.pcepio.protocol.PcepStateReport;
95import org.onosproject.pcepio.protocol.PcepUpdateMsg;
96import org.onosproject.pcepio.protocol.PcepUpdateRequest;
97import org.onosproject.pcepio.types.IPv4SubObject;
98import org.onosproject.pcepio.types.PcepValueType;
99import org.onosproject.pcepio.types.StatefulIPv4LspIdentidiersTlv;
100import org.onosproject.pcepio.types.SymbolicPathNameTlv;
cheng fan48e832c2015-05-29 01:54:47 +0800101import org.slf4j.Logger;
102
103import static org.onosproject.pcep.api.PcepDpid.*;
104
105/**
106 * Provider which uses an PCEP controller to detect, update, create network
107 * tunnels.
108 */
109@Component(immediate = true)
110@Service
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530111public class PcepTunnelProvider extends AbstractProvider implements TunnelProvider {
cheng fan48e832c2015-05-29 01:54:47 +0800112
113 private static final Logger log = getLogger(PcepTunnelProvider.class);
114 private static final long MAX_BANDWIDTH = 99999744;
115 private static final long MIN_BANDWIDTH = 64;
cheng fan7716ec92015-05-31 01:53:19 +0800116 private static final String BANDWIDTH_UINT = "kbps";
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530117 static final String PROVIDER_ID = "org.onosproject.provider.tunnel.pcep";
cheng fan48e832c2015-05-29 01:54:47 +0800118
119 private static final String TUNNLE_NOT_NULL = "Create failed,The given port may be wrong or has been occupied.";
120
121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
122 protected TunnelProviderRegistry tunnelProviderRegistry;
123
124 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
125 protected PcepController controller;
126
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
128 protected PcepClientController pcepClientController;
cheng fan48e832c2015-05-29 01:54:47 +0800129 TunnelProviderService service;
130
131 HashMap<String, TunnelId> tunnelMap = new HashMap<String, TunnelId>();
132
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530133 private InnerTunnelProvider listener = new InnerTunnelProvider();
134
135 protected PcepTunnelApiMapper pcepTunnelAPIMapper = new PcepTunnelApiMapper();
136 private static final int DEFAULT_BANDWIDTH_VALUE = 10;
cheng fan48e832c2015-05-29 01:54:47 +0800137
138 /**
139 * Creates a Tunnel provider.
140 */
141 public PcepTunnelProvider() {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530142 super(new ProviderId("pcep", PROVIDER_ID));
cheng fan48e832c2015-05-29 01:54:47 +0800143 }
144
145 @Activate
146 public void activate() {
147 service = tunnelProviderRegistry.register(this);
148 controller.addTunnelListener(listener);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530149 pcepClientController.addListener(listener);
150 pcepClientController.addEventListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800151 log.info("Started");
152 }
153
154 @Deactivate
155 public void deactivate() {
156 tunnelProviderRegistry.unregister(this);
157 controller.removeTunnelListener(listener);
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530158 pcepClientController.removeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800159 log.info("Stopped");
160 }
161
162 @Override
163 public void setupTunnel(Tunnel tunnel, Path path) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530164 if (tunnel.type() != Tunnel.Type.MPLS) {
165 log.error("Tunnel Type MPLS is only supported");
166 return;
167 }
cheng fan48e832c2015-05-29 01:54:47 +0800168
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530169 // check for tunnel end points
170 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
171 log.error("Tunnel source or destination is not valid");
172 return;
173 }
174
175 // Get the pcc client
176 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
177
178 if (!(pc instanceof PcepClient)) {
179 log.error("There is no PCC connected with ip addresss {}"
180 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
181 return;
182 }
183 pcepSetupTunnel(tunnel, path, pc);
cheng fan48e832c2015-05-29 01:54:47 +0800184 }
185
186 @Override
187 public void setupTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800188
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530189 if (tunnel.type() != Tunnel.Type.MPLS) {
190 log.error("Tunnel Type MPLS is only supported");
191 return;
192 }
193
194 if (!(srcElement instanceof IpElementId)) {
195 log.error("Element id is not valid");
196 return;
197 }
198
199 // check for tunnel end points
200 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
201 log.error("Tunnel source or destination is not valid");
202 return;
203 }
204
205 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
206
207 if (!(pc instanceof PcepClient)) {
208 log.error("There is no PCC connected with ip addresss {}"
209 + ((IpElementId) srcElement).ipAddress().toString());
210 return;
211 }
212 pcepSetupTunnel(tunnel, path, pc);
cheng fan48e832c2015-05-29 01:54:47 +0800213 }
214
215 @Override
216 public void releaseTunnel(Tunnel tunnel) {
cheng fan48e832c2015-05-29 01:54:47 +0800217
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530218 if (tunnel.type() != Tunnel.Type.MPLS) {
219 log.error("Tunnel Type MPLS is only supported");
220 return;
221 }
222
223 // check for tunnel end points
224 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
225 log.error("Tunnel source or destination is not valid");
226 return;
227 }
228
229 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
230
231 if (!(pc instanceof PcepClient)) {
232 log.error("There is no PCC connected with ip addresss {}"
233 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
234 return;
235 }
236 pcepReleaseTunnel(tunnel, pc);
cheng fan48e832c2015-05-29 01:54:47 +0800237 }
238
239 @Override
240 public void releaseTunnel(ElementId srcElement, Tunnel tunnel) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530241 if (tunnel.type() != Tunnel.Type.MPLS) {
242 log.error("Tunnel Type MPLS is only supported");
243 return;
244 }
cheng fan48e832c2015-05-29 01:54:47 +0800245
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530246 if (!(srcElement instanceof IpElementId)) {
247 log.error("Element id is not valid");
248 return;
249 }
250
251 // check for tunnel end points
252 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
253 log.error("Tunnel source or destination is not valid");
254 return;
255 }
256
257 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
258
259 if (!(pc instanceof PcepClient)) {
260 log.error("There is no PCC connected with ip addresss {}"
261 + ((IpElementId) srcElement).ipAddress().toString());
262 return;
263 }
264 pcepReleaseTunnel(tunnel, pc);
cheng fan48e832c2015-05-29 01:54:47 +0800265 }
266
267 @Override
268 public void updateTunnel(Tunnel tunnel, Path path) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530269 if (tunnel.type() != Tunnel.Type.MPLS) {
270 log.error("Tunnel Type MPLS is only supported");
271 return;
272 }
cheng fan48e832c2015-05-29 01:54:47 +0800273
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530274 // check for tunnel end points
275 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
276 log.error("Tunnel source or destination is not valid");
277 return;
278 }
279
280 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpTunnelEndPoint) tunnel.src()).ip()));
281
282 if (!(pc instanceof PcepClient)) {
283 log.error("There is no PCC connected with ip addresss {}"
284 + ((IpTunnelEndPoint) tunnel.src()).ip().toString());
285 return;
286 }
287 pcepUpdateTunnel(tunnel, path, pc);
cheng fan48e832c2015-05-29 01:54:47 +0800288 }
289
290 @Override
291 public void updateTunnel(ElementId srcElement, Tunnel tunnel, Path path) {
cheng fan48e832c2015-05-29 01:54:47 +0800292
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530293 if (tunnel.type() != Tunnel.Type.MPLS) {
294 log.error("Tunnel Type MPLS is only supported");
295 return;
296 }
297
298 if (!(srcElement instanceof IpElementId)) {
299 log.error("Element id is not valid");
300 return;
301 }
302
303 // check for tunnel end points
304 if (!(tunnel.src() instanceof IpTunnelEndPoint) || !(tunnel.dst() instanceof IpTunnelEndPoint)) {
305 log.error("Tunnel source or destination is not valid");
306 return;
307 }
308
309 PcepClient pc = pcepClientController.getClient(PccId.pccId(((IpElementId) srcElement).ipAddress()));
310
311 if (!(pc instanceof PcepClient)) {
312 log.error("There is no PCC connected with ip addresss {}"
313 + ((IpElementId) srcElement).ipAddress().toString());
314 return;
315 }
316 pcepUpdateTunnel(tunnel, path, pc);
cheng fan48e832c2015-05-29 01:54:47 +0800317 }
318
319 @Override
320 public TunnelId tunnelAdded(TunnelDescription tunnel) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530321 if (tunnel.type() == Tunnel.Type.MPLS) {
322 pcepTunnelAPIMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
323 return service.tunnelAdded(tunnel);
324 }
cheng fan48e832c2015-05-29 01:54:47 +0800325
cheng fan7716ec92015-05-31 01:53:19 +0800326 long bandwidth = Long
327 .parseLong(tunnel.annotations().value("bandwidth"));
cheng fan48e832c2015-05-29 01:54:47 +0800328
329 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800330 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800331 return null;
332 }
333
334 // endpoints
335 OpticalTunnelEndPoint src = (org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint) tunnel
336 .src();
337 OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst();
338 // devices
339 DeviceId srcId = (DeviceId) src.elementId().get();
340 DeviceId dstId = (DeviceId) dst.elementId().get();
341
342 // ports
343 long srcPort = src.portNumber().get().toLong();
344 long dstPort = dst.portNumber().get().toLong();
345
346 // type
347 if (tunnel.type() != Tunnel.Type.VLAN) {
cheng fan7716ec92015-05-31 01:53:19 +0800348 error("Illegal tunnel type. Only support VLAN tunnel creation.");
cheng fan48e832c2015-05-29 01:54:47 +0800349 return null;
350 }
351
352 PcepTunnel pcepTunnel = controller.applyTunnel(srcId, dstId, srcPort,
353 dstPort, bandwidth,
354 tunnel.tunnelName()
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530355 .value());
cheng fan48e832c2015-05-29 01:54:47 +0800356
357 checkNotNull(pcepTunnel, TUNNLE_NOT_NULL);
358 TunnelDescription tunnelAdded = buildOpticalTunnel(pcepTunnel, null);
359 TunnelId tunnelId = service.tunnelAdded(tunnelAdded);
360
361 tunnelMap.put(String.valueOf(pcepTunnel.id()), tunnelId);
362 return tunnelId;
363 }
364
365 @Override
366 public void tunnelRemoved(TunnelDescription tunnel) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530367 if (tunnel.type() == Tunnel.Type.MPLS) {
368 pcepTunnelAPIMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
369 service.tunnelRemoved(tunnel);
370 }
371
cheng fan48e832c2015-05-29 01:54:47 +0800372 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
373 checkNotNull(tunnelOld, "The tunnel id is not exsited.");
374 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800375 error("Illegal tunnel type. Only support VLAN tunnel deletion.");
cheng fan48e832c2015-05-29 01:54:47 +0800376 return;
377 }
378 String pcepTunnelId = getPCEPTunnelKey(tunnel.id());
379 checkNotNull(pcepTunnelId, "The tunnel id is not exsited.");
cheng fan7716ec92015-05-31 01:53:19 +0800380 if (!controller.deleteTunnel(pcepTunnelId)) {
381 error("Delete tunnel failed, Maybe some devices have been disconnected.");
382 return;
cheng fan48e832c2015-05-29 01:54:47 +0800383 }
384 tunnelMap.remove(pcepTunnelId);
385 service.tunnelRemoved(tunnel);
cheng fan48e832c2015-05-29 01:54:47 +0800386 }
387
388 @Override
389 public void tunnelUpdated(TunnelDescription tunnel) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530390 if (tunnel.type() == Tunnel.Type.MPLS) {
391 pcepTunnelAPIMapper.removeFromCoreTunnelRequestQueue(tunnel.id());
392 service.tunnelUpdated(tunnel);
393 }
cheng fan48e832c2015-05-29 01:54:47 +0800394
395 Tunnel tunnelOld = tunnelQueryById(tunnel.id());
396 if (tunnelOld.type() != Tunnel.Type.VLAN) {
cheng fan93258c72015-06-02 23:42:32 +0800397 error("Illegal tunnel type. Only support VLAN tunnel update.");
cheng fan48e832c2015-05-29 01:54:47 +0800398 return;
399 }
cheng fan7716ec92015-05-31 01:53:19 +0800400 long bandwidth = Long
401 .parseLong(tunnel.annotations().value("bandwidth"));
cheng fan48e832c2015-05-29 01:54:47 +0800402 if (bandwidth < MIN_BANDWIDTH || bandwidth > MAX_BANDWIDTH) {
cheng fan7716ec92015-05-31 01:53:19 +0800403 error("Update failed, invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800404 return;
405 }
406 String pcepTunnelId = getPCEPTunnelKey(tunnel.id());
407
408 checkNotNull(pcepTunnelId, "Invalid tunnel id");
409 if (!controller.updateTunnelBandwidth(pcepTunnelId, bandwidth)) {
410
cheng fan7716ec92015-05-31 01:53:19 +0800411 error("Update failed,maybe invalid bandwidth.");
cheng fan48e832c2015-05-29 01:54:47 +0800412 return;
413
414 }
415 service.tunnelUpdated(tunnel);
416 }
417
cheng fan7716ec92015-05-31 01:53:19 +0800418 private void error(String info) {
419 System.err.println(info);
420 }
421
cheng fan48e832c2015-05-29 01:54:47 +0800422 // Short-hand for creating a connection point.
423 private ConnectPoint connectPoint(PcepDpid id, long port) {
424 return new ConnectPoint(deviceId(uri(id)), portNumber(port));
425 }
426
427 // Short-hand for creating a link.
428 private Link link(PcepDpid src, long sp, PcepDpid dst, long dp) {
429 return new DefaultLink(id(), connectPoint(src, sp), connectPoint(dst,
430 dp),
431 Link.Type.TUNNEL);
432 }
433
434 // Creates a path that leads through the given devices.
435 private Path createPath(List<PcepHopNodeDescription> hopList,
cheng fan93258c72015-06-02 23:42:32 +0800436 PATHTYPE pathtype, PathState pathState) {
cheng fan48e832c2015-05-29 01:54:47 +0800437 if (hopList == null || hopList.size() == 0) {
438 return null;
439 }
440 List<Link> links = new ArrayList<>();
441 for (int i = 1; i < hopList.size() - 1; i = i + 2) {
442 links.add(link(hopList.get(i).getDeviceId(), hopList.get(i)
443 .getPortNum(), hopList.get(i + 1).getDeviceId(), hopList
444 .get(i + 1).getPortNum()));
445 }
446
447 int hopNum = hopList.size() - 2;
448 DefaultAnnotations extendAnnotations = DefaultAnnotations.builder()
449 .set("pathNum", String.valueOf(hopNum))
cheng fan93258c72015-06-02 23:42:32 +0800450 .set("pathState", String.valueOf(pathState))
cheng fan48e832c2015-05-29 01:54:47 +0800451 .set("pathType", String.valueOf(pathtype)).build();
452 return new DefaultPath(id(), links, hopNum, extendAnnotations);
453 }
454
455 // convert the path description to a string.
456 public String pathToString(List<Link> links) {
457 StringBuilder builder = new StringBuilder();
458 builder.append("{");
459 for (Link link : links) {
460 builder.append("(Device:" + link.src().deviceId() + " Port:"
461 + link.src().port().toLong());
462 builder.append(" Device:" + link.dst().deviceId() + " Port:"
463 + link.dst().port().toLong());
464 builder.append(")");
465 }
466 builder.append("}");
467 return builder.toString();
468 }
469
470 // build a TunnelDescription.
471 private TunnelDescription buildOpticalTunnel(PcepTunnel pcepTunnel,
472 TunnelId tunnelId) {
473 TunnelEndPoint srcPoint = null;
474 TunnelEndPoint dstPoint = null;
475 Tunnel.Type tunnelType = null;
476 TunnelName name = TunnelName.tunnelName(pcepTunnel.name());
477
478 // add path after codes of tunnel's path merged
479 Path path = createPath(pcepTunnel.getHopList(),
cheng fan93258c72015-06-02 23:42:32 +0800480 pcepTunnel.getPathType(),
481 pcepTunnel.getPathState());
cheng fan48e832c2015-05-29 01:54:47 +0800482
483 OpticalTunnelEndPoint.Type endPointType = null;
484 switch (pcepTunnel.type()) {
485 case OCH:
486 tunnelType = Tunnel.Type.OCH;
487 endPointType = OpticalTunnelEndPoint.Type.LAMBDA;
488 break;
489
490 case OTN:
491 tunnelType = Tunnel.Type.ODUK;
492 endPointType = OpticalTunnelEndPoint.Type.TIMESLOT;
493 break;
494
495 case UNI:
496 tunnelType = Tunnel.Type.VLAN;
497 endPointType = null;
498 break;
499
500 default:
501 break;
502 }
503 DeviceId srcDid = deviceId(uri(pcepTunnel.srcDeviceID()));
504 DeviceId dstDid = deviceId(uri(pcepTunnel.dstDeviceId()));
505 PortNumber srcPort = PortNumber.portNumber(pcepTunnel.srcPort());
506 PortNumber dstPort = PortNumber.portNumber(pcepTunnel.dstPort());
507
508 srcPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(srcDid),
509 Optional.of(srcPort), null,
510 endPointType,
511 OpticalLogicId.logicId(0),
512 true);
513 dstPoint = new DefaultOpticalTunnelEndPoint(id(), Optional.of(dstDid),
514 Optional.of(dstPort), null,
515 endPointType,
516 OpticalLogicId.logicId(0),
517 true);
518
519 // basic annotations
cheng fan7716ec92015-05-31 01:53:19 +0800520 DefaultAnnotations annotations = DefaultAnnotations
521 .builder()
cheng fan48e832c2015-05-29 01:54:47 +0800522 .set("SLA", String.valueOf(pcepTunnel.getSla()))
cheng fan7716ec92015-05-31 01:53:19 +0800523 .set("bandwidth",
524 String.valueOf(pcepTunnel.bandWidth()) + BANDWIDTH_UINT)
cheng fan48e832c2015-05-29 01:54:47 +0800525 .set("index", String.valueOf(pcepTunnel.id())).build();
526
cheng fan48e832c2015-05-29 01:54:47 +0800527 // a VLAN tunnel always carry OCH tunnel, this annotation is the index
528 // of a OCH tunnel.
cheng fan93258c72015-06-02 23:42:32 +0800529 if (pcepTunnel.underlayTunnelId() != 0) {
cheng fan48e832c2015-05-29 01:54:47 +0800530 DefaultAnnotations extendAnnotations = DefaultAnnotations
531 .builder()
532 .set("underLayTunnelIndex",
cheng fan93258c72015-06-02 23:42:32 +0800533 String.valueOf(pcepTunnel.underlayTunnelId())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800534 annotations = DefaultAnnotations.merge(annotations,
535 extendAnnotations);
536
537 }
538 TunnelDescription tunnel = new DefaultTunnelDescription(
539 tunnelId,
540 srcPoint,
541 dstPoint,
542 tunnelType,
543 new DefaultGroupId(
544 0),
545 id(), name,
546 path,
547 annotations);
548 return tunnel;
549
550 }
551
552 /**
553 * Get the tunnelID according to the tunnel key.
554 *
555 * @param tunnelKey tunnel key
556 * @return corresponding tunnel id of the a tunnel key.
557 */
558 private TunnelId getTunnelId(String tunnelKey) {
cheng fan48e832c2015-05-29 01:54:47 +0800559 for (String key : tunnelMap.keySet()) {
560 if (key.equals(tunnelKey)) {
561 return tunnelMap.get(key);
562 }
563 }
564 return null;
565 }
566
567 /**
568 * Get the tunnel key according to the tunnelID.
569 *
570 * @param tunnelId tunnel id
571 * @return corresponding a tunnel key of the tunnel id.
572 */
573 private String getPCEPTunnelKey(TunnelId tunnelId) {
574 for (String key : tunnelMap.keySet()) {
575 if (tunnelMap.get(key).id() == tunnelId.id()) {
576 return key;
577 }
578 }
579 return null;
580
581 }
582
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530583 /**
584 * Creates list of hops for ERO object from Path.
585 *
586 * @param path network path
587 * @return list of ipv4 subobjects
588 */
589 private LinkedList<PcepValueType> createPcepPath(Path path) {
590 LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
591 List<Link> listLink = path.links();
592 ConnectPoint source = null;
593 ConnectPoint destination = null;
594 IpAddress ipDstAddress = null;
595 IpAddress ipSrcAddress = null;
596 PcepValueType subObj = null;
597
598 for (Link link : listLink) {
599 source = link.src();
600 if (!(source.equals(destination))) {
601 //set IPv4SubObject for ERO object
602 ipSrcAddress = source.ipElementId().ipAddress();
603 subObj = new IPv4SubObject(ipSrcAddress.getIp4Address().toInt());
604 llSubObjects.add(subObj);
605 }
606
607 destination = link.dst();
608 ipDstAddress = destination.ipElementId().ipAddress();
609 subObj = new IPv4SubObject(ipDstAddress.getIp4Address().toInt());
610 llSubObjects.add(subObj);
611 }
612 return llSubObjects;
613 }
614
615 /**
616 * Creates PcInitiated lsp request list for setup tunnel.
617 *
618 * @param tunnel mpls tunnel
619 * @param path network path
620 * @param pc pcep client
621 * @param srpId unique id for pcep message
622 * @return list of PcInitiatedLspRequest
623 * @throws PcepParseException while building pcep objects fails
624 */
625 LinkedList<PcInitiatedLspRequest> createPcInitiatedLspReqList(Tunnel tunnel, Path path,
626 PcepClient pc, int srpId)
627 throws PcepParseException {
628 PcepValueType tlv;
629 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
630
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700631 if (llSubObjects == null || llSubObjects.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530632 log.error("There is no link information to create tunnel");
633 return null;
634 }
635
636 //build SRP object
637 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false).build();
638
639 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
640 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
641 // set LSP identifiers TLV
642 tlv = new StatefulIPv4LspIdentidiersTlv((((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
643 (short) 0, (short) 0, 0,
644 (((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt()));
645 llOptionalTlv.add(tlv);
646 //set SymbolicPathNameTlv of LSP object
647 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
648 llOptionalTlv.add(tlv);
649
650 //build LSP object
651 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setOFlag((byte) 0).setPlspId(0)
652 .setOptionalTlv(llOptionalTlv).build();
653
654 //build ENDPOINTS object
655 PcepEndPointsObject endpointsobj = pc.factory().buildEndPointsObject()
656 .setSourceIpAddress(((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt())
657 .setDestIpAddress(((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt())
658 .setPFlag(true).build();
659
660 //build ERO object
661 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
662
663 int iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700664 if (tunnel.annotations().value("bandwidth") != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530665 iBandwidth = Integer.parseInt(tunnel.annotations().value("bandwidth"));
666 }
667 // build bandwidth object
668 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
669 // build pcep attribute
670 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
671
672 PcInitiatedLspRequest initiateLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
673 .setLspObject(lspobj).setEndPointsObject(endpointsobj).setEroObject(eroobj)
674 .setPcepAttribute(pcepAttribute).build();
675 llPcInitiatedLspRequestList.add(initiateLspRequest);
676 return llPcInitiatedLspRequestList;
677 }
678
679 /**
680 * To send initiate tunnel message to pcc.
681 *
682 * @param tunnel mpls tunnel info
683 * @param path explicit route for the tunnel
684 * @param pc pcep client to send message
685 */
686 private void pcepSetupTunnel(Tunnel tunnel, Path path, PcepClient pc) {
687 try {
688 int srpId = SrpIdGenerators.create();
689 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, RequestType.CREATE);
690
691 pcepTunnelAPIMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
692
693 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = createPcInitiatedLspReqList(tunnel, path,
694 pc, srpId);
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700695 if (llPcInitiatedLspRequestList == null || llPcInitiatedLspRequestList.size() == 0) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530696 log.error("Failed to create PcInitiatedLspRequestList");
697 return;
698 }
699
700 //build PCInitiate message
701 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
702 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList)
703 .build();
704
705 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
706
707 pcepTunnelAPIMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
708 } catch (PcepParseException e) {
709 log.error("PcepParseException occurred while processing setup tunnel {}", e.getMessage());
710 }
711 }
712
713 /**
714 * To send Release tunnel message to pcc.
715 *
716 * @param tunnel mpls tunnel info
717 * @param pc pcep client to send message
718 */
719 private void pcepReleaseTunnel(Tunnel tunnel, PcepClient pc) {
720 try {
721 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, RequestType.DELETE);
722 pcepTunnelAPIMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
723 int srpId = SrpIdGenerators.create();
724 TunnelId tunnelId = tunnel.tunnelId();
725 int plspId = 0;
726 StatefulIPv4LspIdentidiersTlv statefulIpv4IndentifierTlv = null;
727
728 if (!(pcepTunnelAPIMapper.checkFromTunnelDBQueue(tunnelId))) {
729 log.error("Tunnel doesnot exists. Tunnel id {}" + tunnelId.toString());
730 return;
731 } else {
732 PcepTunnelData pcepTunnelDbData = pcepTunnelAPIMapper.getDataFromTunnelDBQueue(tunnelId);
733 plspId = pcepTunnelDbData.plspId();
734 statefulIpv4IndentifierTlv = pcepTunnelDbData.statefulIpv4IndentifierTlv();
735 }
736 // build srp object
737 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(true).build();
738
739 PcepValueType tlv;
740 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
741 LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
742
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700743 if (statefulIpv4IndentifierTlv != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530744 tlv = statefulIpv4IndentifierTlv;
745 } else {
746 tlv = new StatefulIPv4LspIdentidiersTlv((
747 ((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
748 (short) 0, (short) 0, 0,
749 (((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt()));
750 }
751 llOptionalTlv.add(tlv);
752 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
753 llOptionalTlv.add(tlv);
754 // build lsp object, set r flag as false to delete the tunnel
755 PcepLspObject lspobj = pc.factory().buildLspObject().setRFlag(false).setPlspId(plspId)
756 .setOptionalTlv(llOptionalTlv).build();
757
758 PcInitiatedLspRequest releaseLspRequest = pc.factory().buildPcInitiatedLspRequest().setSrpObject(srpobj)
759 .setLspObject(lspobj).build();
760
761 llPcInitiatedLspRequestList.add(releaseLspRequest);
762
763 PcepInitiateMsg pcInitiateMsg = pc.factory().buildPcepInitiateMsg()
764 .setPcInitiatedLspRequestList(llPcInitiatedLspRequestList).build();
765
766 pc.sendMessage(Collections.singletonList(pcInitiateMsg));
767
768 pcepTunnelAPIMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
769 } catch (PcepParseException e) {
770 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
771 }
772 }
773
774 /**
775 * To send Update tunnel request message to pcc.
776 *
777 * @param tunnel mpls tunnel info
778 * @param path explicit route for the tunnel
779 * @param pc pcep client to send message
780 */
781 private void pcepUpdateTunnel(Tunnel tunnel, Path path, PcepClient pc) {
782 try {
783 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, RequestType.UPDATE);
784 pcepTunnelAPIMapper.addToCoreTunnelRequestQueue(pcepTunnelData);
785 int srpId = SrpIdGenerators.create();
786 TunnelId tunnelId = tunnel.tunnelId();
787 PcepValueType tlv;
788 int plspId = 0;
789
790 LinkedList<PcepValueType> llSubObjects = createPcepPath(path);
791 LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
792 LinkedList<PcepUpdateRequest> llUpdateRequestList = new LinkedList<PcepUpdateRequest>();
793
794 //build SRP object
795 PcepSrpObject srpobj = pc.factory().buildSrpObject().setSrpID(srpId).setRFlag(false).build();
796
797 if (!(pcepTunnelAPIMapper.checkFromTunnelDBQueue(tunnelId))) {
798 log.error("Tunnel doesnot exists in DB");
799 return;
800 } else {
801 PcepTunnelData pcepTunnelDBData = pcepTunnelAPIMapper.getDataFromTunnelDBQueue(tunnelId);
802 plspId = pcepTunnelDBData.plspId();
803 }
804
805 tlv = new StatefulIPv4LspIdentidiersTlv((((IpTunnelEndPoint) tunnel.src()).ip().getIp4Address().toInt()),
806 (short) 0, (short) 0, 0,
807 (((IpTunnelEndPoint) tunnel.dst()).ip().getIp4Address().toInt()));
808 llOptionalTlv.add(tlv);
809
810 if (tunnel.tunnelName().value() != null) {
811 tlv = new SymbolicPathNameTlv(tunnel.tunnelName().value().getBytes());
812 llOptionalTlv.add(tlv);
813 }
814
815 // build lsp object
816 PcepLspObject lspobj = pc.factory().buildLspObject().setAFlag(true).setPlspId(plspId)
817 .setOptionalTlv(llOptionalTlv).build();
818 // build ero object
819 PcepEroObject eroobj = pc.factory().buildEroObject().setSubObjects(llSubObjects).build();
820
821 int iBandwidth = DEFAULT_BANDWIDTH_VALUE;
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700822 if (tunnel.annotations().value("bandwidth") != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530823 iBandwidth = Integer.parseInt(tunnel.annotations().value("bandwidth"));
824 }
825 // build bandwidth object
826 PcepBandwidthObject bandwidthObject = pc.factory().buildBandwidthObject().setBandwidth(iBandwidth).build();
827 // build pcep attribute
828 PcepAttribute pcepAttribute = pc.factory().buildPcepAttribute().setBandwidthObject(bandwidthObject).build();
829 // build pcep msg path
830 PcepMsgPath msgPath = pc.factory().buildPcepMsgPath().setEroObject(eroobj).setPcepAttribute(pcepAttribute)
831 .build();
832
833 PcepUpdateRequest updateRequest = pc.factory().buildPcepUpdateRequest().setSrpObject(srpobj)
834 .setLspObject(lspobj).setMsgPath(msgPath).build();
835
836 llUpdateRequestList.add(updateRequest);
837
838 PcepUpdateMsg pcUpdateMsg = pc.factory().buildUpdateMsg().setUpdateRequestList(llUpdateRequestList).build();
839
840 pc.sendMessage(Collections.singletonList(pcUpdateMsg));
841 pcepTunnelAPIMapper.addToTunnelRequestQueue(srpId, pcepTunnelData);
842 } catch (PcepParseException e) {
843 log.error("PcepParseException occurred while processing release tunnel {}", e.getMessage());
844 }
845 }
846
847 private class InnerTunnelProvider implements PcepTunnelListener, PcepEventListener, PcepClientListener {
cheng fan48e832c2015-05-29 01:54:47 +0800848
849 @Override
850 public void handlePCEPTunnel(PcepTunnel pcepTunnel) {
cheng fan48e832c2015-05-29 01:54:47 +0800851 TunnelDescription tunnel = null;
852 // instance and id identify a tunnel together
853 String tunnelKey = String.valueOf(pcepTunnel.getInstance())
854 + String.valueOf(pcepTunnel.id());
855
856 if (tunnelKey == null || "".equals(tunnelKey)) {
857 log.error("Invalid PCEP tunnel");
858 return;
859 }
860
861 TunnelId tunnelId = getTunnelId(tunnelKey);
862
863 tunnel = buildOpticalTunnel(pcepTunnel, tunnelId);
864
865 OperationType operType = pcepTunnel.getOperationType();
866 switch (operType) {
867 case ADD:
868 tunnelId = service.tunnelAdded(tunnel);
869 tunnelMap.put(tunnelKey, tunnelId);
870 break;
871
872 case UPDATE:
873 service.tunnelUpdated(tunnel);
874 break;
875
876 case DELETE:
877 service.tunnelRemoved(tunnel);
878 tunnelMap.remove(tunnelKey);
879 break;
880
881 default:
882 log.error("Invalid tunnel operation");
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530883 }
884 }
cheng fan48e832c2015-05-29 01:54:47 +0800885
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530886 @Override
887 public void handleMessage(PccId pccId, PcepMessage msg) {
888 try {
889 log.debug("tunnel provider handle message {}", msg.getType().toString());
890 switch (msg.getType()) {
891 case REPORT:
892 int srpId = 0;
893 LinkedList<PcepStateReport> llStateReportList = null;
894 llStateReportList = ((PcepReportMsg) msg).getStateReportList();
895 ListIterator<PcepStateReport> listIterator = llStateReportList.listIterator();
896 PcepSrpObject srpObj = null;
897 PcepLspObject lspObj = null;
898 while (listIterator.hasNext()) {
899 PcepStateReport stateRpt = listIterator.next();
900 srpObj = stateRpt.getSrpObject();
901 lspObj = stateRpt.getLspObject();
902
903 if (srpObj instanceof PcepSrpObject) {
904 srpId = srpObj.getSrpID();
905 }
906
907 log.debug("Plsp ID in handle message " + lspObj.getPlspId());
908 log.debug("SRP ID in handle message " + srpId);
909
910 if (!(pcepTunnelAPIMapper.checkFromTunnelRequestQueue(srpId))) {
911
912 // Check the sync status
913 if (lspObj.getSFlag()) {
914 handleSyncReport(stateRpt);
915 } else if (!pcepClientController.getClient(pccId).isSyncComplete()) {
916 // sync is done
917 pcepClientController.getClient(pccId).setIsSyncComplete(true);
918 }
919 continue;
920 }
921
922 handleReportMessage(srpId, lspObj);
923 }
924 break;
925
926 default:
927 log.debug("Received unsupported message type {}", msg.getType().toString());
928 }
929 } catch (Exception e) {
930 log.error("Exception occured while processing report message {}", e.getMessage());
931 }
932 }
933
934 /**
935 * Handles report message for setup/update/delete tunnel request.
936 *
937 * @param srpId unique identifier for pcep message
938 * @param lspObj lsp object
939 */
940 private void handleReportMessage(int srpId, PcepLspObject lspObj) {
941 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
942 PcepTunnelData pcepTunnelData = pcepTunnelAPIMapper.getDataFromTunnelRequestQueue(srpId);
943 SparseAnnotations annotations = (SparseAnnotations) pcepTunnelData.tunnel().annotations();
944
945 // store the values required from report message
946 pcepTunnelData.setPlspId(lspObj.getPlspId());
947 pcepTunnelData.setLspAFlag(lspObj.getAFlag());
948 pcepTunnelData.setLspOFlag(lspObj.getOFlag());
949 pcepTunnelData.setLspDFlag(lspObj.getDFlag());
950
951 StatefulIPv4LspIdentidiersTlv ipv4LspTlv = null;
952 ListIterator<PcepValueType> listTlvIterator = lspObj.getOptionalTlv().listIterator();
953 while (listTlvIterator.hasNext()) {
954 PcepValueType tlv = listTlvIterator.next();
955 if (tlv.getType() == StatefulIPv4LspIdentidiersTlv.TYPE) {
956 ipv4LspTlv = (StatefulIPv4LspIdentidiersTlv) tlv;
957 break;
958 }
959 }
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700960 if (ipv4LspTlv != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530961 pcepTunnelData.setStatefulIpv4IndentifierTlv(ipv4LspTlv);
cheng fan48e832c2015-05-29 01:54:47 +0800962 }
963
Phanendra Manda37b97fb2015-08-15 02:04:24 +0530964 Path path = pcepTunnelData.path();
965 Tunnel tunnel = pcepTunnelData.tunnel();
966 DefaultTunnelDescription td = new DefaultTunnelDescription(tunnel.tunnelId(), tunnel.src(),
967 tunnel.dst(), tunnel.type(), tunnel.groupId(),
968 providerId, tunnel.tunnelName(), path,
969 annotations);
970
971 if (RequestType.CREATE == pcepTunnelData.requestType()) {
972 log.debug("Report received for create request");
973
974 pcepTunnelAPIMapper.handleCreateTunnelRequestQueue(srpId, pcepTunnelData);
975 if (0 == lspObj.getOFlag()) {
976 log.warn("The tunnel is in down state");
977 }
978 tunnelAdded(td);
979 }
980 if (RequestType.DELETE == pcepTunnelData.requestType()) {
981 log.debug("Report received for delete request");
982 pcepTunnelAPIMapper.handleRemoveFromTunnelRequestQueue(srpId, pcepTunnelData);
983 tunnelRemoved(td);
984 }
985
986 if (RequestType.UPDATE == pcepTunnelData.requestType()) {
987 log.debug("Report received for update request");
988 pcepTunnelData.setRptFlag(true);
989 pcepTunnelAPIMapper.addToTunnelIdMap(pcepTunnelData);
990 pcepTunnelAPIMapper.handleUpdateTunnelRequestQueue(srpId, pcepTunnelData);
991
992 if (0 == lspObj.getOFlag()) {
993 log.warn("The tunnel is in down state");
994 }
995 if (!(pcepTunnelAPIMapper.checkFromTunnelRequestQueue(srpId))) {
996 tunnelUpdated(td);
997 }
998 }
999 }
1000
1001 /**
1002 * Handles sync report received from pcc.
1003 *
1004 * @param stateRpt pcep state report
1005 */
1006 private void handleSyncReport(PcepStateReport stateRpt) {
1007 PcepLspObject lspObj = stateRpt.getLspObject();
1008 PcepStateReport.PcepMsgPath msgPath = stateRpt.getMsgPath();
1009 checkNotNull(msgPath);
1010 PcepRroObject rroObj = msgPath.getRroObject();
Mahesh Poojary S5eab8572015-09-01 17:45:48 +05301011 if (rroObj == null) {
1012 log.debug("RRO object is null in sate report");
1013 return;
1014 }
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301015 int bandwidth = 0;
1016
1017 log.debug("Handle Sync report received from PCC.");
1018
1019 if (0 == lspObj.getOFlag()) {
1020 log.warn("The PCC reported tunnel is in down state");
1021 }
1022 log.debug("Sync report received");
1023
Sho SHIMIZUde09fa02015-09-03 09:39:52 -07001024 if (msgPath.getBandwidthObject() != null) {
Phanendra Manda37b97fb2015-08-15 02:04:24 +05301025 bandwidth = msgPath.getBandwidthObject().getBandwidth();
1026 }
1027
1028 buildAndStorePcepTunnelData(lspObj, rroObj, bandwidth);
1029 }
1030
1031 /**
1032 * To build Path in network from RRO object.
1033 *
1034 * @param rroObj rro object
1035 * @param providerId provider id
1036 * @return path object
1037 */
1038 private Path buildPathFromRroObj(PcepRroObject rroObj, ProviderId providerId) {
1039 checkNotNull(rroObj);
1040 List<Link> links = new ArrayList<Link>();
1041 LinkedList<PcepValueType> llSubObj = rroObj.getSubObjects();
1042 if (0 == llSubObj.size()) {
1043 log.error("RRO in report message does not have hop information");
1044 }
1045 ListIterator<PcepValueType> tlvIterator = llSubObj.listIterator();
1046
1047 ConnectPoint src = null;
1048 ConnectPoint dst = null;
1049 boolean isSrcSet = false;
1050 while (tlvIterator.hasNext()) {
1051 PcepValueType subObj = tlvIterator.next();
1052 switch (subObj.getType()) {
1053
1054 case IPv4SubObject.TYPE:
1055
1056 IPv4SubObject ipv4SubObj = (IPv4SubObject) subObj;
1057 if (!isSrcSet) {
1058 IpAddress srcIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1059 src = new ConnectPoint(IpElementId.ipElement(srcIp), PortNumber.portNumber(0));
1060 isSrcSet = true;
1061 } else {
1062 IpAddress dstIp = IpAddress.valueOf(ipv4SubObj.getIpAddress());
1063 dst = new ConnectPoint(IpElementId.ipElement(dstIp), PortNumber.portNumber(0));
1064 Link link = new DefaultLink(providerId, src, dst, Link.Type.DIRECT, EMPTY);
1065 links.add(link);
1066 src = dst;
1067 }
1068 break;
1069 default:
1070 // the other sub objects are not required
1071 }
1072 }
1073 return new DefaultPath(providerId, links, 0, EMPTY);
1074 }
1075
1076 /**
1077 * To build pcepTunnelData and informs core about the pcc reported tunnel.
1078 *
1079 * @param lspObj pcep lsp object
1080 * @param rroObj pcep rro object
1081 * @param bandwidth bandwidth of tunnel
1082 */
1083 private void buildAndStorePcepTunnelData(PcepLspObject lspObj, PcepRroObject rroObj,
1084 int bandwidth) {
1085
1086 ProviderId providerId = new ProviderId("pcep", PROVIDER_ID);
1087
1088 // StatefulIPv4LspIdentidiersTlv in LSP object will have the source and destination address.
1089 StatefulIPv4LspIdentidiersTlv lspIdenTlv = null;
1090 SymbolicPathNameTlv pathNameTlv = null;
1091 LinkedList<PcepValueType> llOptionalTlv = lspObj.getOptionalTlv();
1092 ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
1093 while (listIterator.hasNext()) {
1094 PcepValueType tlv = listIterator.next();
1095 switch (tlv.getType()) {
1096 case StatefulIPv4LspIdentidiersTlv.TYPE:
1097 lspIdenTlv = (StatefulIPv4LspIdentidiersTlv) tlv;
1098 break;
1099 case SymbolicPathNameTlv.TYPE:
1100 pathNameTlv = (SymbolicPathNameTlv) tlv;
1101 break;
1102 default:
1103 // currently this tlv is not required
1104 }
1105 }
1106
1107 IpTunnelEndPoint tunnelEndPointSrc;
1108 tunnelEndPointSrc = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(lspIdenTlv.getIpv4IngressAddress()));
1109 IpTunnelEndPoint tunnelEndPointDst;
1110 tunnelEndPointDst = IpTunnelEndPoint.ipTunnelPoint(IpAddress.valueOf(lspIdenTlv.getIpv4EgressAddress()));
1111
1112 Path path = buildPathFromRroObj(rroObj, providerId);
1113
1114 SparseAnnotations annotations = DefaultAnnotations.builder()
1115 .set("bandwidth", (new Integer(bandwidth)).toString())
1116 .build();
1117
1118 DefaultTunnelDescription td = new DefaultTunnelDescription(null, tunnelEndPointSrc,
1119 tunnelEndPointDst, Tunnel.Type.MPLS,
1120 new DefaultGroupId(0), providerId,
1121 TunnelName.tunnelName(pathNameTlv.toString()),
1122 path, annotations);
1123 TunnelId tId = tunnelAdded(td);
1124
1125 Tunnel tunnel = new DefaultTunnel(providerId, tunnelEndPointSrc, tunnelEndPointDst, Tunnel.Type.MPLS,
1126 new DefaultGroupId(0), tId,
1127 TunnelName.tunnelName(pathNameTlv.toString()), path, annotations);
1128
1129 PcepTunnelData pcepTunnelData = new PcepTunnelData(tunnel, path, RequestType.LSP_STATE_RPT);
1130 pcepTunnelData.setStatefulIpv4IndentifierTlv(lspIdenTlv);
1131 pcepTunnelAPIMapper.addPccTunnelDB(pcepTunnelData);
1132 pcepTunnelAPIMapper.addToTunnelIdMap(pcepTunnelData);
1133 }
1134
1135 @Override
1136 public void clientConnected(PccId pccId) {
1137 // TODO
1138 }
1139
1140 @Override
1141 public void clientDisconnected(PccId pccId) {
1142 // TODO
cheng fan48e832c2015-05-29 01:54:47 +08001143 }
1144 }
1145
1146 @Override
1147 public Tunnel tunnelQueryById(TunnelId tunnelId) {
1148 return service.tunnelQueryById(tunnelId);
1149 }
cheng fan48e832c2015-05-29 01:54:47 +08001150}