summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io
diff options
context:
space:
mode:
authorHongjun Ni <hongjun.ni@intel.com>2016-06-01 01:23:46 +0800
committerHongjun Ni <hongjun.ni@intel.com>2016-06-02 00:56:11 +0800
commitf1da426ffcd61fc4b498dfa4192c0cde19b552e2 (patch)
tree7b4ff29f06d67e3fa91162aa10c4477cb46dfeff /v3po/v3po2vpp/src/main/java/io
parente78326418cc149f7c90827b3d0be49eaeca54dae (diff)
HONEYCOMB-71: Add VxLAN-GPE feature
Patchset 3: Add Vxlan-gpe requests in postman_rest_collection.json Patchset 2: Fix the indent issue. Change-Id: If42b667f60a3591efc4b79353d78935277f8fb4d Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io')
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java19
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java191
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java141
3 files changed, 351 insertions, 0 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java
index 3571fbc90..38ab58af1 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java
@@ -31,18 +31,21 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeVni;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.EthernetBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.SubInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.TapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Ethernet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Tap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VhostUser;
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.VxlanGpe;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.Interconnection;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.VlanTagRewrite;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.attributes.VlanTagRewriteBuilder;
@@ -99,6 +102,11 @@ public class InterfacesInitializer extends AbstractDataTreeConverter<InterfacesS
setVxlan(augmentBuilder, vxlan);
}
+ final VxlanGpe vxlanGpe = vppIfcAugmentation.getVxlanGpe();
+ if(vxlanGpe != null) {
+ setVxlanGpe(augmentBuilder, vxlanGpe);
+ }
+
final Tap tap = vppIfcAugmentation.getTap();
if(tap != null) {
setTap(input, augmentBuilder, tap);
@@ -224,4 +232,15 @@ public class InterfacesInitializer extends AbstractDataTreeConverter<InterfacesS
vxlanBuilder.setVni(new VxlanVni(vxlan.getVni()));
augmentBuilder.setVxlan(vxlanBuilder.build());
}
+
+ private static void setVxlanGpe(final VppInterfaceAugmentationBuilder augmentBuilder, final VxlanGpe vxlanGpe) {
+ final VxlanGpeBuilder vxlanGpeBuilder = new VxlanGpeBuilder();
+ vxlanGpeBuilder.setLocal(vxlanGpe.getLocal());
+ vxlanGpeBuilder.setRemote(vxlanGpe.getRemote());
+ vxlanGpeBuilder.setVni(new VxlanGpeVni(vxlanGpe.getVni()));
+ vxlanGpeBuilder.setNextProtocol(vxlanGpe.getNextProtocol());
+ vxlanGpeBuilder.setEncapVrfId(vxlanGpe.getEncapVrfId());
+ vxlanGpeBuilder.setDecapVrfId(vxlanGpe.getDecapVrfId());
+ augmentBuilder.setVxlanGpe(vxlanGpeBuilder.build());
+ }
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java
new file mode 100644
index 000000000..7d9641122
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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.v3po.util.AbstractInterfaceTypeCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
+import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+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.InterfaceType;
+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.VxlanGpeTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpe;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnel;
+import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnelReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// TODO extract common code from all Interface type specific writer customizers into a superclass
+public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class);
+ private final NamingContext interfaceContext;
+
+ public VxlanGpeCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
+ super(vppApi);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Nonnull
+ @Override
+ public Optional<VxlanGpe> extract(@Nonnull final InstanceIdentifier<VxlanGpe> currentId,
+ @Nonnull final DataObject parentData) {
+ return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getVxlanGpe());
+ }
+
+ @Override
+ protected Class<? extends InterfaceType> getExpectedInterfaceType() {
+ return VxlanGpeTunnel.class;
+ }
+
+ @Override
+ protected final void writeInterface(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataAfter,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException.CreateFailedException {
+ try {
+ createVxlanGpeTunnel(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
+ } catch (VppApiInvocationException | IllegalInterfaceTypeException e) {
+ LOG.warn("Write of VxlanGpe failed", e);
+ throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
+ }
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataBefore,
+ @Nonnull final VxlanGpe dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException.UpdateFailedException {
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter,
+ new UnsupportedOperationException("VxlanGpe tunnel update is not supported"));
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe dataBefore,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException.DeleteFailedException {
+ try {
+ deleteVxlanGpeTunnel(id.firstKeyOf(Interface.class).getName(), dataBefore, writeContext);
+ } catch (VppApiInvocationException e) {
+ LOG.warn("Delete of VxlanGpe tunnel failed", e);
+ throw new WriteFailedException.DeleteFailedException(id, e);
+ }
+ }
+
+ private void createVxlanGpeTunnel(final String swIfName, final VxlanGpe VxlanGpe, final WriteContext writeContext) throws VppApiInvocationException {
+ final byte isIpv6 = (byte) (isIpv6(VxlanGpe) ? 1 : 0);
+ final InetAddress Local = InetAddresses.forString(getAddressString(VxlanGpe.getLocal()));
+ final InetAddress Remote = InetAddresses.forString(getAddressString(VxlanGpe.getRemote()));
+
+ int vni = VxlanGpe.getVni().getValue().intValue();
+ byte protocol = (byte) VxlanGpe.getNextProtocol().getIntValue();
+ int encapVrfId = VxlanGpe.getEncapVrfId().intValue();
+ int decapVrfId = VxlanGpe.getDecapVrfId().intValue();
+
+ LOG.debug("Setting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, VxlanGpe);
+ final CompletionStage<VxlanGpeAddDelTunnelReply> VxlanGpeAddDelTunnelReplyCompletionStage =
+ getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, Local.getAddress(),
+ Remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6));
+
+ final VxlanGpeAddDelTunnelReply reply =
+ TranslateUtils.getReply(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.debug("Failed to set VxlanGpe tunnel for interface: {}, VxlanGpe: {}", swIfName, VxlanGpe);
+ throw new VppApiInvocationException("VxlanGpeAddDelTunnel", reply.context, reply.retval);
+ } else {
+ LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe);
+ if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) {
+ final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext());
+ LOG.debug("Removing updated mapping of a vxlan-gpe tunnel, id: {}, former name: {}, new name: {}",
+ reply.swIfIndex, formerName, swIfName);
+ interfaceContext.removeName(formerName, writeContext.getMappingContext());
+ }
+ // Add new interface to our interface context
+ interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
+ }
+ }
+
+ private boolean isIpv6(final VxlanGpe VxlanGpe) {
+ if (VxlanGpe.getLocal().getIpv4Address() == null) {
+ checkArgument(VxlanGpe.getRemote().getIpv4Address() == null, "Inconsistent ip addresses: %s, %s", VxlanGpe.getLocal(),
+ VxlanGpe.getRemote());
+ return true;
+ } else {
+ checkArgument(VxlanGpe.getRemote().getIpv6Address() == null, "Inconsistent ip addresses: %s, %s", VxlanGpe.getLocal(),
+ VxlanGpe.getRemote());
+ return false;
+ }
+ }
+
+ private String getAddressString(final IpAddress addr) {
+ return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue();
+ }
+
+ private void deleteVxlanGpeTunnel(final String swIfName, final VxlanGpe VxlanGpe, final WriteContext writeContext) throws VppApiInvocationException {
+ final byte isIpv6 = (byte) (isIpv6(VxlanGpe) ? 1 : 0);
+ final InetAddress local = InetAddresses.forString(getAddressString(VxlanGpe.getLocal()));
+ final InetAddress remote = InetAddresses.forString(getAddressString(VxlanGpe.getRemote()));
+
+ int vni = VxlanGpe.getVni().getValue().intValue();
+ byte protocol = (byte) VxlanGpe.getNextProtocol().getIntValue();
+ int encapVrfId = VxlanGpe.getEncapVrfId().intValue();
+ int decapVrfId = VxlanGpe.getDecapVrfId().intValue();
+
+ LOG.debug("Deleting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, VxlanGpe);
+ final CompletionStage<VxlanGpeAddDelTunnelReply> VxlanGpeAddDelTunnelReplyCompletionStage =
+ getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 0 /* is delete */, local.getAddress(),
+ remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6));
+
+ final VxlanGpeAddDelTunnelReply reply =
+ TranslateUtils.getReply(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.debug("Failed to delete VxlanGpe tunnel for interface: {}, VxlanGpe: {}", swIfName, VxlanGpe);
+ throw new VppApiInvocationException("VxlanGpeAddDelTunnel", reply.context, reply.retval);
+ } else {
+ LOG.debug("VxlanGpe tunnel deleted successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe);
+ // Remove interface from our interface context
+ interfaceContext.removeName(swIfName, writeContext.getMappingContext());
+ }
+ }
+
+ private static VxlanGpeAddDelTunnel getVxlanGpeTunnelRequest(final byte isAdd, final byte[] local, final byte[] remote,
+ final int vni, final byte protocol, final int encapVrfId, final int decapVrfId,
+ final byte isIpv6) {
+ final VxlanGpeAddDelTunnel VxlanGpeAddDelTunnel = new VxlanGpeAddDelTunnel();
+ VxlanGpeAddDelTunnel.isAdd = isAdd;
+ VxlanGpeAddDelTunnel.local = local;
+ VxlanGpeAddDelTunnel.remote = remote;
+ VxlanGpeAddDelTunnel.vni = vni;
+ VxlanGpeAddDelTunnel.protocol = protocol;
+ VxlanGpeAddDelTunnel.encapVrfId = encapVrfId;
+ VxlanGpeAddDelTunnel.decapVrfId = decapVrfId;
+ VxlanGpeAddDelTunnel.isIpv6 = isIpv6;
+ return VxlanGpeAddDelTunnel;
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java
new file mode 100644
index 000000000..64a5b895a
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+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.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.VxlanGpeTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpeBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.VxlanGpeTunnelDetails;
+import org.openvpp.jvpp.dto.VxlanGpeTunnelDetailsReplyDump;
+import org.openvpp.jvpp.dto.VxlanGpeTunnelDump;
+import org.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VxlanGpeCustomizer extends FutureJVppCustomizer
+ implements ChildReaderCustomizer<VxlanGpe, VxlanGpeBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class);
+ private NamingContext interfaceContext;
+
+ public VxlanGpeCustomizer(@Nonnull final FutureJVpp jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull VxlanGpe readValue) {
+ ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlanGpe(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public VxlanGpeBuilder getBuilder(@Nonnull InstanceIdentifier<VxlanGpe> id) {
+ return new VxlanGpeBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VxlanGpe> id,
+ @Nonnull final VxlanGpeBuilder builder,
+ @Nonnull final ReadContext 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(), ctx.getMappingContext());
+ if (!InterfaceUtils.isInterfaceOfType(ctx.getModificationCache(), index, VxlanGpeTunnel.class)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for VxlanGpe tunnel: {}", key.getName());
+ // Dump just a single
+ final VxlanGpeTunnelDump request = new VxlanGpeTunnelDump();
+ request.swIfIndex = index;
+
+ final CompletionStage<VxlanGpeTunnelDetailsReplyDump> swInterfaceVxlanGpeDetailsReplyDumpCompletionStage =
+ getFutureJVpp().vxlanGpeTunnelDump(request);
+ final VxlanGpeTunnelDetailsReplyDump reply =
+ TranslateUtils.getReply(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture());
+
+ // VPP keeps VxlanGpe tunnel interfaces even after they were deleted (optimization)
+ // However there are no longer any VxlanGpe tunnel specific fields assigned to it and this call
+ // returns nothing
+ if (reply == null || reply.vxlanGpeTunnelDetails == null || reply.vxlanGpeTunnelDetails.isEmpty()) {
+ LOG.debug(
+ "VxlanGpe tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" +
+ "after delete", key.getName(), index);
+ return;
+ }
+
+ checkState(reply.vxlanGpeTunnelDetails.size() == 1,
+ "Unexpected number of returned VxlanGpe tunnels: {} for tunnel: {}", reply.vxlanGpeTunnelDetails, key.getName());
+ LOG.trace("VxlanGpe tunnel: {} attributes returned from VPP: {}", key.getName(), reply);
+
+ final VxlanGpeTunnelDetails swInterfaceVxlanGpeDetails = reply.vxlanGpeTunnelDetails.get(0);
+ if (swInterfaceVxlanGpeDetails.isIpv6 == 1) {
+ final Ipv6Address remote6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress());
+ builder.setRemote(new IpAddress(remote6));
+ final Ipv6Address local6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress());
+ builder.setLocal(new IpAddress(local6));
+ } else {
+ final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4);
+ final Ipv4Address remote4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress());
+ builder.setRemote(new IpAddress(remote4));
+ final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.local, 0, 4);
+ final Ipv4Address local4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress());
+ builder.setLocal(new IpAddress(local4));
+ }
+ builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni));
+ builder.setEncapVrfId((long) swInterfaceVxlanGpeDetails.encapVrfId);
+ builder.setDecapVrfId((long) swInterfaceVxlanGpeDetails.decapVrfId);
+ LOG.debug("VxlanGpe tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Nonnull
+ private static InetAddress parseAddress(@Nonnull final byte[] addr) {
+ try {
+ return InetAddress.getByAddress(addr);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e);
+ }
+ }
+}