From: Dana Kutenicsova Date: Sat, 9 Nov 2013 15:46:11 +0000 (+0000) Subject: Merge "Add model of graceful-restart capability" X-Git-Tag: jenkins-bgpcep-bulk-release-prepare-only-1~237^2~58 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=aeb469f0217a1fbd08cad4d9b114fdd04b368862;hp=29d3fd29b11310987bef506fdb3dac2e40d05d7d;p=bgpcep.git Merge "Add model of graceful-restart capability" --- diff --git a/concepts/src/test/java/org/opendaylight/protocol/concepts/BandwidthTest.java b/concepts/src/test/java/org/opendaylight/protocol/concepts/BandwidthTest.java index dfa552b126..6fced21e9d 100644 --- a/concepts/src/test/java/org/opendaylight/protocol/concepts/BandwidthTest.java +++ b/concepts/src/test/java/org/opendaylight/protocol/concepts/BandwidthTest.java @@ -18,7 +18,6 @@ import java.util.HashSet; import java.util.Set; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.opendaylight.protocol.util.ByteArray; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Bandwidth; diff --git a/pcep/api/src/main/yang/pcep-types.yang b/pcep/api/src/main/yang/pcep-types.yang index 6326985a4f..43112e3da3 100644 --- a/pcep/api/src/main/yang/pcep-types.yang +++ b/pcep/api/src/main/yang/pcep-types.yang @@ -662,23 +662,7 @@ module pcep-types { container lspa { uses object; - - leaf hold-priority { - type uint8; - mandatory true; - } - - leaf setup-priority { - type uint8; - mandatory true; - } - - leaf local-protection-desired { - type boolean; - default false; - } - - uses rsvp:attribute-filters; + uses rsvp:tunnel-attributes; } } diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java index 7a51170d8e..9e38ec9a8c 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java @@ -7,7 +7,6 @@ */ package org.opendaylight.bgpcep.pcep.topology.provider; -import com.google.common.base.Preconditions; import io.netty.channel.ChannelFuture; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; @@ -30,8 +29,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.net.InetSocketAddress; -import java.util.concurrent.ExecutionException; +import com.google.common.base.Preconditions; public final class BundleActivator extends AbstractBindingAwareProvider { private static final Logger LOG = LoggerFactory.getLogger(BundleActivator.class); @@ -46,7 +44,7 @@ public final class BundleActivator extends AbstractBindingAwareProvider { final Open prefs = spf.getSessionProposal(address, 0); final PCEPDispatcher dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl .getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory( - new HashedWheelTimer(), prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup()); + new HashedWheelTimer(), prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup()); final InstanceIdentifier topology = InstanceIdentifier.builder().node(Topology.class).toInstance(); diff --git a/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang b/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang index eb2de0203a..67b6c24837 100644 --- a/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang +++ b/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang @@ -6,6 +6,7 @@ module topology-tunnel-pcep-programming { import pcep-types { prefix pcep; revision-date 2013-10-05; } import topology-tunnel-programming { prefix ttp; revision-date 2013-09-30; } import topology-tunnel-p2p { prefix p2p; revision-date 2013-08-19; } + import topology-tunnel-pcep { prefix ptp; } organization "Cisco Systems, Inc."; contact "Robert Varga "; @@ -32,6 +33,7 @@ module topology-tunnel-pcep-programming { uses ttp:create-p2p-tunnel-input; uses p2p:tunnel-p2p-path-cfg-attributes; + uses ptp:tunnel-pcep-link-cfg-attributes; } output { uses ttp:create-p2p-tunnel-output; @@ -52,6 +54,7 @@ module topology-tunnel-pcep-programming { uses ttp:base-tunnel-input; uses p2p:tunnel-p2p-path-cfg-attributes; + uses ptp:tunnel-pcep-link-cfg-attributes; } output { diff --git a/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang b/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang index e17563e6e7..4e2f54cd81 100644 --- a/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang +++ b/pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang @@ -4,8 +4,8 @@ module topology-tunnel-pcep { namespace "urn:opendaylight:params:xml:ns:yang:topology:tunnel:pcep"; prefix "pceptun"; - import ieee754 { prefix ieee754; revision-date 2013-08-19; } import network-topology { prefix nt; revision-date 2013-10-21; } + import nps-concepts { prefix nps-c; } import pcep-types { prefix pcep; revision-date 2013-10-05; } import rsvp { prefix rsvp; revision-date 2013-08-20; } import topology-tunnel { prefix tt; revision-date 2013-08-19; } @@ -34,6 +34,31 @@ module topology-tunnel-pcep { reference "https://tools.ietf.org/html/draft-ietf-pce-stateful-pce-05#section-7.3"; } + grouping topology-tunnel-pcep-type { + container topology-tunnel-pcep { + presence "indicates a PCEP tunnel-aware topology"; + } + } + + augment "/nt:network-topology/nt:topology/nt:topology-types" { + uses topology-tunnel-pcep-type; + } + + grouping tunnel-pcep-supporting-node-attributes { + container path-computation-client { + leaf controlling { + type boolean; + default false; + } + } + } + + augment "/nt:network-topology/nt:topology/nt:node/nt:supporting-node" { + when "../../../nt:topology-types/topology-tunnel-pcep"; + + uses tunnel-pcep-supporting-node-attributes; + } + grouping tunnel-pcep-type { container pcep-tunnel { presence "indicates a link is a PCEP tunnel"; @@ -44,22 +69,30 @@ module topology-tunnel-pcep { uses tunnel-pcep-type; } - grouping tunnel-pcep-link-attributes { + grouping tunnel-pcep-link-cfg-attributes { leaf administrative-status { type administrative-status; } - leaf operational-status { - type pcep:operational-status; - config false; - } - leaf class-type { type pcep:class-type; } leaf bandwidth { - type ieee754:float32; + type nps-c:bandwidth; + } + + leaf symbolic-path-name { + type pcep:symbolic-path-name; + } + + uses rsvp:tunnel-attributes; + } + + grouping tunnel-pcep-link-oper-attributes { + leaf operational-status { + type pcep:operational-status; + config false; } } @@ -76,7 +109,8 @@ module topology-tunnel-pcep { augment "/nt:network-topology/nt:topology/nt:link" { when "../../tunnel-types/pcep-tunnel"; - uses tunnel-pcep-link-attributes; + uses tunnel-pcep-link-cfg-attributes; + uses tunnel-pcep-link-oper-attributes; } augment "/nt:network-topology/nt:topology/tt:paths" { diff --git a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java index 754925de33..8bea183e83 100644 --- a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java +++ b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java @@ -22,6 +22,6 @@ public final class BundleActivator extends AbstractBindingAwareProvider { tte.addTargetTopology(null); final InstructionScheduler scheduler = null; - final TunnelProgramming tp = new TunnelProgramming(scheduler, session.getRpcService(NetworkTopologyPcepService.class)); + final TunnelProgramming tp = new TunnelProgramming(scheduler, dps, session.getRpcService(NetworkTopologyPcepService.class)); } } diff --git a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java index a81fcb0b4a..8d939a2828 100644 --- a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java +++ b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java @@ -16,8 +16,13 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.SymbolicPathName; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLsps; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -77,4 +82,10 @@ final class NodeChangedListener implements DataChangeListener { LOG.error("Failed to propagate a topology change, target topology became inconsistent", e); } } -} \ No newline at end of file + + public static InstanceIdentifier linkIdentifier(final InstanceIdentifier topology, + final NodeId node, final SymbolicPathName name) { + return InstanceIdentifier.builder(topology). + node(Link.class, new LinkKey(new LinkId(node.getValue() + "/lsp/" + name))).toInstance(); + } +} diff --git a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java index 963d91ff3e..0bea03fda3 100644 --- a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java +++ b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java @@ -8,10 +8,27 @@ package org.opendaylight.bgpcep.pcep.tunnel.provider; +import java.util.ArrayList; +import java.util.List; + import org.opendaylight.bgpcep.pcep.topology.spi.AbstractTopologyProgrammingExecutor; import org.opendaylight.bgpcep.programming.spi.InstructionExecutor; import org.opendaylight.bgpcep.programming.spi.InstructionScheduler; import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.BandwidthBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.classtype.object.ClassTypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.EndpointsObjBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobjects; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.LspaBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.FailureBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.failure.Failure; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspInputBuilder; @@ -22,6 +39,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.add.lsp.args.ArgumentsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.programming.rev131102.TopologyInstructionInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.p2p.rev130819.tunnel.p2p.path.cfg.attributes.ExplicitHops; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutputBuilder; @@ -32,7 +52,30 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.AdministrativeStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.ExplicitHops1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.Link1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.SupportingNode1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.BaseTunnelInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.TpReference; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNode; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.TerminationPoint1; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.TerminationPointType; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.termination.point.type.Ip; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Preconditions; @@ -40,35 +83,179 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; final class TunnelProgramming implements TopologyTunnelPcepProgrammingService { - private final NetworkTopologyPcepService pcepTopology; + private static final Logger LOG = LoggerFactory.getLogger(TunnelProgramming.class); + private final NetworkTopologyPcepService topologyService; + private final DataProviderService dataProvider; private final InstructionScheduler scheduler; - TunnelProgramming(final InstructionScheduler scheduler, final NetworkTopologyPcepService pcepTopology) { + TunnelProgramming(final InstructionScheduler scheduler, final DataProviderService dataProvider, + final NetworkTopologyPcepService topologyService) { this.scheduler = Preconditions.checkNotNull(scheduler); - this.pcepTopology = Preconditions.checkNotNull(pcepTopology); + this.dataProvider = Preconditions.checkNotNull(dataProvider); + this.topologyService = Preconditions.checkNotNull(topologyService); } - @Override - public ListenableFuture> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput input) { - Preconditions.checkNotNull(input.getLinkId()); - Preconditions.checkNotNull(input.getSourceTp()); - Preconditions.checkNotNull(input.getDestinationTp()); + private static final class TpReader { + private final DataModificationTransaction t; + private final InstanceIdentifier nii; + private final InstanceIdentifier tii; + + TpReader(final DataModificationTransaction t, final InstanceIdentifier topo, final TpReference ref) { + this.t = Preconditions.checkNotNull(t); + + nii = InstanceIdentifier.builder(topo).node(Node.class, new NodeKey(ref.getNode())).toInstance(); + tii = InstanceIdentifier.builder(nii).node(TerminationPoint.class, new TerminationPointKey(ref.getTp())).toInstance(); + } + + private Node getNode() { + return (Node) t.readOperationalData(nii); + } + + private TerminationPoint getTp() { + return (TerminationPoint) t.readOperationalData(tii); + } + } + + private AddressFamily buildAddressFamily(final TerminationPoint sp, final TerminationPoint dp) { + // We need the IGP augmentation -- it has IP addresses + final TerminationPoint1 sp1 = Preconditions.checkNotNull(sp.getAugmentation(TerminationPoint1.class)); + final TerminationPoint1 dp1 = Preconditions.checkNotNull(dp.getAugmentation(TerminationPoint1.class)); + + // Get the types + final TerminationPointType spt = sp1.getIgpTerminationPointAttributes().getTerminationPointType(); + final TerminationPointType dpt = dp1.getIgpTerminationPointAttributes().getTerminationPointType(); + + // The types have to match + Preconditions.checkArgument(spt.getImplementedInterface().equals(dpt.getImplementedInterface())); + + // And they have to actually be Ip + final Ip sips = (Ip) spt; + final Ip dips = (Ip) dpt; + + /* + * Now a bit of magic. We need to find 'like' addresses, e.g. both + * IPv4 or both IPv6. We are in IPv6-enabled world now, so let's + * prefer that. + */ + AddressFamily ret = findIpv6(sips.getIpAddress(), dips.getIpAddress()); + if (ret == null) { + ret = findIpv4(sips.getIpAddress(), dips.getIpAddress()); + } + + // We need to have a ret now + Preconditions.checkArgument(ret != null, "Failed to find like Endpoint addresses"); + + return ret; + } + + private AddressFamily findIpv4(final List srcs, final List dsts) { + for (final IpAddress sc : srcs) { + if (sc.getIpv4Address() != null) { + for (final IpAddress dc : dsts) { + if (dc.getIpv4Address() != null) { + return new Ipv4Builder(). + setSourceIpv4Address(sc.getIpv4Address()). + setDestinationIpv4Address(dc.getIpv4Address()).build(); + } + } + } + } + + return null; + } + + private AddressFamily findIpv6(final List srcs, final List dsts) { + for (final IpAddress sc : srcs) { + if (sc.getIpv6Address() != null) { + for (final IpAddress dc : dsts) { + if (dc.getIpv6Address() != null) { + return new Ipv6Builder(). + setSourceIpv6Address(sc.getIpv6Address()). + setDestinationIpv6Address(dc.getIpv6Address()).build(); + } + } + } + } + + return null; + } + + private NodeId supportingNode(final DataModificationTransaction t, final Node node) { + for (SupportingNode n : node.getSupportingNode()) { + final SupportingNode1 n1 = n.getAugmentation(SupportingNode1.class); + if (n1 != null && n1.getPathComputationClient().isControlling()) { + return n.getKey().getNodeRef(); + } + } + + return null; + } + + private Ero buildEro(final List explicitHops) { + final EroBuilder b = new EroBuilder(); - final AddLspInputBuilder ab = new AddLspInputBuilder(); - ab.fieldsFrom(input); + if (!explicitHops.isEmpty()) { + final List subobjs = new ArrayList<>(explicitHops.size()); + for (ExplicitHops h : explicitHops) { + final ExplicitHops1 h1 = h.getAugmentation(ExplicitHops1.class); + if (h1 != null) { + final SubobjectsBuilder sb = new SubobjectsBuilder(); + sb.fieldsFrom(h1); + sb.setLoose(h.isLoose()); + subobjs.add(sb.build()); + } else { + LOG.debug("Ignoring unhandled explicit hop {}", h); + } + } + b.setSubobjects(subobjs); + } + return b.build(); + } + + @Override + public ListenableFuture> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput input) { final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() { @Override protected ListenableFuture executeImpl() { - final ListenableFuture> s = - (ListenableFuture>) pcepTopology.addLsp(ab.build()); + final InstanceIdentifier tii = topologyIdentifier(input); - return Futures.transform(s, new Function, OperationResult>() { - @Override - public OperationResult apply(final RpcResult input) { - return input.getResult(); - } - }); + final DataModificationTransaction t = dataProvider.beginTransaction(); + + + final TpReader dr = new TpReader(t, tii, input.getDestination()); + final TpReader sr = new TpReader(t, tii, input.getSource()); + + final Node sn = Preconditions.checkNotNull(sr.getNode()); + final TerminationPoint sp = Preconditions.checkNotNull(sr.getTp()); + final TerminationPoint dp = Preconditions.checkNotNull(dr.getTp()); + + final AddLspInputBuilder ab = new AddLspInputBuilder(); + ab.setNode(Preconditions.checkNotNull(supportingNode(t, sn))); + ab.setName(Preconditions.checkNotNull(input.getSymbolicPathName())); + + // The link has to be non-existent + final InstanceIdentifier lii = NodeChangedListener.linkIdentifier(tii, ab.getNode(), ab.getName()); + Preconditions.checkState(t.readOperationalData(lii) == null); + + final ArgumentsBuilder args = new ArgumentsBuilder(); + args.setAdministrative(input.getAdministrativeStatus() == AdministrativeStatus.Active); + args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build()); + args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build()); + args.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(buildAddressFamily(sp, dp)).build()); + args.setEro(buildEro(input.getExplicitHops())); + args.setLspa(new LspaBuilder(input).build()); + + ab.setArguments(args.build()); + + return Futures.transform( + (ListenableFuture>) topologyService.addLsp(ab.build()), + new Function, OperationResult>() { + @Override + public OperationResult apply(final RpcResult input) { + return input.getResult(); + } + }); } }; @@ -82,25 +269,54 @@ final class TunnelProgramming implements TopologyTunnelPcepProgrammingService { return Futures.immediateFuture(res); } - @Override - public ListenableFuture> pcepDestroyTunnel(final PcepDestroyTunnelInput input) { - Preconditions.checkNotNull(input.getLinkId()); + // FIXME: topology programming utility class + private InstanceIdentifier topologyIdentifier(final TopologyInstructionInput input) { + return InstanceIdentifier.builder(). + node(NetworkTopology.class).node(Topology.class, new TopologyKey(input.getTopologyId())).toInstance(); + } + + // FIXME: tunnel programming utility class + private InstanceIdentifier linkIdentifier(final InstanceIdentifier topology, final BaseTunnelInput input) { + return InstanceIdentifier.builder(topology). + node(Link.class, new LinkKey(Preconditions.checkNotNull(input.getLinkId()))).toInstance(); + } - final RemoveLspInputBuilder ab = new RemoveLspInputBuilder(); - ab.fieldsFrom(input); + private Node sourceNode(final DataModificationTransaction t, final InstanceIdentifier topology, final Link link) { + final InstanceIdentifier nii = InstanceIdentifier.builder(topology). + node(Node.class, new NodeKey(link.getSource().getSourceNode())).toInstance(); + return (Node) t.readOperationalData(nii); + } + @Override + public ListenableFuture> pcepDestroyTunnel(final PcepDestroyTunnelInput input) { final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() { @Override protected ListenableFuture executeImpl() { - final ListenableFuture> s = - (ListenableFuture>) pcepTopology.removeLsp(ab.build()); + final InstanceIdentifier tii = topologyIdentifier(input); + final InstanceIdentifier lii = linkIdentifier(tii, input); - return Futures.transform(s, new Function, OperationResult>() { - @Override - public OperationResult apply(final RpcResult input) { - return input.getResult(); - } - }); + final DataModificationTransaction t = dataProvider.beginTransaction(); + + // The link has to exist + final Link link = (Link) t.readOperationalData(lii); + Preconditions.checkState(link != null); + + // The source node has to exist + final Node node = sourceNode(t, tii, link); + Preconditions.checkState(node != null); + + final RemoveLspInputBuilder ab = new RemoveLspInputBuilder(); + ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName()); + ab.setNode(node.getSupportingNode().get(0).getKey().getNodeRef()); + + return Futures.transform( + (ListenableFuture>) topologyService.removeLsp(ab.build()), + new Function, OperationResult>() { + @Override + public OperationResult apply(final RpcResult input) { + return input.getResult(); + } + }); } }; @@ -116,23 +332,45 @@ final class TunnelProgramming implements TopologyTunnelPcepProgrammingService { @Override public ListenableFuture> pcepUpdateTunnel(final PcepUpdateTunnelInput input) { - Preconditions.checkNotNull(input.getLinkId()); - - final UpdateLspInputBuilder ab = new UpdateLspInputBuilder(); - ab.fieldsFrom(input); - final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() { @Override protected ListenableFuture executeImpl() { - final ListenableFuture> s = - (ListenableFuture>) pcepTopology.updateLsp(ab.build()); + final InstanceIdentifier tii = topologyIdentifier(input); + final InstanceIdentifier lii = linkIdentifier(tii, input); - return Futures.transform(s, new Function, OperationResult>() { - @Override - public OperationResult apply(final RpcResult input) { - return input.getResult(); - } - }); + final DataModificationTransaction t = dataProvider.beginTransaction(); + + // The link has to exist + final Link link = (Link) t.readOperationalData(lii); + Preconditions.checkState(link != null); + + // The source node has to exist + final Node node = sourceNode(t, tii, link); + Preconditions.checkState(node != null); + + final UpdateLspInputBuilder ab = new UpdateLspInputBuilder(); + ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName()); + ab.setNode(Preconditions.checkNotNull(supportingNode(t, node))); + + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder args = + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder(); + + args.setAdministrative(input.getAdministrativeStatus() == AdministrativeStatus.Active); + args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build()); + args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build()); + args.setEro(buildEro(input.getExplicitHops())); + args.setLspa(new LspaBuilder(input).build()); + + ab.setArguments(args.build()); + + return Futures.transform( + (ListenableFuture>) topologyService.updateLsp(ab.build()), + new Function, OperationResult>() { + @Override + public OperationResult apply(final RpcResult input) { + return input.getResult(); + } + }); } }; diff --git a/programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang b/programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang index fbbe2e991e..471e01d9c5 100644 --- a/programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang +++ b/programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang @@ -41,11 +41,16 @@ module topology-tunnel-programming { } grouping create-tunnel-input { - uses base-tunnel-input; + uses tp:topology-instruction-input; } grouping create-tunnel-output { uses base-tunnel-output; + + leaf link-id { + type nt:link-id; + mandatory true; + } } grouping destroy-tunnel-input { @@ -56,29 +61,30 @@ module topology-tunnel-programming { uses base-tunnel-output; } - grouping p2p-tunnel-input { - uses base-tunnel-input; - - leaf source-tp { - type nt:tp-ref; + grouping tp-reference { + leaf node { + type nt:node-ref; mandatory true; } - leaf destination-tp { + leaf tp { type nt:tp-ref; mandatory true; } } - grouping p2p-tunnel-output { - uses base-tunnel-output; - } - grouping create-p2p-tunnel-input { - uses p2p-tunnel-input; + uses create-tunnel-input; + + container destination { + uses tp-reference; + } + container source { + uses tp-reference; + } } grouping create-p2p-tunnel-output { - uses p2p-tunnel-output; + uses create-tunnel-output; } } diff --git a/rsvp/api/src/main/yang/rsvp.yang b/rsvp/api/src/main/yang/rsvp.yang index 556ac16e47..a6a61931e7 100644 --- a/rsvp/api/src/main/yang/rsvp.yang +++ b/rsvp/api/src/main/yang/rsvp.yang @@ -47,6 +47,25 @@ module rsvp { } } + grouping tunnel-attributes { + leaf hold-priority { + type uint8; + mandatory true; + } + + leaf setup-priority { + type uint8; + mandatory true; + } + + leaf local-protection-desired { + type boolean; + default false; + } + + uses attribute-filters; + } + typedef lsp-id { type uint32; reference "https://tools.ietf.org/html/rfc3209#section-4.6.2.1";