From 5aa62ee7d2be070b2ffef0443b59c8891ed06845 Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Tue, 9 Feb 2016 15:03:53 +0100 Subject: Adding vxlan tunnel id allocator. Change-Id: Id638bc0262481921cd42d830e9fc788e76bc3907 Signed-off-by: Jozef Gloncak --- .../VxlanTunnelIdAllocator.java | 25 +++++++++++ .../VxlanTunnelIdAlocator.java | 23 ---------- .../io/fd/honeycomb/vbd/impl/BridgeDomain.java | 51 ++++++++++++---------- .../io/fd/honeycomb/vbd/impl/TopologyMonitor.java | 29 +++++++++++- .../java/io/fd/honeycomb/vbd/impl/VbdUtil.java | 7 +++ .../java/io/fd/honeycomb/vbd/impl/VppModifier.java | 13 +++--- 6 files changed, 96 insertions(+), 52 deletions(-) create mode 100644 vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java delete mode 100644 vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAlocator.java (limited to 'vbd') diff --git a/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java b/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java new file mode 100644 index 000000000..c458e5754 --- /dev/null +++ b/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAllocator.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + *

+ * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package io.fd.honeycomb.vbd.api; + + +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 VxlanTunnelIdAllocator { + + /** + * Allocate next available vxlan tunnel ID + * + * @param vpp specify contret vpp for which is next available vxlan id looked for + * @return next available (in order) vxlan id. + */ + Integer nextIdFor(final KeyedInstanceIdentifier vpp); +} 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/VxlanTunnelIdAlocator.java deleted file mode 100644 index 58c7e38f3..000000000 --- a/vbd/api/src/main/java/io.fd.honeycomb.vbd.api/VxlanTunnelIdAlocator.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. - *

- * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package io.fd.honeycomb.vbd.api; - - -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; - - -public interface VxlanTunnelIdAlocator { - - /** - * Allocate next available vxlan tunnel ID - * - * @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); -} 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 { 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; @GuardedBy("this") @@ -85,23 +84,26 @@ final class BridgeDomain implements DataTreeChangeListener { 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> nodesToVpps = ArrayListMultimap.create(); private BridgeDomain(final DataBroker dataBroker, final MountPointService mountService, final KeyedInstanceIdentifier 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 { } static BridgeDomain create(final DataBroker dataBroker, - MountPointService mountService, final KeyedInstanceIdentifier topology, final BindingTransactionChain chain) { + MountPointService mountService, final KeyedInstanceIdentifier topology, final BindingTransactionChain chain, + final VxlanTunnelIdAllocator tunnelIdAllocator) { LOG.debug("Wiping operational state of {}", topology); @@ -120,7 +123,7 @@ final class BridgeDomain implements DataTreeChangeListener { 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 { private void addTunnel(final NodeId sourceNode) { final KeyedInstanceIdentifier iiToSrcVpp = nodesToVpps.get(sourceNode).iterator().next(); + final Integer srcVxlanTunnelId = tunnelIdAllocator.nextIdFor(iiToSrcVpp); for (Map.Entry> nodeToVpp : nodesToVpps.entries()) { if (!nodeToVpp.getKey().equals(sourceNode)) { //TODO: check whether returned value from nodesToVpps is not null final KeyedInstanceIdentifier iiToDstVpp = nodeToVpp.getValue(); + final Integer dstVxlanTunnelId = tunnelIdAllocator.nextIdFor(iiToDstVpp); final NodeId dstNode = nodeToVpp.getKey(); final ListenableFuture>> ipAddressesFuture = vppModifier.readIpAddressesFromVpps(iiToSrcVpp, iiToDstVpp); @@ -255,16 +260,16 @@ final class BridgeDomain implements DataTreeChangeListener { 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 { } } - 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 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 { }); } - private void addTerminationPoint(final KeyedInstanceIdentifier nodeIID) { + private void addTerminationPoint(final KeyedInstanceIdentifier 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 { 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, private final Map 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, } }); - 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, LOG.debug("Topology monitor {} shut down completed", this); } + + public static class VxlanTunnelIdAllocatorImpl implements VxlanTunnelIdAllocator { + + private final Map, Integer> vppIIToNextTunnelId; + + VxlanTunnelIdAllocatorImpl() { + vppIIToNextTunnelId = new HashMap<>(); + } + + @Override + public synchronized Integer nextIdFor(final KeyedInstanceIdentifier 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 iiToVpp) { + void createVirtualInterfaceOnVpp(final Ipv4AddressNoZone ipSrc, final Ipv4AddressNoZone ipDst, final KeyedInstanceIdentifier 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 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 submitFuture = wTx.submit(); Futures.addCallback(submitFuture, new FutureCallback() { @@ -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); -- cgit 1.2.3-korg