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
8 package org.opendaylight.bgpcep.pcep.server.provider;
10 import com.google.common.collect.Lists;
11 import java.nio.ByteBuffer;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.path.descriptions.PathDescription;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcerrBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcrep;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcrepBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.NaiType;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.pcrep.pcrep.message.replies.result.success._case.success.paths.ero.subobject.subobject.type.SrEroType;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.pcrep.pcrep.message.replies.result.success._case.success.paths.ero.subobject.subobject.type.SrEroTypeBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev200720.sr.subobject.nai.IpAdjacencyBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.NoPathVectorTlv.Flags;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.RequestId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.BandwidthBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassTypeBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.Subobject;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.SubobjectBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.MetricBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObjectBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.PcerrMessageBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.ErrorsBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.RequestCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.RequestBuilder;
50 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;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessageBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.RepliesBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.NoPathBuilder;
56 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;
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.tlvs.NoPathVectorBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
59 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;
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.PathsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2p;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.Rp;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.RpBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefix;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
68 import org.opendaylight.yangtools.yang.common.Uint32;
69 import org.opendaylight.yangtools.yang.common.Uint8;
71 public final class MessagesUtil {
73 public static final byte NO_PATH = 0x0;
74 public static final byte UNKNOWN_SOURCE = 0x1;
75 public static final byte UNKNOWN_DESTINATION = 0x0;
79 * https://www.iana.org/assignments/pcep/pcep.xhtml#metric-object-ni-field
81 public static final int IGP_METRIC = 1;
82 public static final int TE_METRIC = 2;
83 public static final int PATH_DELAY = 12;
85 private MessagesUtil() {
89 public static Ero getEro(final List<PathDescription> pathDescriptions) {
91 final EroBuilder eroBuilder = new EroBuilder()
93 .setProcessingRule(true);
94 final List<Subobject> eroSubs = new ArrayList<>();
96 /* Fulfill ERO sublist */
97 for (PathDescription path : pathDescriptions) {
99 if (path.getSid() == null) {
100 IpPrefix ipPref = null;
101 /* Prepare SubObject for IPv4 or IPv6 address */
102 if (path.getIpv4() != null) {
103 final Ipv4Prefix ipv4Pref = new Ipv4Prefix(path.getIpv4().getValue() + "/32");
104 ipPref = new IpPrefixBuilder().setIpPrefix(
105 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715
109 if (path.getIpv6() != null) {
110 final Ipv6Prefix ipv6Pref = new Ipv6Prefix(path.getIpv6().getValue() + "/128");
111 ipPref = new IpPrefixBuilder().setIpPrefix(
112 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715
116 if (ipPref != null) {
117 final IpPrefixCase ipPrefCase = new IpPrefixCaseBuilder().setIpPrefix(ipPref).build();
118 sb = new SubobjectBuilder().setSubobjectType(ipPrefCase).setLoose(false).build();
121 /* Prepare SubObject for Segment Routing */
122 SrEroType srEro = null;
123 if (path.getLocalIpv4() != null && path.getRemoteIpv4() != null) {
124 srEro = new SrEroTypeBuilder()
125 .setNaiType(NaiType.Ipv4Adjacency)
126 .setSid(path.getSid())
129 .setNai(new IpAdjacencyBuilder()
131 new IpAddressNoZone(new Ipv4AddressNoZone(path.getLocalIpv4().getValue())))
133 new IpAddressNoZone(new Ipv4AddressNoZone(path.getRemoteIpv4().getValue())))
137 if (path.getLocalIpv6() != null && path.getRemoteIpv6() != null) {
138 srEro = new SrEroTypeBuilder()
139 .setNaiType(NaiType.Ipv6Adjacency)
140 .setSid(path.getSid())
143 .setNai(new IpAdjacencyBuilder()
145 new IpAddressNoZone(new Ipv6AddressNoZone(path.getLocalIpv6().getValue())))
147 new IpAddressNoZone(new Ipv6AddressNoZone(path.getRemoteIpv6().getValue())))
152 sb = new SubobjectBuilder().setSubobjectType(srEro).setLoose(false).build();
156 /* Add corresponding SubObject to the ERO List */
161 /* Set ERO sublist */
162 eroBuilder.setSubobject(eroSubs);
164 return eroBuilder.build();
167 private static PathsBuilder buildPath(final ConstrainedPath cpath) {
168 final PathsBuilder pathBuilder = new PathsBuilder();
170 /* Get ERO from Path Description */
171 pathBuilder.setEro(getEro(cpath.getPathDescription()));
173 /* Fulfill Computed Metrics if available */
174 final ArrayList<Metrics> metrics = new ArrayList<>();
175 if (cpath.getMetric() != null) {
176 final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
177 .setMetricType(Uint8.valueOf(IGP_METRIC)).setValue(new Float32(
178 ByteBuffer.allocate(4).putFloat(cpath.getMetric().floatValue()).array()));
179 metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
181 if (cpath.getTeMetric() != null) {
182 final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
183 .setMetricType(Uint8.valueOf(TE_METRIC)).setValue(new Float32(
184 ByteBuffer.allocate(4).putFloat(cpath.getTeMetric().floatValue()).array()));
185 metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
187 if (cpath.getDelay() != null) {
188 final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
189 .setMetricType(Uint8.valueOf(PATH_DELAY)).setValue(new Float32(ByteBuffer.allocate(4)
190 .putFloat(cpath.getDelay().getValue().floatValue()).array()));
191 metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
193 if (!metrics.isEmpty()) {
194 pathBuilder.setMetrics(metrics);
196 /* Fulfill Bandwidth and ClassType if set */
197 if (cpath.getBandwidth() != null) {
198 final BandwidthBuilder bwBuilder = new BandwidthBuilder();
199 bwBuilder.setBandwidth(new Bandwidth(new Float32(ByteBuffer.allocate(4)
200 .putFloat(cpath.getBandwidth().getValue().floatValue()).array())));
201 pathBuilder.setBandwidth(bwBuilder.build());
202 if (cpath.getClassType() != null) {
203 pathBuilder.setClassType(new ClassTypeBuilder().setClassType(
204 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109
205 .ClassType(cpath.getClassType()))
212 public static Pcrep createPcRepMessage(final Rp rp, final P2p p2p, final ConstrainedPath cpath) {
214 /* Prepare Path Object with ERO and Object from the Request */
215 final ArrayList<Paths> paths = new ArrayList<>();
216 PathsBuilder pathBuilder = buildPath(cpath);
218 if (p2p.getLspa() != null) {
219 pathBuilder.setLspa(p2p.getLspa());
221 if (p2p.getIro() != null) {
222 pathBuilder.setIro(p2p.getIro());
224 if (p2p.getXro() != null) {
225 pathBuilder.setXro(p2p.getXro());
227 paths.add(pathBuilder.build());
229 /* Prepare Reply with Path Object */
230 final RepliesBuilder replyBuilder = new RepliesBuilder()
232 .setResult(new SuccessCaseBuilder().setSuccess(new SuccessBuilder().setPaths(paths).build()).build());
234 /* Prepare PcRep Message */
235 final PcrepMessageBuilder msgBuilder = new PcrepMessageBuilder()
236 .setReplies(Lists.newArrayList(replyBuilder.build()));
237 return new PcrepBuilder().setPcrepMessage(msgBuilder.build()).build();
240 public static Pcrep createNoPathMessage(final Rp rp, final byte reason) {
242 /* Prepare NoPath Object */
243 final Flags flags = new Flags(false, false, false, false, false, false,
244 reason == UNKNOWN_DESTINATION, reason == UNKNOWN_SOURCE);
245 final NoPathVectorBuilder npvBuilder = new NoPathVectorBuilder().setFlags(flags);
246 final TlvsBuilder tlvsBuilder = new TlvsBuilder().setNoPathVector(npvBuilder.build());
247 final NoPathBuilder npBuilder = new NoPathBuilder()
248 .setProcessingRule(false)
250 .setNatureOfIssue(Uint8.ZERO)
251 .setUnsatisfiedConstraints(true)
252 .setTlvs(tlvsBuilder.build());
255 final RepliesBuilder replyBuilder = new RepliesBuilder()
257 .setResult(new FailureCaseBuilder().setNoPath(npBuilder.build()).build());
259 /* Prepare PcRep Message */
260 final PcrepMessageBuilder msgBuilder = new PcrepMessageBuilder()
261 .setReplies(Lists.newArrayList(replyBuilder.build()));
262 return new PcrepBuilder().setPcrepMessage(msgBuilder.build()).build();
265 public static Pcerr createErrorMsg(@NonNull final PCEPErrors pcepErrors, final Uint32 reqID) {
266 final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
267 return new PcerrBuilder().setPcerrMessage(msgBuilder
269 new RequestCaseBuilder().setRequest(new RequestBuilder()
271 .newArrayList(new RpsBuilder().setRp(new RpBuilder().setProcessingRule(false)
272 .setIgnore(false).setRequestId(new RequestId(reqID)).build()).build()))
274 .setErrors(Collections.singletonList(new ErrorsBuilder().setErrorObject(new ErrorObjectBuilder()
275 .setType(pcepErrors.getErrorType()).setValue(pcepErrors.getErrorValue()).build()).build()))