diff options
author | Jozef Gloncak <jgloncak@cisco.com> | 2016-02-09 15:03:53 +0100 |
---|---|---|
committer | Gerrit Code Review <gerrit@fd.io> | 2016-02-09 16:22:39 +0000 |
commit | 5aa62ee7d2be070b2ffef0443b59c8891ed06845 (patch) | |
tree | 8a6d57d66fe2dea72dcdc4dd259cd9eba36561ac | |
parent | ed1bb590d38c1581d35fd822564510ff22288510 (diff) |
Adding vxlan tunnel id allocator.
Change-Id: Id638bc0262481921cd42d830e9fc788e76bc3907
Signed-off-by: Jozef Gloncak <jgloncak@cisco.com>
-rw-r--r-- | vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java (renamed from vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAlocator.java) | 8 | ||||
-rw-r--r-- | vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java | 51 | ||||
-rw-r--r-- | vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java | 29 | ||||
-rw-r--r-- | vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java | 7 | ||||
-rw-r--r-- | vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java | 13 |
5 files changed, 76 insertions, 32 deletions
diff --git a/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAlocator.java b/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java index 58c7e38f3..c458e5754 100644 --- a/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAlocator.java +++ b/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java @@ -8,10 +8,12 @@ package io.fd.honeycomb.vbd.api; -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.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -public interface VxlanTunnelIdAlocator { +public interface VxlanTunnelIdAllocator { /** * Allocate next available vxlan tunnel ID @@ -19,5 +21,5 @@ public interface VxlanTunnelIdAlocator { * @param vpp specify contret vpp for which is next available vxlan id looked for * @return next available (in order) vxlan id. */ - Integer nextIdFor(final NodeId vpp); + Integer nextIdFor(final KeyedInstanceIdentifier<Node, NodeKey> vpp); } diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java index 114e67c90..915e1b431 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/BridgeDomain.java @@ -16,6 +16,7 @@ import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import io.fd.honeycomb.vbd.api.VxlanTunnelIdAllocator; import java.util.Collection; import java.util.List; import java.util.Map; @@ -76,8 +77,6 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { private static final int SOURCE_VPP_INDEX = 0; private static final int DESTINATION_VPP_INDEX = 1; - private static final String TUNNEL_ID_PREFIX = "vxlan_tunnel"; - static final String TUNNEL_ID_DEMO = TUNNEL_ID_PREFIX + "0"; private final KeyedInstanceIdentifier<Topology, TopologyKey> topology; @GuardedBy("this") @@ -85,23 +84,26 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { private final ListenerRegistration<?> reg; private final MountPointService mountService; private final VppModifier vppModifier; + private final VxlanTunnelIdAllocator tunnelIdAllocator; private TopologyVbridgeAugment config; private final String bridgeDomainName; private final String iiBridgeDomainOnVPPRest; private Multimap<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> nodesToVpps = ArrayListMultimap.create(); private BridgeDomain(final DataBroker dataBroker, final MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, - final BindingTransactionChain chain) { + final BindingTransactionChain chain, VxlanTunnelIdAllocator tunnelIdAllocator) { + this.bridgeDomainName = topology.getKey().getTopologyId().getValue(); + this.vppModifier = new VppModifier(mountService, bridgeDomainName); + this.topology = Preconditions.checkNotNull(topology); this.chain = Preconditions.checkNotNull(chain); this.mountService = mountService; + this.tunnelIdAllocator = tunnelIdAllocator; - this.bridgeDomainName = topology.getKey().getTopologyId().getValue(); this.iiBridgeDomainOnVPPRest = provideIIBrdigeDomainOnVPPRest(); reg = dataBroker.registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, topology), this); - this.vppModifier = new VppModifier(mountService, bridgeDomainName); } private String provideIIBrdigeDomainOnVPPRest() { @@ -112,7 +114,8 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { } static BridgeDomain create(final DataBroker dataBroker, - MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final BindingTransactionChain chain) { + MountPointService mountService, final KeyedInstanceIdentifier<Topology, TopologyKey> topology, final BindingTransactionChain chain, + final VxlanTunnelIdAllocator tunnelIdAllocator) { LOG.debug("Wiping operational state of {}", topology); @@ -120,7 +123,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { tx.delete(LogicalDatastoreType.OPERATIONAL, topology); tx.submit(); - return new BridgeDomain(dataBroker, mountService, topology, chain); + return new BridgeDomain(dataBroker, mountService, topology, chain, tunnelIdAllocator); } synchronized void forceStop() { @@ -238,10 +241,12 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { private void addTunnel(final NodeId sourceNode) { final KeyedInstanceIdentifier<Node, NodeKey> iiToSrcVpp = nodesToVpps.get(sourceNode).iterator().next(); + final Integer srcVxlanTunnelId = tunnelIdAllocator.nextIdFor(iiToSrcVpp); for (Map.Entry<NodeId, KeyedInstanceIdentifier<Node, NodeKey>> nodeToVpp : nodesToVpps.entries()) { if (!nodeToVpp.getKey().equals(sourceNode)) { //TODO: check whether returned value from nodesToVpps is not null final KeyedInstanceIdentifier<Node, NodeKey> iiToDstVpp = nodeToVpp.getValue(); + final Integer dstVxlanTunnelId = tunnelIdAllocator.nextIdFor(iiToDstVpp); final NodeId dstNode = nodeToVpp.getKey(); final ListenableFuture<List<Optional<Ipv4AddressNoZone>>> ipAddressesFuture = vppModifier.readIpAddressesFromVpps(iiToSrcVpp, iiToDstVpp); @@ -255,16 +260,16 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { if (ipAddressSrcVpp != null && ipAddressDstVpp != null) { if (ipAddressSrcVpp.isPresent() && ipAddressDstVpp.isPresent()) { //writing v3po:vxlan container to source node - vppModifier.createVirtualInterfaceOnVpp(ipAddressSrcVpp.get(), ipAddressDstVpp.get(), iiToSrcVpp); + vppModifier.createVirtualInterfaceOnVpp(ipAddressSrcVpp.get(), ipAddressDstVpp.get(), iiToSrcVpp, srcVxlanTunnelId); //writing v3po:vxlan container to existing node - vppModifier.createVirtualInterfaceOnVpp(ipAddressDstVpp.get(), ipAddressSrcVpp.get(), iiToDstVpp); + vppModifier.createVirtualInterfaceOnVpp(ipAddressDstVpp.get(), ipAddressSrcVpp.get(), iiToDstVpp, dstVxlanTunnelId); - addTerminationPoint(topology.child(Node.class, new NodeKey(dstNode))); - addTerminationPoint(topology.child(Node.class, new NodeKey(sourceNode))); + addTerminationPoint(topology.child(Node.class, new NodeKey(dstNode)), dstVxlanTunnelId); + addTerminationPoint(topology.child(Node.class, new NodeKey(sourceNode)), srcVxlanTunnelId); - addLinkBetweenTerminationPoints(sourceNode, dstNode); - addLinkBetweenTerminationPoints(dstNode, sourceNode); + addLinkBetweenTerminationPoints(sourceNode, dstNode, srcVxlanTunnelId, dstVxlanTunnelId); + addLinkBetweenTerminationPoints(dstNode, sourceNode, srcVxlanTunnelId, dstVxlanTunnelId); } } } @@ -279,32 +284,34 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { } } - private void addLinkBetweenTerminationPoints(final NodeId newVpp, final NodeId odlVpp) { + private void addLinkBetweenTerminationPoints(final NodeId newVpp, final NodeId odlVpp, + final int srcVxlanTunnelId, final int dstVxlanTunnelId) { //TODO clarify how should identifier of link looks like final String linkIdStr = newVpp.getValue() + "-" + odlVpp.getValue(); final LinkId linkId = new LinkId(linkIdStr); final KeyedInstanceIdentifier<Link, LinkKey> iiToLink = topology.child(Link.class, new LinkKey(linkId)); final WriteTransaction wTx = chain.newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.OPERATIONAL, iiToLink, prepareLinkData(newVpp, odlVpp, linkId), true); + wTx.put(LogicalDatastoreType.OPERATIONAL, iiToLink, prepareLinkData(newVpp, odlVpp, linkId, srcVxlanTunnelId, dstVxlanTunnelId), true); wTx.submit(); } - private Link prepareLinkData(final NodeId newVpp, final NodeId oldVpp, final LinkId linkId) { + private Link prepareLinkData(final NodeId newVpp, final NodeId oldVpp, final LinkId linkId, + final int srcVxlanTunnelId, final int dstVxlanTunnelId) { final LinkBuilder linkBuilder = new LinkBuilder(); linkBuilder.setLinkId(linkId); final SourceBuilder sourceBuilder = new SourceBuilder(); sourceBuilder.setSourceNode(newVpp); - sourceBuilder.setSourceTp(new TpId(TUNNEL_ID_DEMO)); + sourceBuilder.setSourceTp(new TpId(VbdUtil.provideVxlanId(srcVxlanTunnelId))); linkBuilder.setSource(sourceBuilder.build()); final DestinationBuilder destinationBuilder = new DestinationBuilder(); destinationBuilder.setDestNode(oldVpp); - destinationBuilder.setDestTp(new TpId(TUNNEL_ID_DEMO)); + destinationBuilder.setDestTp(new TpId(VbdUtil.provideVxlanId(dstVxlanTunnelId))); linkBuilder.setDestination(destinationBuilder.build()); final LinkVbridgeAugmentBuilder linkVbridgeAugmentBuilder = new LinkVbridgeAugmentBuilder(); - linkVbridgeAugmentBuilder.setTunnel(new ExternalReference(TUNNEL_ID_DEMO)); + linkVbridgeAugmentBuilder.setTunnel(new ExternalReference(VbdUtil.provideVxlanId(srcVxlanTunnelId))); linkBuilder.addAugmentation(LinkVbridgeAugment.class, linkVbridgeAugmentBuilder.build()); return linkBuilder.build(); } @@ -344,9 +351,9 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { }); } - private void addTerminationPoint(final KeyedInstanceIdentifier<Node, NodeKey> nodeIID) { + private void addTerminationPoint(final KeyedInstanceIdentifier<Node, NodeKey> nodeIID, final int vxlanTunnelId) { // build data - final ExternalReference ref = new ExternalReference(TUNNEL_ID_DEMO); + final ExternalReference ref = new ExternalReference(VbdUtil.provideVxlanId(vxlanTunnelId)); final TunnelInterfaceBuilder iFaceBuilder = new TunnelInterfaceBuilder(); iFaceBuilder.setTunnelInterface(ref); @@ -355,7 +362,7 @@ final class BridgeDomain implements DataTreeChangeListener<Topology> { final TerminationPointBuilder tpBuilder = new TerminationPointBuilder(); tpBuilder.addAugmentation(TerminationPointVbridgeAugment.class, tpAugmentBuilder.build()); - tpBuilder.setTpId(new TpId(TUNNEL_ID_DEMO)); + tpBuilder.setTpId(new TpId(VbdUtil.provideVxlanId(vxlanTunnelId))); final TerminationPoint tp = tpBuilder.build(); // process data diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java index 213ff6685..dfab2e877 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/TopologyMonitor.java @@ -9,6 +9,7 @@ package io.fd.honeycomb.vbd.impl; import com.google.common.base.Preconditions; +import io.fd.honeycomb.vbd.api.VxlanTunnelIdAllocator; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -26,6 +27,8 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListen import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopology; 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.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,10 +44,12 @@ final class TopologyMonitor implements DataTreeChangeListener<VbridgeTopology>, private final Map<TopologyKey, BridgeDomain> domains = new HashMap<>(); private final DataBroker dataBroker; private final MountPointService mountService; + private static final VxlanTunnelIdAllocator tunnelIdAllocator = new VxlanTunnelIdAllocatorImpl(); public TopologyMonitor(DataBroker dataBroker, MountPointService mountService) { this.dataBroker = Preconditions.checkNotNull(dataBroker); this.mountService = Preconditions.checkNotNull(mountService); + } @Override @@ -118,7 +123,7 @@ final class TopologyMonitor implements DataTreeChangeListener<VbridgeTopology>, } }); - final BridgeDomain domain = BridgeDomain.create(dataBroker, mountService, topology, chain); + final BridgeDomain domain = BridgeDomain.create(dataBroker, mountService, topology, chain, tunnelIdAllocator); domains.put(topology.getKey(), domain); LOG.debug("Bridge domain {} for {} started", domain, topology); @@ -159,4 +164,26 @@ final class TopologyMonitor implements DataTreeChangeListener<VbridgeTopology>, LOG.debug("Topology monitor {} shut down completed", this); } + + public static class VxlanTunnelIdAllocatorImpl implements VxlanTunnelIdAllocator { + + private final Map<KeyedInstanceIdentifier<Node, NodeKey>, Integer> vppIIToNextTunnelId; + + VxlanTunnelIdAllocatorImpl() { + vppIIToNextTunnelId = new HashMap<>(); + } + + @Override + public synchronized Integer nextIdFor(final KeyedInstanceIdentifier<Node, NodeKey> iiToVPP) { + if(vppIIToNextTunnelId.containsKey(iiToVPP)) { + final int value = vppIIToNextTunnelId.get(iiToVPP); + vppIIToNextTunnelId.put(iiToVPP, value + 1); + return value + 1; + } else { + vppIIToNextTunnelId.put(iiToVPP, 0); + return 0; + } + } + + } } diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java index ecc970322..2a29d7b4e 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VbdUtil.java @@ -17,6 +17,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class VbdUtil { + private static final String TUNNEL_ID_PREFIX = "vxlan_tunnel"; + + private VbdUtil() { throw new UnsupportedOperationException("Can't instantiate util class"); } @@ -33,5 +36,9 @@ public class VbdUtil { return null; } + static String provideVxlanId(final int vxlanTunnelId) { + return TUNNEL_ID_PREFIX + vxlanTunnelId; + } + } diff --git a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java index 489f6c796..3378e6817 100644 --- a/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java +++ b/vbd/impl/src/main/java/io/fd/honeycomb/vbd/impl/VppModifier.java @@ -146,15 +146,16 @@ public class VppModifier { return resultFuture; } - void createVirtualInterfaceOnVpp(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst, final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp) { + void createVirtualInterfaceOnVpp(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst, final KeyedInstanceIdentifier<Node, NodeKey> iiToVpp, + final Integer vxlanTunnelId) { final Vxlan vxlanData = prepareVxlan(ipSrc, ipDst); - final Interface intfData = prepareVirtualInterfaceData(vxlanData); + final Interface intfData = prepareVirtualInterfaceData(vxlanData, vxlanTunnelId); final DataBroker vppDataBroker = VbdUtil.resolveDataBrokerForMountPoint(iiToVpp, mountService); if (vppDataBroker != null) { final WriteTransaction wTx = vppDataBroker.newWriteOnlyTransaction(); final KeyedInstanceIdentifier<Interface, InterfaceKey> iiToInterface - = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(BridgeDomain.TUNNEL_ID_DEMO)); + = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(VbdUtil.provideVxlanId(vxlanTunnelId))); wTx.put(LogicalDatastoreType.CONFIGURATION, iiToInterface, intfData); final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wTx.submit(); Futures.addCallback(submitFuture, new FutureCallback<Void>() { @@ -169,14 +170,14 @@ public class VppModifier { } }); } else { - LOG.debug("Writing virtual interface {} to VPP {} wasn't successfull because missing data broker.", BridgeDomain.TUNNEL_ID_DEMO, iiToVpp); + LOG.debug("Writing virtual interface {} to VPP {} wasn't successfull because missing data broker.", VbdUtil.provideVxlanId(vxlanTunnelId), iiToVpp); } } - private Interface prepareVirtualInterfaceData(final Vxlan vxlan) { + private Interface prepareVirtualInterfaceData(final Vxlan vxlan, Integer vxlanTunnelId) { final InterfaceBuilder interfaceBuilder = new InterfaceBuilder(); //TODO implement tunnel counter - interfaceBuilder.setName(BridgeDomain.TUNNEL_ID_DEMO); + interfaceBuilder.setName(VbdUtil.provideVxlanId(vxlanTunnelId)); interfaceBuilder.setType(VxlanTunnel.class); VppInterfaceAugmentationBuilder vppInterfaceAugmentationBuilder = new VppInterfaceAugmentationBuilder(); vppInterfaceAugmentationBuilder.setVxlan(vxlan); |