<groupId>org.opendaylight.mdsal</groupId>
<artifactId>yang-binding</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types-20130715</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
--- /dev/null
+module pod-meta {
+ namespace "urn:opendaylight:netvirt:coe:meta";
+ prefix "coemeta";
+
+ import ietf-yang-types {
+ prefix yang;
+ revision-date "2013-07-15";
+ }
+
+ revision "2018-01-18" {
+ description "Coe Meta Information";
+ }
+
+ container podidentifier-info {
+ description "Contains the list of podnames to poduuid mapping";
+
+ list pod-identifier {
+ key pod-name;
+ leaf pod-name {
+ type string;
+ }
+
+ leaf pod-uuid {
+ type instance-identifier;
+ description "reference to a pod";
+ }
+ }
+ }
+}
\ No newline at end of file
<artifactId>elanmanager-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>vpnmanager-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.ovsdb</groupId>
+ <artifactId>utils.southbound-utils</artifactId>
+ <version>${ovsdb.version}</version>
+ </dependency>
</dependencies>
<build>
--- /dev/null
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. 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 org.opendaylight.netvirt.coe.caches;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
+import org.opendaylight.infrautils.caches.CacheProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.Coe;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@Singleton
+public class PodsCache extends DataObjectCache<Pods> {
+ @Inject
+ public PodsCache(DataBroker dataBroker, CacheProvider cacheProvider) {
+ super(Pods.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.create(Coe.class).child(Pods.class), cacheProvider);
+ }
+}
/*
- * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ * Copyright (c) 2017 - 2018 Ericsson India Global Services Pvt Ltd. 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,
package org.opendaylight.netvirt.coe.listeners;
import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.netvirt.coe.utils.CoeUtils;
+import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.Coe;
import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.pod_attributes.Interface;
private static final Logger LOG = LoggerFactory.getLogger(PodListener.class);
private ListenerRegistration<PodListener> listenerRegistration;
- private final ManagedNewTransactionRunner txRunner;
private final JobCoordinator jobCoordinator;
+ private final ManagedNewTransactionRunner txRunner;
@Inject
public PodListener(final DataBroker dataBroker, JobCoordinator jobCoordinator) {
Interface podInterfaceAfter = dataObjectModification.getDataAfter();
switch (dataObjectModification.getModificationType()) {
case DELETE:
- remove(podsBefore, podInterfaceBefore);
+ remove(rootIdentifier, podsBefore, podInterfaceBefore);
break;
case SUBTREE_MODIFIED:
- update(pods, podsBefore, podInterfaceAfter);
+ update(rootIdentifier, pods, podsBefore, podInterfaceBefore, podInterfaceAfter);
break;
case WRITE:
if (podInterfaceBefore == null) {
- add(pods, podInterfaceAfter);
+ add(rootIdentifier, pods, podInterfaceAfter);
} else {
- update(pods, podsBefore, podInterfaceAfter);
+ update(rootIdentifier, pods, podsBefore, podInterfaceBefore,
+ podInterfaceAfter);
}
break;
default:
}
}
- private void add(Pods pods, Interface podInterface) {
+ private void add(InstanceIdentifier<Pods> instanceIdentifier, Pods pods, Interface podInterface) {
LOG.trace("Pod added {}",pods);
if (pods.getNetworkNS() == null || pods.getHostIpAddress() == null) {
LOG.warn("pod {} added with insufficient information to process", pods.getName());
return;
}
- // TODO use infrautils caching mechanism to add this info to cache.
-
- jobCoordinator.enqueueJob(pods.getName(), new PodConfigAddWorker(txRunner, pods, podInterface));
+ jobCoordinator.enqueueJob(pods.getName(), new PodConfigAddWorker(txRunner, instanceIdentifier,
+ pods, podInterface));
}
- private void update(Pods podsAfter, Pods podsBefore, Interface podInterfaceAfter) {
+ private void update(InstanceIdentifier<Pods> instanceIdentifier, Pods podsAfter, Pods podsBefore,
+ Interface podInterfaceBefore, Interface podInterfaceAfter) {
LOG.trace("Pod updated before :{}, after :{}",podsBefore, podsAfter);
- if (!Objects.equals(podsAfter.getNetworkNS(), podsBefore.getNetworkNS())
- || !Objects.equals(podsAfter.getHostIpAddress(), podsBefore.getHostIpAddress())) {
- if (podsBefore.getNetworkNS() != null || podsBefore.getHostIpAddress() != null) {
+ if (!Objects.equals(podsAfter.getHostIpAddress(), podsBefore.getHostIpAddress())
+ || !Objects.equals(podInterfaceBefore.getIpAddress(), podInterfaceAfter.getIpAddress())) {
+ //if (podsBefore.getNetworkNS() != null || podsBefore.getHostIpAddress() != null) {
// Case where pod is moving from one namespace to another
// issue a delete of all previous configuration, and add the new one.
- jobCoordinator.enqueueJob(podsAfter.getName(), new PodConfigRemoveWorker(txRunner, podsBefore));
- }
- jobCoordinator.enqueueJob(podsAfter.getName(), new PodConfigAddWorker(txRunner, podsAfter,
- podInterfaceAfter));
+ //jobCoordinator.enqueueJob(podsAfter.getName(), new PodConfigRemoveWorker(txRunner, podsBefore));
+ //}
+ jobCoordinator.enqueueJob(podsAfter.getName(), new PodConfigAddWorker(txRunner, instanceIdentifier,
+ podsAfter, podInterfaceAfter));
}
- // TODO use infrautils caching mechanism to add this info to cache.
}
- private void remove(Pods pods, Interface podInterface) {
+ private void remove(InstanceIdentifier<Pods> instanceIdentifier,
+ Pods pods, Interface podInterface) {
LOG.trace("Pod removed {}", pods);
if (pods.getNetworkNS() == null || pods.getHostIpAddress() == null) {
LOG.warn("pod {} deletion without a valid network id {}", podInterface.getUid().getValue());
}
private static class PodConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+ InstanceIdentifier<Pods> podsInstanceIdentifier;
private final Pods pods;
private final Interface podInterface;
private final ManagedNewTransactionRunner txRunner;
- PodConfigAddWorker(ManagedNewTransactionRunner txRunner, Pods pods, Interface podInterface) {
+ PodConfigAddWorker(ManagedNewTransactionRunner txRunner, InstanceIdentifier<Pods> podsInstanceIdentifier,
+ Pods pods, Interface podInterface) {
this.pods = pods;
this.podInterface = podInterface;
this.txRunner = txRunner;
+ this.podsInstanceIdentifier = podsInstanceIdentifier;
}
@Override
public List<ListenableFuture<Void>> call() {
LOG.trace("Adding Pod : {}", podInterface);
String interfaceName = CoeUtils.buildInterfaceName(pods.getNetworkNS(), pods.getName());
- return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
String nodeIp = String.valueOf(pods.getHostIpAddress().getValue());
ElanInstance elanInstance = CoeUtils.createElanInstanceForTheFirstPodInTheNetwork(
pods.getNetworkNS(), nodeIp, podInterface, tx);
LOG.debug("Creating ELAN Interface for pod {}", interfaceName);
CoeUtils.createElanInterface(portInterfaceName,
elanInstance.getElanInstanceName(), tx);
+ LOG.debug("Creating VPN instance for namespace {}", pods.getNetworkNS());
+ List<String> rd = Arrays.asList("100:1");
+ CoeUtils.createVpnInstance(pods.getNetworkNS(), rd, null, null,
+ VpnInstance.Type.L3, 0, IpVersionChoice.IPV4, tx);
}));
+ if (podInterface.getIpAddress() != null) {
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ CoeUtils.createPodNameToPodUuidMap(interfaceName, podsInstanceIdentifier, tx);
+ }));
+ }
+ return futures;
}
}
private final Pods pods;
private final ManagedNewTransactionRunner txRunner;
- PodConfigRemoveWorker(ManagedNewTransactionRunner txRunner, Pods pods) {
+
+ PodConfigRemoveWorker(ManagedNewTransactionRunner txRunner,
+ Pods pods) {
this.pods = pods;
this.txRunner = txRunner;
}
@Override
public List<ListenableFuture<Void>> call() {
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
String podInterfaceName = CoeUtils.buildInterfaceName(pods.getNetworkNS(), pods.getName());
- LOG.trace("Deleting Pod : {}", podInterfaceName);
- return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ LOG.trace("Deleting Pod : {}", podInterfaceName);
+ LOG.debug("Deleting VPN Interface for pod {}", podInterfaceName);
+ CoeUtils.deleteVpnInterface(podInterfaceName, tx);
LOG.debug("Deleting ELAN Interface for pod {}", podInterfaceName);
CoeUtils.deleteElanInterface(podInterfaceName, tx);
LOG.info("interface deletion for pod {}", podInterfaceName);
CoeUtils.deleteOfPortInterface(podInterfaceName, tx);
- // TODO delete elan-instance if this is the last pod in the network
- // TODO use infrautils cache to maintain this mapping and to decide on elan-instance deletion
+ // TODO delete elan-instance if this is the last pod in the host
+ // TODO delete vpn-instance if this is the last pod in the network
+ }));
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ CoeUtils.deletePodNameToPodUuidMap(podInterfaceName, tx);
}));
+ return futures;
}
}
}
--- /dev/null
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. 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 org.opendaylight.netvirt.coe.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.listeners.AbstractSyncDataTreeChangeListener;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.netvirt.coe.caches.PodsCache;
+import org.opendaylight.netvirt.coe.utils.CoeUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+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.network.topology.Topology;
+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.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class TerminationPointStateListener extends
+ AbstractSyncDataTreeChangeListener<OvsdbTerminationPointAugmentation> {
+ private static final Logger LOG = LoggerFactory.getLogger(TerminationPointStateListener.class);
+ private final JobCoordinator coordinator;
+ private final PodsCache podsCache;
+ private final DataTreeEventCallbackRegistrar eventCallbacks;
+ private final ManagedNewTransactionRunner txRunner;
+
+ @Inject
+ public TerminationPointStateListener(DataBroker dataBroker, final JobCoordinator coordinator,
+ PodsCache podsCache, DataTreeEventCallbackRegistrar eventCallbacks) {
+ super(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(Node.class)
+ .child(TerminationPoint.class).augmentation(OvsdbTerminationPointAugmentation.class).build());
+ this.coordinator = coordinator;
+ this.podsCache = podsCache;
+ this.eventCallbacks = eventCallbacks;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ }
+
+ @Override
+ public void remove(OvsdbTerminationPointAugmentation tpOld) {
+ // DO nothing
+ }
+
+ @Override
+ public void update(@Nullable OvsdbTerminationPointAugmentation tpOld, OvsdbTerminationPointAugmentation tpNew) {
+ LOG.debug("Received Update DataChange Notification for ovsdb termination point {}", tpNew.getName());
+
+ Pair<String, String> tpNewDetails = CoeUtils.getAttachedInterfaceAndMac(tpNew);
+ Pair<String, String> tpOldDetails = CoeUtils.getAttachedInterfaceAndMac(tpOld);
+
+ if (!Objects.equals(tpNewDetails, tpOldDetails)) {
+ String interfaceName = tpNewDetails.getLeft();
+ String macAddress = tpNewDetails.getRight();
+ if (interfaceName != null && macAddress != null) {
+ LOG.debug("Detected external interface-id {} and attached mac address {} for {}", interfaceName,
+ macAddress, tpNew.getName());
+ eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL,
+ CoeUtils.getPodMetaInstanceId(interfaceName), (unused, alsoUnused) -> {
+ LOG.info("Pod configuration {} detected for termination-point {},"
+ + "proceeding with l2 and l3 configurations", interfaceName, tpNew.getName());
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
+ InstanceIdentifier<Pods> instanceIdentifier = CoeUtils.getPodUUIDforPodName(interfaceName,
+ tx);
+ Pods pods = podsCache.get(instanceIdentifier).get();
+ if (pods != null) {
+ IpAddress podIpAddress = pods.getInterface().get(0).getIpAddress();
+ CoeUtils.createVpnInterface(pods.getNetworkNS(), pods, interfaceName, macAddress,
+ false, tx);
+ CoeUtils.updateElanInterfaceWithStaticMac(macAddress, podIpAddress, interfaceName, tx);
+ }
+ }));
+ return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
+ });
+ }
+ }
+ }
+
+ @Override
+ public void add(OvsdbTerminationPointAugmentation tpNew) {
+ update(null, tpNew);
+ }
+}
/*
- * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ * Copyright (c) 2017 - 2018 Ericsson India Global Services Pvt Ltd. 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,
package org.opendaylight.netvirt.coe.utils;
-import com.google.common.base.Optional;
import com.google.common.collect.ImmutableBiMap;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+
+import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv6FamilyBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNames;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNamesBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNamesKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.NetworkAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.coe.Pods;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.PodidentifierInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.coe.meta.rev180118.podidentifier.info.PodIdentifierKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.elan._interface.StaticMacEntriesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
WriteTransaction wrtConfigTxn) {
InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
.class, new ElanInterfaceKey(elanInterfaceName)).build();
- // TODO set static mac entries based on pod interface mac
ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName)
.setName(elanInterfaceName).setKey(new ElanInterfaceKey(elanInterfaceName)).build();
wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, id, elanInterface);
LOG.debug("Creating new ELAN Interface {}", elanInterface);
}
+ public static void updateElanInterfaceWithStaticMac(String macAddress, IpAddress ipAddress,
+ String elanInterfaceName,
+ WriteTransaction wrtConfigTxn) {
+ InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
+ .class, new ElanInterfaceKey(elanInterfaceName)).build();
+ PhysAddress physAddress = PhysAddress.getDefaultInstance(macAddress);
+ List<StaticMacEntries> staticMacEntriesList = new ArrayList<>();
+ StaticMacEntries staticMacEntries = new StaticMacEntriesBuilder().setKey(new StaticMacEntriesKey(
+ physAddress)).setMacAddress(physAddress).setIpPrefix(ipAddress).build();
+ staticMacEntriesList.add(staticMacEntries);
+ ElanInterface elanInterface = new ElanInterfaceBuilder().setName(elanInterfaceName)
+ .setKey(new ElanInterfaceKey(elanInterfaceName)).setStaticMacEntries(staticMacEntriesList).build();
+ wrtConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, id, elanInterface);
+ LOG.debug("Updating ELAN Interface with static mac {}", elanInterface);
+ }
+
+ public static void createPodNameToPodUuidMap(String podName, InstanceIdentifier<Pods> pod,
+ WriteTransaction writeTransaction) {
+ InstanceIdentifier<PodIdentifier> id = InstanceIdentifier.builder(PodidentifierInfo.class)
+ .child(PodIdentifier.class, new PodIdentifierKey(podName)).build();
+ PodIdentifier podIdentifier = new PodIdentifierBuilder().setKey(new PodIdentifierKey(podName))
+ .setPodName(podName).setPodUuid(pod).build();
+ writeTransaction.put(LogicalDatastoreType.OPERATIONAL, id, podIdentifier);
+ LOG.debug("Creating podnametouuid map {} to {}", podName, pod);
+ }
+
+ public static void deletePodNameToPodUuidMap(String podName,
+ WriteTransaction writeTransaction) {
+ InstanceIdentifier<PodIdentifier> id = InstanceIdentifier.builder(PodidentifierInfo.class)
+ .child(PodIdentifier.class, new PodIdentifierKey(podName)).build();
+ writeTransaction.delete(LogicalDatastoreType.OPERATIONAL, id);
+ LOG.debug("Deleting podnametouuid map for {}", podName);
+ }
+
+ public static InstanceIdentifier<Pods> getPodUUIDforPodName(String podName,
+ ReadTransaction readTransaction) throws ReadFailedException {
+ InstanceIdentifier<PodIdentifier> id = InstanceIdentifier.builder(PodidentifierInfo.class)
+ .child(PodIdentifier.class, new PodIdentifierKey(podName)).build();
+ InstanceIdentifier<?> instanceIdentifier = readTransaction.read(LogicalDatastoreType.OPERATIONAL, id)
+ .checkedGet().toJavaUtil().map(PodIdentifier::getPodUuid).orElse(null);
+ if (instanceIdentifier != null) {
+ return (InstanceIdentifier<Pods>) instanceIdentifier;
+ }
+ return null;
+ }
+
public static void deleteElanInterface(String elanInterfaceName, WriteTransaction wrtConfigTxn) {
InstanceIdentifier<ElanInterface> id = InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface
.class, new ElanInterfaceKey(elanInterfaceName)).build();
}
public static ElanInstance createElanInstanceForTheFirstPodInTheNetwork(String networkNS, String nodeIp,
- org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod.rev170611.pod_attributes.Interface
- podInterface, ReadWriteTransaction tx) throws ReadFailedException {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.coe.northbound.pod
+ .rev170611.pod_attributes.Interface podInterface,
+ ReadWriteTransaction wrtConfigTxn) throws ReadFailedException {
String elanInstanceName = buildElanInstanceName(nodeIp, networkNS);
InstanceIdentifier<ElanInstance> id = createElanInstanceIdentifier(elanInstanceName);
- Optional<ElanInstance> existingElanInstance = tx.read(LogicalDatastoreType.CONFIGURATION, id).checkedGet();
- if (existingElanInstance.isPresent()) {
- return existingElanInstance.get();
+ ElanInstance existingElanInstance = wrtConfigTxn.read(LogicalDatastoreType.CONFIGURATION, id)
+ .checkedGet().orNull();
+ if (existingElanInstance != null) {
+ return existingElanInstance;
}
Class<? extends SegmentTypeBase> segmentType = getSegmentTypeFromNetwork(podInterface);
String segmentationId = String.valueOf(podInterface.getSegmentationId());
Boolean isExternal = false;
ElanInstance elanInstance = CoeUtils.buildElanInstance(elanInstanceName, segmentType,
segmentationId, isExternal);
- tx.put(LogicalDatastoreType.CONFIGURATION, id, elanInstance);
+ wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, id, elanInstance);
LOG.info("ELAN instance created for the first pod in the network {}", podInterface.getUid());
return elanInstance;
}
+
+ public static Pair<String, String> getAttachedInterfaceAndMac(OvsdbTerminationPointAugmentation ovsdbTp) {
+ String interfaceName = null;
+ String macAddress = null;
+ if (ovsdbTp != null) {
+ List<InterfaceExternalIds> ifaceExtIds = ovsdbTp.getInterfaceExternalIds();
+ if (ifaceExtIds != null) {
+ Iterator var2 = ifaceExtIds.iterator();
+ while (var2.hasNext()) {
+ if (interfaceName != null && macAddress != null) {
+ break;
+ }
+ InterfaceExternalIds entry = (InterfaceExternalIds)var2.next();
+ if (entry.getExternalIdKey().equals("iface-id")) {
+ interfaceName = entry.getExternalIdValue();
+ continue;
+ }
+ if (entry.getExternalIdKey().equals("attached-mac")) {
+ macAddress = entry.getExternalIdValue();
+ continue;
+ }
+ }
+ }
+ }
+
+ return Pair.of(interfaceName, macAddress);
+ }
+
+ public static InstanceIdentifier<PodIdentifier> getPodMetaInstanceId(String externalInterfaceId) {
+ return InstanceIdentifier.builder(PodidentifierInfo.class)
+ .child(PodIdentifier.class, new PodIdentifierKey(externalInterfaceId)).build();
+ }
+
+ public static void createVpnInstance(String vpnName, List<String> rd, List<String> irt, List<String> ert,
+ VpnInstance.Type type, long l3vni, IpVersionChoice ipVersion,
+ ReadWriteTransaction tx) throws ReadFailedException {
+ List<VpnTarget> vpnTargetList = new ArrayList<>();
+ LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
+
+ VpnInstanceBuilder builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName))
+ .setVpnInstanceName(vpnName)
+ .setType(type).setL3vni(l3vni);
+ if (irt != null && !irt.isEmpty()) {
+ if (ert != null && !ert.isEmpty()) {
+ List<String> commonRT = new ArrayList<>(irt);
+ commonRT.retainAll(ert);
+
+ for (String common : commonRT) {
+ irt.remove(common);
+ ert.remove(common);
+ VpnTarget vpnTarget =
+ new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue(common)
+ .setVrfRTType(VpnTarget.VrfRTType.Both).build();
+ vpnTargetList.add(vpnTarget);
+ }
+ }
+ for (String importRT : irt) {
+ VpnTarget vpnTarget =
+ new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue(importRT)
+ .setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
+ vpnTargetList.add(vpnTarget);
+ }
+ }
+
+ if (ert != null && !ert.isEmpty()) {
+ for (String exportRT : ert) {
+ VpnTarget vpnTarget =
+ new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue(exportRT)
+ .setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
+ vpnTargetList.add(vpnTarget);
+ }
+ }
+
+ VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
+
+ Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
+ Ipv6FamilyBuilder ipv6vpnBuilder = new Ipv6FamilyBuilder().setVpnTargets(vpnTargets);
+
+ if (rd != null && !rd.isEmpty()) {
+ ipv4vpnBuilder.setRouteDistinguisher(rd);
+ ipv6vpnBuilder.setRouteDistinguisher(rd);
+ }
+
+ if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
+ builder.setIpv4Family(ipv4vpnBuilder.build());
+ }
+ if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) {
+ builder.setIpv6Family(ipv6vpnBuilder.build());
+ }
+ if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.UNDEFINED)) {
+ builder.setIpv4Family(ipv4vpnBuilder.build());
+ }
+ VpnInstance newVpn = builder.build();
+ LOG.debug("Creating/Updating vpn-instance for {} ", vpnName);
+ InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+ tx.put(LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
+ }
+
+ static void deleteVpnInstance(String vpnName, WriteTransaction wrtConfigTxn) {
+ LOG.debug("Deleting vpn-instance for {} ", vpnName);
+ InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+ wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+ }
+
+ static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
+ InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).child(VpnInterface
+ .class, new VpnInterfaceKey(ifName)).build();
+ return id;
+ }
+
+ public static void createVpnInterface(String vpnName, Pods pod, String interfaceName, String macAddress,
+ boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
+ LOG.trace("createVpnInterface for Port: {}, isRouterInterface: {}", interfaceName, isRouterInterface);
+ List<VpnInstanceNames> listVpn = new ArrayList<>();
+ listVpn.add(new VpnInstanceNamesBuilder().setKey(new VpnInstanceNamesKey(vpnName))
+ .setVpnName(vpnName).setAssociatedSubnetType(VpnInstanceNames.AssociatedSubnetType
+ .V4Subnet).build());
+ VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(interfaceName))
+ .setName(interfaceName)
+ .setVpnInstanceNames(listVpn)
+ .setRouterInterface(isRouterInterface);
+ Adjacencies adjs = createPortIpAdjacencies(pod, interfaceName, macAddress, isRouterInterface);
+ if (adjs != null) {
+ vpnb.addAugmentation(Adjacencies.class, adjs);
+ }
+ VpnInterface vpnIf = vpnb.build();
+ LOG.info("Creating vpn interface {}", vpnIf);
+ InstanceIdentifier<VpnInterface> vpnIfIdentifier = buildVpnInterfaceIdentifier(interfaceName);
+ wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
+
+ }
+
+ public static void deleteVpnInterface(String interfaceName, WriteTransaction wrtConfigTxn) {
+ LOG.trace("deleteVpnInterface for Pod {}", interfaceName);
+ InstanceIdentifier<VpnInterface> vpnIfIdentifier = buildVpnInterfaceIdentifier(interfaceName);
+ wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
+ }
+
+ static Adjacencies createPortIpAdjacencies(Pods pod, String interfaceName, String macAddress,
+ Boolean isRouterInterface) {
+ List<Adjacency> adjList = new ArrayList<>();
+ LOG.trace("create config adjacencies for Port: {}", interfaceName);
+ IpAddress ip = pod.getInterface().get(0).getIpAddress();
+ String ipValue = ip.getIpv4Address() != null ? ip.getIpv4Address().getValue() : ip.getIpv6Address().getValue();
+ String ipPrefix = ip.getIpv4Address() != null ? ipValue + "/32" : ipValue + "/128";
+ String hostIp = new String(pod.getHostIpAddress().getValue());
+ UUID subnetId = UUID.nameUUIDFromBytes(hostIp.getBytes(StandardCharsets.UTF_8));
+ String gatewayIP = ipValue.replaceFirst("\\d+$", "1");
+ Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
+ .setMacAddress(macAddress).setAdjacencyType(Adjacency.AdjacencyType.PrimaryAdjacency)
+ .setSubnetId(new Uuid(subnetId.toString())).setSubnetGatewayIp(gatewayIP).build();
+ if (!adjList.contains(vmAdj)) {
+ adjList.add(vmAdj);
+ }
+
+ //if (isRouterInterface) {
+ // TODO
+ // create extraroute Adjacence for each ipValue,
+ // because router can have IPv4 and IPv6 subnet ports, or can have
+ // more that one IPv4 subnet port or more than one IPv6 subnet port
+ //List<Adjacency> erAdjList = getAdjacencyforExtraRoute(vpnId, routeList, ipValue);
+ //if (!erAdjList.isEmpty()) {
+ // adjList.addAll(erAdjList);
+ //}
+ //}
+ return new AdjacenciesBuilder().setAdjacency(adjList).build();
+ }
+
}
interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
<reference id="jobCoordinator"
interface="org.opendaylight.infrautils.jobcoordinator.JobCoordinator" />
+ <reference id="dataTreeEventCallbackRegistrar"
+ interface="org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar"/>
+ <reference id="cacheProvider"
+ interface="org.opendaylight.infrautils.caches.CacheProvider"/>
</blueprint>
leaf label { type uint32; config "false"; } /* optional */
leaf mac_address {type string;} /* optional */
leaf subnet_id {type yang:uuid;} /* optional */
+ leaf subnet_gateway_ip {type string;} /* optional */
leaf subnet_gateway_mac_address {type string; config "false";} /* optional */
leaf vrf-id { type string; config "false"; }
leaf phys-network-func {
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NWUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
import org.slf4j.Logger;
List<Adjacency> value = new ArrayList<>();
for (Adjacency nextHop : nextHops) {
String rd = primaryRd;
- Subnetmap sn = VpnUtil.getSubnetmapFromItsUuid(dataBroker, nextHop.getSubnetId());
- if (!VpnUtil.isSubnetPartOfVpn(sn, vpnName)) {
+ String nexthopIpValue = nextHop.getIpAddress().split("/")[0];
+ if (vpnInstanceOpData.getBgpvpnType() == VpnInstanceOpDataEntry.BgpvpnType.BGPVPNInternet
+ && NWUtil.isIpv4Address(nexthopIpValue)) {
String prefix = nextHop.getIpAddress() == null ? "null" :
VpnUtil.getIpPrefix(nextHop.getIpAddress());
- LOG.debug("processVpnInterfaceAdjacencies: Not Adding prefix {} to interface {}"
- + " as the subnet is not part of vpn {}", prefix, interfaceName, vpnName);
+ LOG.debug("processVpnInterfaceAdjacencies: UnsupportedOperation : Not Adding prefix {} to interface {}"
+ + " as InternetVpn has an IPV4 address {}", prefix, interfaceName, vpnName);
continue;
}
if (nextHop.getAdjacencyType() == AdjacencyType.PrimaryAdjacency) {
VpnUtil.getPrefixToInterface(dpnId, interfaceName, prefix, nextHop.getSubnetId(),
prefixCue), true);
final Uuid subnetId = nextHop.getSubnetId();
- final Optional<String> gatewayIp = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetId);
- if (gatewayIp.isPresent()) {
- gwMac = getMacAddressForSubnetIp(vpnName, interfaceName, gatewayIp.get());
+
+ String gatewayIp = nextHop.getSubnetGatewayIp();
+ if (gatewayIp == null) {
+ Optional<String> gatewayIpOptional = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetId);
+ if (gatewayIpOptional.isPresent()) {
+ gatewayIp = gatewayIpOptional.get();
+ }
+ }
+
+ if (gatewayIp != null) {
+ gwMac = getMacAddressForSubnetIp(vpnName, interfaceName, gatewayIp);
if (gwMac.isPresent()) {
// A valid mac-address is available for this subnet-gateway-ip
// Use this for programming ARP_RESPONDER table here. And save this
// info into vpnInterface operational, so it can used in VrfEntryProcessor
// to populate L3_GW_MAC_TABLE there.
arpResponderHandler.addArpResponderFlow(dpnId, lportTag, interfaceName,
- gatewayIp.get(), gwMac.get());
+ gatewayIp, gwMac.get());
vpnInterfaceSubnetGwMacAddress = gwMac.get();
} else {
// A valid mac-address is not available for this subnet-gateway-ip
VpnUtil.setupGwMacIfExternalVpn(dataBroker, mdsalManager, dpnId, interfaceName,
vpnId, writeInvTxn, NwConstants.ADD_FLOW, gwMac.get());
arpResponderHandler.addArpResponderFlow(dpnId, lportTag, interfaceName,
- gatewayIp.get(), gwMac.get());
+ gatewayIp, gwMac.get());
} else {
LOG.error("processVpnInterfaceAdjacencies: Gateway MAC for subnet ID {} could not be "
+ "obtained, cannot create ARP responder flow for interface name {}, vpnName {}, "
+ "gwIp {}",
- interfaceName, vpnName, gatewayIp.get());
+ interfaceName, vpnName, gatewayIp);
}
}
} else {
VpnUtil.setupGwMacIfExternalVpn(dataBroker, mdsalManager, dpnId, interfaceName,
vpnId, writeInvTxn, NwConstants.DEL_FLOW, gwMac);
}
- arpResponderHandler.removeArpResponderFlow(dpnId, lportTag, interfaceName, subnetId);
+ arpResponderHandler.removeArpResponderFlow(dpnId, lportTag, interfaceName, nextHop.getSubnetGatewayIp(),
+ subnetId);
}
private List<String> getNextHopForNonPrimaryAdjacency(Adjacency nextHop, String vpnName, BigInteger dpnId,
* lport tag of the interface
* @param ifName
* interface to which ARP responder flow to be removed
+ * @param gatewayIp
+ * subnet gateway ip
* @param subnetUuid
* subnet Id of the interface
*/
- public void removeArpResponderFlow(BigInteger dpId, int lportTag, String ifName,
+ public void removeArpResponderFlow(BigInteger dpId, int lportTag, String ifName, String gatewayIp,
Uuid subnetUuid) {
- Optional<String> gwIp = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetUuid);
- if (gwIp.isPresent()) {
+ if (gatewayIp == null) {
+ Optional<String> gwIpOptional = VpnUtil.getVpnSubnetGatewayIp(dataBroker, subnetUuid);
+ if (gwIpOptional.isPresent()) {
+ gatewayIp = gwIpOptional.get();
+ }
+ }
+ if (gatewayIp != null) {
ArpReponderInputBuilder builder = new ArpReponderInputBuilder();
- builder.setDpId(dpId).setInterfaceName(ifName).setSpa(gwIp.get()).setLportTag(lportTag);
+ builder.setDpId(dpId).setInterfaceName(ifName).setSpa(gatewayIp).setLportTag(lportTag);
elanService.removeArpResponderFlow(builder.buildForRemoveFlow());
}
}