summaryrefslogtreecommitdiffstats
path: root/v3po
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-05-11 11:01:08 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-05-13 06:59:33 +0000
commit11395c60f5c204a6c050c5d90c902c4fc5940537 (patch)
treea5d7261a1f187fd9d5b4c87ca06aeaf2bf734795 /v3po
parent65e93b3426fcc61ee821c3674b51f8365721abeb (diff)
HONEYCOMG-37 Enable ipv6 addresses for vxlan-tunnels
+ Add logging to other interface type customizers Change-Id: I177c0af26991c5f421b513f5fd9964ca1c23027e Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po')
-rw-r--r--v3po/api/src/main/yang/v3po.yang16
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java40
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java10
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java27
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java28
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java104
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java9
7 files changed, 136 insertions, 98 deletions
diff --git a/v3po/api/src/main/yang/v3po.yang b/v3po/api/src/main/yang/v3po.yang
index e346ae144..ca335aa1c 100644
--- a/v3po/api/src/main/yang/v3po.yang
+++ b/v3po/api/src/main/yang/v3po.yang
@@ -191,15 +191,15 @@ module v3po {
when "../if:type = 'v3po:vxlan-tunnel'";
leaf src {
- /* mandatory true; */
- type inet:ipv4-address;
+ /*mandatory true;*/
+ type inet:ip-address;
}
leaf dst {
- /* mandatory true; */
- type inet:ipv4-address;
+ /*mandatory true;*/
+ type inet:ip-address;
}
leaf vni {
- /* mandatory true; */
+ /*mandatory true;*/
type vxlan-vni;
}
leaf encap-vrf-id {
@@ -338,11 +338,13 @@ module v3po {
when "../if:type = 'v3po:vxlan-tunnel'";
leaf src {
- type inet:ipv4-address;
+ type inet:ip-address;
}
leaf dst {
- type inet:ipv4-address;
+ type inet:ip-address;
}
+
+
leaf vni {
type uint32;
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
index b5ef6e010..2034a0301 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+import static com.google.common.base.Preconditions.checkArgument;
+
import com.google.common.base.Optional;
import com.google.common.net.InetAddresses;
import io.fd.honeycomb.v3po.translate.Context;
@@ -28,6 +30,7 @@ import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
import java.net.InetAddress;
import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
+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.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
@@ -94,15 +97,17 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
}
private void createVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
- final InetAddress srcAddress = InetAddresses.forString(vxlan.getSrc().getValue());
- final InetAddress dstAddress = InetAddresses.forString(vxlan.getDst().getValue());
+ final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0);
+ final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc()));
+ final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst()));
+
int encapVrfId = vxlan.getEncapVrfId().intValue();
int vni = vxlan.getVni().getValue().intValue();
LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan);
final CompletionStage<VxlanAddDelTunnelReply> vxlanAddDelTunnelReplyCompletionStage =
getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 1 /* is add */, srcAddress.getAddress(),
- dstAddress.getAddress(), encapVrfId, -1, vni, (byte) 0 /* is IPV6 */));
+ dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6));
final VxlanAddDelTunnelReply reply =
V3poUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture());
@@ -116,16 +121,36 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
}
}
+ private boolean isIpv6(final Vxlan vxlan) {
+ if (vxlan.getSrc().getIpv4Address() == null) {
+ checkArgument(vxlan.getDst().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(),
+ vxlan.getDst());
+ return true;
+ } else {
+ checkArgument(vxlan.getDst().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", vxlan.getSrc(),
+ vxlan.getDst());
+ return false;
+ }
+ }
+
+ private String getAddressString(final IpAddress addr) {
+ return addr.getIpv4Address() == null
+ ? addr.getIpv6Address().getValue()
+ : addr.getIpv4Address().getValue();
+ }
+
private void deleteVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
- final InetAddress srcAddress = InetAddresses.forString(vxlan.getSrc().getValue());
- final InetAddress dstAddress = InetAddresses.forString(vxlan.getDst().getValue());
+ final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0);
+ final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc()));
+ final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst()));
+
int encapVrfId = vxlan.getEncapVrfId().intValue();
int vni = vxlan.getVni().getValue().intValue();
LOG.debug("Deleting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan);
final CompletionStage<VxlanAddDelTunnelReply> vxlanAddDelTunnelReplyCompletionStage =
getFutureJVpp().vxlanAddDelTunnel(getVxlanTunnelRequest((byte) 0 /* is add */, srcAddress.getAddress(),
- dstAddress.getAddress(), encapVrfId, -1, vni, (byte) 0 /* is IPV6 */));
+ dstAddress.getAddress(), encapVrfId, -1, vni, isIpv6));
final VxlanAddDelTunnelReply reply =
V3poUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture());
@@ -139,8 +164,7 @@ public class VxlanCustomizer extends FutureJVppCustomizer implements ChildWriter
}
}
-
- private VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr,
+ private static VxlanAddDelTunnel getVxlanTunnelRequest(final byte isAdd, final byte[] srcAddr, final byte[] dstAddr,
final int encapVrfId,
final int decapNextIndex, final int vni, final byte isIpv6) {
final VxlanAddDelTunnel vxlanAddDelTunnel = new VxlanAddDelTunnel();
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
index 3db497a5c..036018e88 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
@@ -16,8 +16,11 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
+import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import java.math.BigInteger;
import java.util.Map;
@@ -204,4 +207,11 @@ public final class InterfaceUtils {
return EthernetCsmacd.class;
}
+
+ static boolean isInterfaceOfType(final Context ctx, final int index,
+ final Class<? extends InterfaceType> ifcType) {
+ final SwInterfaceDetails cachedDetails = checkNotNull(InterfaceCustomizer.getCachedInterfaceDump(ctx).get(index),
+ "Interface {} cannot be found in context", index);
+ return ifcType.equals(getInterfaceType(V3poUtils.toString(cachedDetails.interfaceName)));
+ }
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
index 1245f6a53..e7cd560bb 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
+
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
@@ -51,22 +53,19 @@ public class TapCustomizer extends FutureJVppCustomizer
public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds";
private NamingContext interfaceContext;
- public TapCustomizer(@Nonnull final FutureJVpp jvpp,
- final NamingContext interfaceContext) {
+ public TapCustomizer(@Nonnull final FutureJVpp jvpp, @Nonnull final NamingContext interfaceContext) {
super(jvpp);
this.interfaceContext = interfaceContext;
}
@Override
- public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
- @Nonnull Tap readValue) {
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull Tap readValue) {
((VppInterfaceStateAugmentationBuilder) parentBuilder).setTap(readValue);
}
@Nonnull
@Override
- public TapBuilder getBuilder(
- @Nonnull InstanceIdentifier<Tap> id) {
+ public TapBuilder getBuilder(@Nonnull InstanceIdentifier<Tap> id) {
return new TapBuilder();
}
@@ -75,8 +74,14 @@ public class TapCustomizer extends FutureJVppCustomizer
@Nonnull final TapBuilder builder,
@Nonnull final Context ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
+ // Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
+ // to fill in the context with initial ifc mapping
+ final int index = interfaceContext.getIndex(key.getName());
+ if (!isInterfaceOfType(ctx, index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class)) {
+ return;
+ }
- // TODO add logging
+ LOG.debug("Reading attributes for tap interface: {}", key.getName());
@SuppressWarnings("unchecked")
Map<Integer, SwInterfaceTapDetails> mappedTaps =
@@ -102,14 +107,10 @@ public class TapCustomizer extends FutureJVppCustomizer
ctx.put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps);
}
- // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index);
- if(swInterfaceTapDetails == null) {
- // Not a Tap interface type
- return;
- }
+ LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails);
builder.setTapName(V3poUtils.toString(swInterfaceTapDetails.devName));
+ LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
index 4b9c7c8bc..70a6da1cc 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
+
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
@@ -53,22 +55,19 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds";
private NamingContext interfaceContext;
- public VhostUserCustomizer(@Nonnull final FutureJVpp jvpp,
- final NamingContext interfaceContext) {
+ public VhostUserCustomizer(@Nonnull final FutureJVpp jvpp, @Nonnull final NamingContext interfaceContext) {
super(jvpp);
this.interfaceContext = interfaceContext;
}
@Override
- public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
- @Nonnull VhostUser readValue) {
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull VhostUser readValue) {
((VppInterfaceStateAugmentationBuilder) parentBuilder).setVhostUser(readValue);
}
@Nonnull
@Override
- public VhostUserBuilder getBuilder(
- @Nonnull InstanceIdentifier<VhostUser> id) {
+ public VhostUserBuilder getBuilder(@Nonnull InstanceIdentifier<VhostUser> id) {
return new VhostUserBuilder();
}
@@ -77,6 +76,14 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
@Nonnull final VhostUserBuilder builder,
@Nonnull final Context ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
+ // Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
+ // to fill in the context with initial ifc mapping
+ final int index = interfaceContext.getIndex(key.getName());
+ if (!isInterfaceOfType(ctx, index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for vhpost user interface: {}", key.getName());
@SuppressWarnings("unchecked")
Map<Integer, SwInterfaceVhostUserDetails> mappedVhostUsers =
@@ -103,12 +110,8 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
}
// Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = mappedVhostUsers.get(index);
- if(swInterfaceVhostUserDetails == null) {
- // Not a VhostUser interface type
- return;
- }
+ LOG.trace("Vhost user interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceVhostUserDetails);
builder.setRole(swInterfaceVhostUserDetails.isServer == 1 ? VhostUserRole.Server : VhostUserRole.Client);
builder.setFeatures(BigInteger.valueOf(swInterfaceVhostUserDetails.features));
@@ -116,6 +119,7 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
builder.setSocket(V3poUtils.toString(swInterfaceVhostUserDetails.sockFilename));
builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz);
builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno));
- // TODO add logging
+
+ LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
index 18bf01d6c..829416034 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static com.google.common.base.Preconditions.checkState;
+
import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
@@ -25,16 +27,15 @@ import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import java.util.concurrent.CompletionStage;
-import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+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.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Vxlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanBuilder;
import org.opendaylight.yangtools.concepts.Builder;
@@ -47,16 +48,13 @@ import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class VxlanCustomizer extends FutureJVppCustomizer
implements ChildReaderCustomizer<Vxlan, VxlanBuilder> {
private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
- public static final String DUMPED_VXLANS_CONTEXT_KEY = VxlanCustomizer.class.getName() + "dumpedVxlansDuringGetAllIds";
private NamingContext interfaceContext;
- public VxlanCustomizer(@Nonnull final FutureJVpp jvpp,
- final NamingContext interfaceContext) {
+ public VxlanCustomizer(@Nonnull final FutureJVpp jvpp, @Nonnull final NamingContext interfaceContext) {
super(jvpp);
this.interfaceContext = interfaceContext;
}
@@ -69,8 +67,7 @@ public class VxlanCustomizer extends FutureJVppCustomizer
@Nonnull
@Override
- public VxlanBuilder getBuilder(
- @Nonnull InstanceIdentifier<Vxlan> id) {
+ public VxlanBuilder getBuilder(@Nonnull InstanceIdentifier<Vxlan> id) {
return new VxlanBuilder();
}
@@ -79,61 +76,60 @@ public class VxlanCustomizer extends FutureJVppCustomizer
@Nonnull final VxlanBuilder builder,
@Nonnull final Context ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
-
- // TODO add logging
-
- // FIXME this should take different approach than Tap or Vhost customizers since vxlan dump allows
- // to specify interface index, making it possible to dump just a single interface
- // However we need to determine the type of current interface somehow to know it is vxlan type and we can perform
- // the dump (InterfaceCustomizer can store the type in ctx)
-
- @SuppressWarnings("unchecked")
- Map<Integer, VxlanTunnelDetails> mappedVxlans =
- (Map<Integer, VxlanTunnelDetails>) ctx.get(DUMPED_VXLANS_CONTEXT_KEY);
-
- if(mappedVxlans == null) {
- // Full Vxlan dump has to be performed here, no filter or anything is here to help so at least we cache it
- final VxlanTunnelDump request = new VxlanTunnelDump();
- request.swIfIndex = -1;
-
- final CompletionStage<VxlanTunnelDetailsReplyDump> swInterfaceVxlanDetailsReplyDumpCompletionStage =
- getFutureJVpp().vxlanTunnelDump(request);
- final VxlanTunnelDetailsReplyDump reply =
- V3poUtils.getReply(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture());
-
- if(null == reply || null == reply.vxlanTunnelDetails) {
- mappedVxlans = Collections.emptyMap();
- } else {
- final List<VxlanTunnelDetails> swInterfaceVxlanDetails = reply.vxlanTunnelDetails;
- // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes
- mappedVxlans = swInterfaceVxlanDetails.stream()
- .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails));
- }
-
- ctx.put(DUMPED_VXLANS_CONTEXT_KEY, mappedVxlans);
+ // Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
+ // to fill in the context with initial ifc mapping
+ final int index = interfaceContext.getIndex(key.getName());
+ if (!InterfaceUtils.isInterfaceOfType(ctx, index, VxlanTunnel.class)) {
+ return;
}
- // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
- final VxlanTunnelDetails swInterfaceVxlanDetails = mappedVxlans.get(index);
- if(swInterfaceVxlanDetails == null) {
- // Not a Vxlan interface type
+ LOG.debug("Reading attributes for vxlan tunnel: {}", key.getName());
+ // Dump just a single
+ final VxlanTunnelDump request = new VxlanTunnelDump();
+ request.swIfIndex = index;
+
+ final CompletionStage<VxlanTunnelDetailsReplyDump> swInterfaceVxlanDetailsReplyDumpCompletionStage =
+ getFutureJVpp().vxlanTunnelDump(request);
+ final VxlanTunnelDetailsReplyDump reply =
+ V3poUtils.getReply(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture());
+
+ // VPP keeps vxlan tunnel interfaces even after they were deleted (optimization)
+ // However there ar no longer any vxlan tunnel specific fields assigned to it and this call
+ // returns nothing
+ if (reply == null || reply.vxlanTunnelDetails == null || reply.vxlanTunnelDetails.isEmpty()) {
+ LOG.debug(
+ "Vxlan tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" +
+ "after delete", key.getName(), index);
return;
}
- if(swInterfaceVxlanDetails.isIpv6 == 1) {
- // FIXME enable ipv6 in the vxlan model
-// builder.setDst(new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress()));
-// builder.setSrc(new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress()));
+ checkState(reply.vxlanTunnelDetails.size() == 1,
+ "Unexpected number of returned vxlan tunnels: {} for tunnel: {}", reply.vxlanTunnelDetails, key.getName());
+ LOG.trace("Vxlan tunnel: {} attributes returned from VPP: {}", key.getName(), reply);
+
+ final VxlanTunnelDetails swInterfaceVxlanDetails = reply.vxlanTunnelDetails.get(0);
+ if (swInterfaceVxlanDetails.isIpv6 == 1) {
+ final Ipv6Address dstIpv6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress());
+ builder.setDst(new IpAddress(dstIpv6));
+ final Ipv6Address srcIpv6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress());
+ builder.setSrc(new IpAddress(srcIpv6));
} else {
- builder.setDst(new Ipv4Address(parseAddress(Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4)).getHostAddress()));
- builder.setSrc(new Ipv4Address(parseAddress(Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4)).getHostAddress()));
+ final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4);
+ final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress());
+ builder.setDst(new IpAddress(dstIpv4));
+ final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4);
+ final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress());
+ builder.setSrc(new IpAddress(srcIpv4));
}
builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId);
builder.setVni((long) swInterfaceVxlanDetails.vni);
+ LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
}
- private InetAddress parseAddress(final byte[] addr) {
+ @Nonnull
+ private static InetAddress parseAddress(@Nonnull final byte[] addr) {
try {
return InetAddress.getByAddress(addr);
} catch (UnknownHostException e) {
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
index 2f1a9e606..a599d7565 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
@@ -40,6 +40,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+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.inet.types.rev130715.Ipv4Address;
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;
@@ -104,8 +105,8 @@ public class VxlanCustomizerTest {
final VxlanAddDelTunnel actual = argumentCaptor.getValue();
assertEquals(0, actual.isIpv6);
assertEquals(-1, actual.decapNextIndex);
- assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getValue()).getAddress(), actual.srcAddress);
- assertArrayEquals(InetAddresses.forString(vxlan.getDst().getValue()).getAddress(), actual.dstAddress);
+ assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getIpv4Address().getValue()).getAddress(), actual.srcAddress);
+ assertArrayEquals(InetAddresses.forString(vxlan.getDst().getIpv4Address().getValue()).getAddress(), actual.dstAddress);
assertEquals(vxlan.getEncapVrfId().intValue(), actual.encapVrfId);
assertEquals(vxlan.getVni().getValue().intValue(), actual.vni);
return actual;
@@ -122,8 +123,8 @@ public class VxlanCustomizerTest {
private static Vxlan generateVxlan(long vni) {
final VxlanBuilder builder = new VxlanBuilder();
- builder.setSrc(new Ipv4Address("192.168.20.10"));
- builder.setDst(new Ipv4Address("192.168.20.11"));
+ builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10")));
+ builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11")));
builder.setEncapVrfId(Long.valueOf(123));
builder.setVni(new VxlanVni(Long.valueOf(vni)));
return builder.build();