2 * Copyright (c) 2020 Orange. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.bgpcep.pcep.server.provider;
11 import com.google.common.collect.Lists;
12 import java.nio.ByteBuffer;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.path.descriptions.PathDescription;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcerrBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcrep;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcrepBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.SidType;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.pcrep.pcrep.message.replies.result.success._case.success.paths.ero.subobject.subobject.type.SrEroType;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.pcrep.pcrep.message.replies.result.success._case.success.paths.ero.subobject.subobject.type.SrEroTypeBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpNodeIdBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.NoPathVectorTlv.Flags;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.RequestId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.BandwidthBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassTypeBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.Subobject;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.SubobjectBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.MetricBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObjectBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.PcerrMessageBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.ErrorsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.RequestCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.RequestBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.request.RpsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessageBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.RepliesBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.NoPathBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.no.path.TlvsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.no.path.tlvs.NoPathVectorBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.success.Paths;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.success.PathsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2p;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.Rp;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.RpBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefix;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
69 import org.opendaylight.yangtools.yang.common.Uint32;
70 import org.opendaylight.yangtools.yang.common.Uint8;
72 public final class MessagesUtil {
74 public static final byte NO_PATH = 0x0;
75 public static final byte UNKNOWN_SOURCE = 0x1;
76 public static final byte UNKNOWN_DESTINATION = 0x0;
80 * https://www.iana.org/assignments/pcep/pcep.xhtml#metric-object-ni-field
82 public static final int IGP_METRIC = 1;
83 public static final int TE_METRIC = 2;
84 public static final int PATH_DELAY = 12;
86 private MessagesUtil() {
87 throw new UnsupportedOperationException();
90 public static Ero getEro(List<PathDescription> pathDescriptions) {
92 final EroBuilder eroBuilder = new EroBuilder();
93 eroBuilder.setIgnore(false);
94 eroBuilder.setProcessingRule(true);
95 final List<Subobject> eroSubs = new ArrayList<>();
97 /* Fulfill ERO sublist */
98 for (PathDescription path : pathDescriptions) {
100 if (path.getLabel() == null) {
101 IpPrefix ipPref = null;
102 /* Prepare SubObject for IPv4 or IPv6 address */
103 if (path.getIpv4() != null) {
104 final Ipv4Prefix ipv4Pref = new Ipv4Prefix(path.getIpv4().getValue() + "/32");
105 ipPref = new IpPrefixBuilder().setIpPrefix(
106 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715
110 if (path.getIpv6() != null) {
111 final Ipv6Prefix ipv6Pref = new Ipv6Prefix(path.getIpv6().getValue() + "/128");
112 ipPref = new IpPrefixBuilder().setIpPrefix(
113 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715
117 if (ipPref != null) {
118 final IpPrefixCase ipPrefCase = new IpPrefixCaseBuilder().setIpPrefix(ipPref).build();
119 sb = new SubobjectBuilder().setSubobjectType(ipPrefCase).setLoose(false).build();
122 /* Prepare SubObject for Segment Routing */
123 SrEroType srEro = null;
124 if (path.getIpv4() != null) {
125 srEro = new SrEroTypeBuilder()
126 .setSidType(SidType.Ipv4NodeId)
127 .setSid(path.getLabel().getValue())
130 .setNai(new IpNodeIdBuilder()
131 .setIpAddress(new IpAddressNoZone(new Ipv4AddressNoZone(path.getIpv4().getValue())))
135 if (path.getIpv6() != null) {
136 srEro = new SrEroTypeBuilder()
137 .setSidType(SidType.Ipv6NodeId)
138 .setSid(path.getLabel().getValue())
141 .setNai(new IpNodeIdBuilder()
142 .setIpAddress(new IpAddressNoZone(new Ipv6AddressNoZone(path.getIpv6().getValue())))
147 sb = new SubobjectBuilder().setSubobjectType(srEro).setLoose(false).build();
151 /* Add corresponding SubObject to the ERO List */
156 /* Set ERO sublist */
157 eroBuilder.setSubobject(eroSubs);
159 return eroBuilder.build();
162 private static PathsBuilder buildPath(ConstrainedPath cpath) {
163 final PathsBuilder pathBuilder = new PathsBuilder();
165 /* Get ERO from Path Description */
166 pathBuilder.setEro(getEro(cpath.getPathDescription()));
168 /* Fulfill Computed Metrics if available */
169 final ArrayList<Metrics> metrics = new ArrayList<Metrics>();
170 if (cpath.getMetric() != null) {
171 final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
172 .setMetricType(Uint8.valueOf(IGP_METRIC)).setValue(new Float32(
173 ByteBuffer.allocate(4).putFloat(Float.valueOf(cpath.getMetric().floatValue())).array()));
174 metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
176 if (cpath.getTeMetric() != null) {
177 final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
178 .setMetricType(Uint8.valueOf(TE_METRIC)).setValue(new Float32(
179 ByteBuffer.allocate(4).putFloat(Float.valueOf(cpath.getTeMetric().floatValue())).array()));
180 metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
182 if (cpath.getDelay() != null) {
183 final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
184 .setMetricType(Uint8.valueOf(PATH_DELAY)).setValue(new Float32(ByteBuffer.allocate(4)
185 .putFloat(Float.valueOf(cpath.getDelay().getValue().floatValue())).array()));
186 metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
188 if (!metrics.isEmpty()) {
189 pathBuilder.setMetrics(metrics);
191 /* Fulfill Bandwidth and ClassType if set */
192 if (cpath.getBandwidth() != null) {
193 final BandwidthBuilder bwBuilder = new BandwidthBuilder();
194 bwBuilder.setBandwidth(new Bandwidth(new Float32(ByteBuffer.allocate(4)
195 .putFloat(Float.valueOf(cpath.getBandwidth().getValue().floatValue())).array())));
196 pathBuilder.setBandwidth(bwBuilder.build());
197 if (cpath.getClassType() != null) {
198 pathBuilder.setClassType(new ClassTypeBuilder().setClassType(
199 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109
200 .ClassType(cpath.getClassType()))
207 public static Pcrep createPcRepMessage(Rp rp, P2p p2p, ConstrainedPath cpath) {
209 /* Prepare Path Object with ERO and Object from the Request */
210 final ArrayList<Paths> paths = new ArrayList<Paths>();
211 PathsBuilder pathBuilder = buildPath(cpath);
213 if (p2p.getLspa() != null) {
214 pathBuilder.setLspa(p2p.getLspa());
216 if (p2p.getIro() != null) {
217 pathBuilder.setIro(p2p.getIro());
219 if (p2p.getXro() != null) {
220 pathBuilder.setXro(p2p.getXro());
222 paths.add(pathBuilder.build());
224 /* Prepare Reply with Path Object */
225 final RepliesBuilder replyBuilder = new RepliesBuilder()
227 .setResult(new SuccessCaseBuilder().setSuccess(new SuccessBuilder().setPaths(paths).build()).build());
229 /* Prepare PcRep Message */
230 final PcrepMessageBuilder msgBuilder = new PcrepMessageBuilder()
231 .setReplies(Lists.newArrayList(replyBuilder.build()));
232 return new PcrepBuilder().setPcrepMessage(msgBuilder.build()).build();
235 public static Pcrep createNoPathMessage(Rp rp, byte reason) {
237 /* Prepare NoPath Object */
238 final Flags flags = new Flags(false, false, false, false, false, false,
239 (reason == UNKNOWN_DESTINATION) ? true : false, (reason == UNKNOWN_SOURCE) ? true : false);
240 final NoPathVectorBuilder npvBuilder = new NoPathVectorBuilder().setFlags(flags);
241 final TlvsBuilder tlvsBuilder = new TlvsBuilder().setNoPathVector(npvBuilder.build());
242 final NoPathBuilder npBuilder = new NoPathBuilder()
243 .setProcessingRule(false)
245 .setNatureOfIssue(Uint8.ZERO)
246 .setUnsatisfiedConstraints(true)
247 .setTlvs(tlvsBuilder.build());
250 final RepliesBuilder replyBuilder = new RepliesBuilder()
252 .setResult(new FailureCaseBuilder().setNoPath(npBuilder.build()).build());
254 /* Prepare PcRep Message */
255 final PcrepMessageBuilder msgBuilder = new PcrepMessageBuilder()
256 .setReplies(Lists.newArrayList(replyBuilder.build()));
257 return new PcrepBuilder().setPcrepMessage(msgBuilder.build()).build();
260 public static Pcerr createErrorMsg(@NonNull final PCEPErrors pcepErrors, final Uint32 reqID) {
261 final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
262 return new PcerrBuilder().setPcerrMessage(msgBuilder
264 new RequestCaseBuilder().setRequest(new RequestBuilder()
266 .newArrayList(new RpsBuilder().setRp(new RpBuilder().setProcessingRule(false)
267 .setIgnore(false).setRequestId(new RequestId(reqID)).build()).build()))
269 .setErrors(Collections.singletonList(new ErrorsBuilder().setErrorObject(new ErrorObjectBuilder()
270 .setType(pcepErrors.getErrorType()).setValue(pcepErrors.getErrorValue()).build()).build()))