summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read')
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/AfPacketCustomizer.java136
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/EthernetCustomizer.java105
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/GreCustomizer.java147
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterconnectionReadUtils.java129
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceCustomizer.java173
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceDataTranslator.java203
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceRoutingCustomizer.java88
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceStatisticsCustomizer.java124
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/L2Customizer.java119
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RewriteCustomizer.java142
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RoutingCustomizer.java65
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceCustomizer.java243
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceL2Customizer.java119
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceRoutingCustomizer.java70
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/TapV2Customizer.java212
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VhostUserCustomizer.java167
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanCustomizer.java164
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanGpeCustomizer.java155
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManager.java59
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerImpl.java202
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerProvider.java38
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManager.java26
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerImpl.java37
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerProvider.java27
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/pbb/PbbRewriteCustomizer.java57
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/AbstractMirroredInterfacesCustomizer.java114
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/InterfaceMirroredInterfacesCustomizer.java78
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/SubInterfaceMirroredInterfacesCustomizer.java80
28 files changed, 3279 insertions, 0 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/AfPacketCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/AfPacketCustomizer.java
new file mode 100644
index 000000000..0022015ec
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/AfPacketCustomizer.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2018 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.hc2vpp.v3po.read;
+
+import static java.lang.String.format;
+
+import com.google.common.annotations.VisibleForTesting;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.StaticCacheKeyFactory;
+import io.fd.jvpp.core.dto.AfPacketDetails;
+import io.fd.jvpp.core.dto.AfPacketDetailsReplyDump;
+import io.fd.jvpp.core.dto.AfPacketDump;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacket;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacketBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AfPacketCustomizer implements InitializingReaderCustomizer<AfPacket, AfPacketBuilder>,
+ InterfaceDataTranslator, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AfPacketCustomizer.class);
+ private NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+ private final DumpCacheManager<AfPacketDetailsReplyDump, Void> afPacketDumpManager;
+
+ public AfPacketCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ this.interfaceContext = interfaceContext;
+ this.dumpManager = dumpManager;
+ this.afPacketDumpManager =
+ new DumpCacheManager.DumpCacheManagerBuilder<AfPacketDetailsReplyDump, Void>()
+ .withCacheKeyFactory(new StaticCacheKeyFactory(AfPacketCustomizer.class.getName() + "_dump",
+ AfPacketDetailsReplyDump.class))
+ .withExecutor((identifier, params) -> {
+ final CompletionStage<AfPacketDetailsReplyDump> cs = jvpp.afPacketDump(new AfPacketDump());
+ return getReplyForRead(cs.toCompletableFuture(), identifier);
+ }).build();
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull AfPacket readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setAfPacket(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public AfPacketBuilder getBuilder(@Nonnull InstanceIdentifier<AfPacket> id) {
+ return new AfPacketBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<AfPacket> id,
+ @Nonnull final AfPacketBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ final SwInterfaceDetails ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName());
+
+ if (!isInterfaceOfType(
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.AfPacket.class,
+ ifcDetails)) {
+ return;
+ }
+
+ final AfPacketDetailsReplyDump dump = afPacketDumpManager.getDump(id, ctx.getModificationCache())
+ .orElse(new AfPacketDetailsReplyDump());
+ // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
+ final AfPacketDetails afPacketDetails = dump.afPacketDetails.stream()
+ .filter(detail -> detail.swIfIndex == index)
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException(format("AfPacket interface %s not found", key.getName())));
+ LOG.trace("AfPacket interface: {} attributes returned from VPP: {}", key.getName(), afPacketDetails);
+
+ builder.setMac(new PhysAddress(vppPhysAddrToYang(ifcDetails.l2Address)));
+ builder.setHostInterfaceName(toString(afPacketDetails.hostIfName));
+
+ LOG.debug("AfPacket interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacket> init(
+ @Nonnull final InstanceIdentifier<AfPacket> id,
+ @Nonnull final AfPacket readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacketBuilder()
+ .setHostInterfaceName(readValue.getHostInterfaceName())
+ .setMac(readValue.getMac())
+ .build());
+ }
+
+ @VisibleForTesting
+ static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacket> getCfgId(
+ final InstanceIdentifier<AfPacket> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.AfPacket.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/EthernetCustomizer.java
new file mode 100644
index 000000000..bdad55b21
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/EthernetCustomizer.java
@@ -0,0 +1,105 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Ethernet;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.EthernetBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+
+public class EthernetCustomizer
+ implements InitializingReaderCustomizer<Ethernet, EthernetBuilder>, InterfaceDataTranslator {
+
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public EthernetCustomizer(@Nonnull final InterfaceCacheDumpManager dumpManager) {
+ this.dumpManager = dumpManager;
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
+ @Nonnull final Ethernet readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setEthernet(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public EthernetBuilder getBuilder(@Nonnull InstanceIdentifier<Ethernet> id) {
+ return new EthernetBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id,
+ @Nonnull final EthernetBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, key.getName());
+
+ if (iface.linkMtu != 0) {
+ // Read physical payload MTU (link_mtu) if given.
+ // VPP since 18.07 supports also setting MTUs for software interfaces,
+ // but these are not supported by HC (TODO: HC2VPP-355).
+ // More details:
+ // https://git.fd.io/vpp/tree/src/vnet/MTU.md
+ builder.setMtu((int) iface.linkMtu);
+ }
+
+ switch (iface.linkDuplex) {
+ case 1:
+ builder.setDuplex(Ethernet.Duplex.Half);
+ break;
+ case 2:
+ builder.setDuplex(Ethernet.Duplex.Full);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Ethernet> init(
+ @Nonnull final InstanceIdentifier<Ethernet> id,
+ @Nonnull final Ethernet readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.EthernetBuilder()
+ .setMtu(readValue.getMtu())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Ethernet> getCfgId(
+ final InstanceIdentifier<Ethernet> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Ethernet.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/GreCustomizer.java
new file mode 100644
index 000000000..3bb0cbdf8
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/GreCustomizer.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Intel 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.dto.GreTunnelDetails;
+import io.fd.jvpp.core.dto.GreTunnelDetailsReplyDump;
+import io.fd.jvpp.core.dto.GreTunnelDump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.GreTunnel;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Gre;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.GreBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GreCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<Gre, GreBuilder>, InterfaceDataTranslator, Ipv4Translator,
+ Ipv6Translator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class);
+ private final NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public GreCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ this.dumpManager = dumpManager;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull Gre readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setGre(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public GreBuilder getBuilder(@Nonnull InstanceIdentifier<Gre> id) {
+ return new GreBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Gre> id,
+ @Nonnull final GreBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(dumpManager, id, ctx, GreTunnel.class)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for gre tunnel: {}", key.getName());
+ // Dump just a single
+ final GreTunnelDump request = new GreTunnelDump();
+ request.swIfIndex = index;
+
+ final CompletionStage<GreTunnelDetailsReplyDump> swInterfaceGreDetailsReplyDumpCompletionStage =
+ getFutureJVpp().greTunnelDump(request);
+ final GreTunnelDetailsReplyDump reply =
+ getReplyForRead(swInterfaceGreDetailsReplyDumpCompletionStage.toCompletableFuture(), id);
+
+ // VPP keeps gre tunnel interfaces even after they were deleted (optimization)
+ // However there ar no longer any gre tunnel specific fields assigned to it and this call
+ // returns nothing
+ if (reply == null || reply.greTunnelDetails == null || reply.greTunnelDetails.isEmpty()) {
+ LOG.debug(
+ "Gre tunnel {}, id {} has no attributes assigned in VPP. Probably is a leftover interface placeholder" +
+ "after delete", key.getName(), index);
+ return;
+ }
+
+ checkState(reply.greTunnelDetails.size() == 1,
+ "Unexpected number of returned gre tunnels: {} for tunnel: {}", reply.greTunnelDetails,
+ key.getName());
+ LOG.trace("Gre tunnel: {} attributes returned from VPP: {}", key.getName(), reply);
+
+ final GreTunnelDetails swInterfaceGreDetails = reply.greTunnelDetails.get(0);
+ if (swInterfaceGreDetails.tunnel.isIpv6 == 1) {
+ builder.setDst(new IpAddressNoZone(
+ arrayToIpv4AddressNoZone(swInterfaceGreDetails.tunnel.dst.un.getIp6().ip6Address)));
+ builder.setSrc(new IpAddressNoZone(
+ arrayToIpv6AddressNoZone(swInterfaceGreDetails.tunnel.src.un.getIp6().ip6Address)));
+ } else {
+ builder.setDst(new IpAddressNoZone(
+ arrayToIpv4AddressNoZone(swInterfaceGreDetails.tunnel.dst.un.getIp4().ip4Address)));
+ builder.setSrc(new IpAddressNoZone(
+ arrayToIpv4AddressNoZone(swInterfaceGreDetails.tunnel.src.un.getIp4().ip4Address)));
+ }
+ builder.setOuterFibId((long) swInterfaceGreDetails.tunnel.outerFibId);
+ LOG.debug("Gre tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Gre> init(
+ @Nonnull final InstanceIdentifier<Gre> id, @Nonnull final Gre readValue, @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.GreBuilder()
+ .setDst(readValue.getDst())
+ .setSrc(readValue.getSrc())
+ .setOuterFibId(readValue.getOuterFibId())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Gre> getCfgId(
+ final InstanceIdentifier<Gre> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Gre.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterconnectionReadUtils.java
new file mode 100644
index 000000000..ab6072615
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterconnectionReadUtils.java
@@ -0,0 +1,129 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.jvpp.core.dto.BridgeDomainDetails;
+import io.fd.jvpp.core.dto.BridgeDomainDetailsReplyDump;
+import io.fd.jvpp.core.dto.BridgeDomainDump;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import io.fd.jvpp.core.types.BridgeDomainSwIf;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.BridgeBasedBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class providing Interconnection read support.
+ */
+final class InterconnectionReadUtils implements InterfaceDataTranslator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterconnectionReadUtils.class);
+
+ private final NamingContext interfaceContext;
+ private final NamingContext bridgeDomainContext;
+ private final InterfaceCacheDumpManager dumpManager;
+ private final DumpCacheManager<BridgeDomainDetailsReplyDump,Void> bdDumpManager;
+
+ InterconnectionReadUtils(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ requireNonNull(futureJVppCore, "futureJVppCore should not be null");
+ this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null");
+ this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null");
+ this.dumpManager = requireNonNull(dumpManager, "dumpManager should not be null");
+ this.bdDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<BridgeDomainDetailsReplyDump, Void>()
+ .acceptOnly(BridgeDomainDetailsReplyDump.class)
+ .withExecutor((id, params) -> {
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = -1;
+
+ final CompletableFuture<BridgeDomainDetailsReplyDump> bdCompletableFuture =
+ futureJVppCore.bridgeDomainDump(request).toCompletableFuture();
+ return getReplyForRead(bdCompletableFuture, id);
+ })
+ .build();
+ }
+
+ @Nullable
+ Interconnection readInterconnection(@Nonnull final InstanceIdentifier<?> id, @Nonnull final String ifaceName,
+ @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext());
+
+ final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, ifaceName);
+ LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface);
+
+ final BridgeDomainDetailsReplyDump dumpReply = bdDumpManager.getDump(id, ctx.getModificationCache())
+ .orElse(new BridgeDomainDetailsReplyDump());
+ for (final BridgeDomainDetails bd : dumpReply.bridgeDomainDetails) {
+ final Optional<BridgeDomainSwIf> bdIfAssignment = getBridgeDomainSwIf(ifaceId, bd);
+ if (bdIfAssignment.isPresent()) {
+ final BridgeDomainSwIf bridgeDomainSwIf = bdIfAssignment.get();
+ final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder();
+ bbBuilder.setBridgeDomain(bridgeDomainContext.getName(bd.bdId, ctx.getMappingContext()));
+
+ // Set BVI if the bridgeDomainDetails.bviSwIfIndex == current sw if index
+ final Optional<BridgeDomainDetails> bridgeDomainForInterface =
+ getBridgeDomainForInterface(dumpReply, bd.bdId);
+ // Since we already found an interface assigned to a bridge domain, the details for BD must be present
+ checkState(bridgeDomainForInterface.isPresent());
+ if (bridgeDomainForInterface.get().bviSwIfIndex == ifaceId) {
+ bbBuilder.setBridgedVirtualInterface(true);
+ } else {
+ bbBuilder.setBridgedVirtualInterface(false);
+ }
+
+ if (bridgeDomainSwIf.shg != 0) {
+ bbBuilder.setSplitHorizonGroup((short) bridgeDomainSwIf.shg);
+ }
+ return bbBuilder.build();
+ }
+ }
+ // TODO HONEYCOMB-190 is there a way to check if interconnection is XconnectBased?
+
+ return null;
+ }
+
+ private Optional<BridgeDomainSwIf> getBridgeDomainSwIf(final int ifaceId, @Nonnull final BridgeDomainDetails bd) {
+ if (null == bd.swIfDetails) {
+ return Optional.empty();
+ }
+ // interface can be added to only one BD only
+ return Arrays.stream(bd.swIfDetails).filter(el -> el.swIfIndex == ifaceId).findFirst();
+ }
+
+ private Optional<BridgeDomainDetails> getBridgeDomainForInterface(final BridgeDomainDetailsReplyDump reply,
+ int bdId) {
+ return reply.bridgeDomainDetails.stream().filter(a -> a.bdId == bdId).findFirst();
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceCustomizer.java
new file mode 100644
index 000000000..3e0a1dc41
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceCustomizer.java
@@ -0,0 +1,173 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.DisabledInterfacesManager;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.InterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface.AdminStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading ietf-interfaces:interfaces/interface.
+ */
+public class InterfaceCustomizer
+ implements InitializingListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder>, ByteDataTranslator,
+ InterfaceDataTranslator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+ private final NamingContext interfaceNamingContext;
+ private final DisabledInterfacesManager interfaceDisableContext;
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public InterfaceCustomizer(@Nonnull final NamingContext interfaceNamingContext,
+ @Nonnull final DisabledInterfacesManager interfaceDisableContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ this.interfaceNamingContext = interfaceNamingContext;
+ this.interfaceDisableContext = interfaceDisableContext;
+ this.dumpManager = dumpManager;
+ }
+
+ @Nonnull
+ @Override
+ public InterfaceBuilder getBuilder(@Nonnull InstanceIdentifier<Interface> id) {
+ return new InterfaceBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull InstanceIdentifier<Interface> id, @Nonnull InterfaceBuilder builder,
+ @Nonnull ReadContext ctx) throws ReadFailedException {
+ LOG.debug("Reading attributes for interface: {}", id);
+ final String ifaceName = id.firstKeyOf(id.getTargetType()).getName();
+
+ final int index = interfaceNamingContext.getIndex(ifaceName, ctx.getMappingContext());
+
+ // Ignore disabled interface (such as deleted VXLAN tunnels)
+ if (interfaceDisableContext.isInterfaceDisabled(index, ctx.getMappingContext())) {
+ LOG.debug("Skipping disabled interface: {}", id);
+ return;
+ }
+
+ final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, ifaceName);
+ LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface);
+
+ if (!isRegularInterface(iface)) {
+ LOG.debug("Interface: {} is a sub-interface. Ignoring read request.", ifaceName);
+ return;
+ }
+
+ builder.setName(ifaceName);
+ builder.setType(getInterfaceType(new String(iface.interfaceName).intern()));
+ builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex));
+ builder.setAdminStatus(1 == iface.adminUpDown
+ ? AdminStatus.Up
+ : AdminStatus.Down);
+ builder.setOperStatus(1 == iface.linkUpDown
+ ? OperStatus.Up
+ : OperStatus.Down);
+ if (0 != iface.linkSpeed) {
+ builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed));
+ }
+ if (iface.l2AddressLength == 6) {
+ builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address)));
+ }
+ LOG.trace("Base attributes read for interface: {} as: {}", ifaceName, builder);
+ }
+
+ @Nonnull
+ @Override
+ public List<InterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final ReadContext context) throws ReadFailedException {
+ final List<InterfaceKey> interfacesKeys;
+ LOG.trace("Dumping all interfaces to get all IDs");
+ final MappingContext mappingCtx = context.getMappingContext();
+ final Set<Integer> interfacesIdxs = dumpManager.getInterfaces(id, context)
+ .filter(elt -> elt != null)
+ // Filter out disabled interfaces, dont read them
+ // This also prevents child readers in being invoked such as vxlan (which relies on disabling interfaces)
+ .filter(elt -> !interfaceDisableContext
+ .isInterfaceDisabled(elt.swIfIndex, mappingCtx))
+ // filter out sub-interfaces
+ .filter(InterfaceDataTranslator.INSTANCE::isRegularInterface)
+ .map(elt -> elt.swIfIndex)
+ .collect(Collectors.toSet());
+
+ // Clean disabled interfaces list
+ interfaceDisableContext.getDisabledInterfaces(mappingCtx).stream()
+ // Find indices not currently in VPP
+ .filter(interfacesIdxs::contains)
+ // Remove from disabled list ... not disabled if not existing
+ .forEach(idx -> interfaceDisableContext.removeDisabledInterface(idx, mappingCtx));
+
+ // Transform indices to keys
+ interfacesKeys = interfacesIdxs.stream()
+ .map(index -> new InterfaceKey(interfaceNamingContext.getName(index, context.getMappingContext())))
+ .collect(Collectors.toList());
+
+ LOG.debug("Interfaces found in VPP: {}", interfacesKeys);
+ return interfacesKeys;
+ }
+
+ @Override
+ public void merge(@Nonnull final org.opendaylight.yangtools.concepts.Builder<? extends DataObject> builder,
+ @Nonnull final List<Interface> readData) {
+ ((InterfacesBuilder) builder).setInterface(readData);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface> init(
+ @Nonnull final InstanceIdentifier<Interface> id, @Nonnull final Interface readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceBuilder()
+ .setName(readValue.getName())
+ .setType(readValue.getType())
+ .setEnabled(AdminStatus.Up.equals(readValue.getAdminStatus()))
+ // Not present in interfaces
+ // .setLinkUpDownTrapEnable()
+ .build());
+ }
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface> getCfgId(
+ final InstanceIdentifier<Interface> id) {
+ return InstanceIdentifier.create(Interfaces.class).child(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey(
+ id.firstKeyOf(Interface.class).getName()));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceDataTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceDataTranslator.java
new file mode 100644
index 000000000..b916431f3
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceDataTranslator.java
@@ -0,0 +1,203 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import java.math.BigInteger;
+import java.util.Objects;
+import java.util.stream.Collector;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.AfPacket;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.GreTunnel;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.Loopback;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.TapV2;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VhostUser;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanGpeTunnel;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanTunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev180703.EthernetCsmacd;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyConsumer {
+
+ InterfaceDataTranslator INSTANCE = new InterfaceDataTranslator() {
+ };
+
+ int PHYSICAL_ADDRESS_LENGTH = 6;
+
+ Collector<SwInterfaceDetails, ?, SwInterfaceDetails> SINGLE_ITEM_COLLECTOR =
+ RWUtils.singleItemCollector();
+
+ /**
+ * Convert VPP's link speed in kbits per second to Yang type.
+ *
+ * @param vppLinkSpeed Link speed in kbits per second from VPP.
+ * @return Converted value from VPP link speed
+ */
+ default Gauge64 vppInterfaceSpeedToYang(int vppLinkSpeed) {
+ return new Gauge64(BigInteger.valueOf(Integer.toUnsignedLong(vppLinkSpeed) * 1000));
+ }
+
+ /**
+ * Reads first 6 bytes of supplied byte array and converts to string as Yang dictates <p> Replace later with
+ * https://git.opendaylight.org/gerrit/#/c/34869/10/model/ietf/ietf-type- util/src/main/
+ * java/org/opendaylight/mdsal/model/ietf/util/AbstractIetfYangUtil.java
+ *
+ * @param vppPhysAddress byte array of bytes in big endian order, constructing the network IF physical address.
+ * @return String like "aa:bb:cc:dd:ee:ff"
+ * @throws NullPointerException if vppPhysAddress is null
+ * @throws IllegalArgumentException if vppPhysAddress.length &lt; 6
+ */
+ default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) {
+ Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes");
+ final int endIndex = PHYSICAL_ADDRESS_LENGTH;
+ checkArgument(endIndex <= vppPhysAddress.length,
+ "Invalid physical address size (%s), expected >= %s", vppPhysAddress.length, endIndex);
+ // Extended (64-bit) MAC addresses are currently not supported , so use first 48-bits.
+ // Adding support for extended MAC addresses might require yang model change.
+ // Also VPP is not consistent (e.g. for TAP it allows to configure MAC of 6 bytes, but sw_interface_details
+ // contains 8 bytes.
+ return printHexBinary(vppPhysAddress, 0, PHYSICAL_ADDRESS_LENGTH);
+ }
+
+ /**
+ * VPP's interface index is counted from 0, whereas ietf-interface's if-index is from 1. This function converts from
+ * VPP's interface index to YANG's interface index.
+ *
+ * @param vppIfIndex the sw interface index VPP reported.
+ * @return VPP's interface index incremented by one
+ */
+ default int vppIfIndexToYang(int vppIfIndex) {
+ return vppIfIndex + 1;
+ }
+
+ /**
+ * This function does the opposite of what {@link #vppIfIndexToYang(int)} does.
+ *
+ * @param yangIfIndex if-index from ietf-interfaces.
+ * @return VPP's representation of the if-index
+ */
+ default int yangIfIndexToVpp(int yangIfIndex) {
+ checkArgument(yangIfIndex >= 1, "YANG if-index has invalid value %s", yangIfIndex);
+ return yangIfIndex - 1;
+ }
+
+ /**
+ * Determine interface type based on its VPP name (relying on VPP's interface naming conventions)
+ *
+ * @param interfaceName VPP generated interface name
+ * @return Interface type
+ */
+ @Nonnull
+ default Class<? extends InterfaceType> getInterfaceType(@Nonnull final String interfaceName) {
+
+ if (interfaceName.startsWith("tap")) {
+ return TapV2.class;
+ }
+
+ if (interfaceName.startsWith("vxlan_gpe")) {
+ return VxlanGpeTunnel.class;
+ }
+
+ if (interfaceName.startsWith("vxlan")) {
+ return VxlanTunnel.class;
+ }
+
+ if (interfaceName.startsWith("gre")) {
+ return GreTunnel.class;
+ }
+
+ if (interfaceName.startsWith("VirtualEthernet")) {
+ return VhostUser.class;
+ }
+
+ if (interfaceName.startsWith("host-")) {
+ return AfPacket.class;
+ }
+
+ if (interfaceName.startsWith("loop")) {
+ return Loopback.class;
+ }
+
+ return EthernetCsmacd.class;
+ }
+
+ /**
+ * Check interface type. Uses interface details from VPP to determine.
+ */
+ default boolean isInterfaceOfType(@Nonnull final InterfaceCacheDumpManager dumpManager,
+ @Nonnull final InstanceIdentifier<?> id,
+ @Nonnull final ReadContext ctx,
+ @Nonnull final Class<? extends InterfaceType> ifcType)
+ throws ReadFailedException {
+ final String name = id.firstKeyOf(Interface.class).getName();
+ final SwInterfaceDetails vppInterfaceDetails = dumpManager.getInterfaceDetail(id, ctx, name);
+
+ return isInterfaceOfType(ifcType, vppInterfaceDetails);
+ }
+
+ default boolean isInterfaceOfType(@Nonnull final Class<? extends InterfaceType> ifcType,
+ @Nullable final SwInterfaceDetails cachedDetails) {
+ if (cachedDetails == null) {
+ return false;
+ } else {
+ return ifcType.equals(getInterfaceType(toString(cachedDetails.interfaceName)));
+ }
+ }
+
+ /**
+ * Checks whether provided {@link SwInterfaceDetails} is detail of sub-interface<br>
+ * <ul>
+ * <li>subId == unique number of sub-interface within set of sub-interfaces of single interface</li>
+ * <li>swIfIndex == unique index of interface/sub-interface within all interfaces</li>
+ * <li>supSwIfIndex == unique index of parent interface</li>
+ * <li>in case of interface , swIfIndex value equals supSwIfIndex</li>
+ * <li>in case of subinterface, supSwIfIndex equals index of parent interface, swIfIndex is index of
+ * subinterface itselt</li>
+ * </ul>
+ */
+ default boolean isSubInterface(@Nonnull final SwInterfaceDetails elt) {
+ //cant check by subId != 0, because you can pick 0 as value
+ return elt.supSwIfIndex != elt.swIfIndex;
+ }
+
+ /**
+ * Checks whether provided {@link SwInterfaceDetails} is detail of interface<br>
+ * <ul>
+ * <li>subId == unique number of subinterface within set of subinterfaces of single interface</li>
+ * <li>swIfIndex == unique index of interface/subinterface within all interfaces</li>
+ * <li>supSwIfIndex == unique index of parent interface</li>
+ * <li>in case of interface , swIfIndex value equals supSwIfIndex</li>
+ * <li>in case of subinterface, supSwIfIndex equals index of parent interface, swIfIndex is index
+ * of subinterface itselt</li>
+ * </ul>
+ */
+ default boolean isRegularInterface(@Nonnull final SwInterfaceDetails elt) {
+ return !isSubInterface(elt);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceRoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceRoutingCustomizer.java
new file mode 100644
index 000000000..b87228edf
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceRoutingCustomizer.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.RoutingBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InterfaceRoutingCustomizer extends RoutingCustomizer implements
+ InitializingReaderCustomizer<Routing, RoutingBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceRoutingCustomizer.class);
+
+ public InterfaceRoutingCustomizer(@Nonnull final FutureJVppCore vppApi,
+ @Nonnull final NamingContext interfaceContext) {
+ super(vppApi, interfaceContext);
+ }
+
+ @Nonnull
+ @Override
+ public RoutingBuilder getBuilder(@Nonnull final InstanceIdentifier<Routing> id) {
+ return new RoutingBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id,
+ @Nonnull final RoutingBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ LOG.debug("Reading attributes for Routing: {}", id);
+ final String ifName = id.firstKeyOf(Interface.class).getName();
+ readInterfaceRouting(id, builder::setIpv4VrfId, builder::setIpv6VrfId, ctx, ifName);
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final Routing readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setRouting(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing> init(
+ @Nonnull final InstanceIdentifier<Routing> id,
+ @Nonnull final Routing readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.RoutingBuilder()
+ .setIpv4VrfId(readValue.getIpv4VrfId())
+ .setIpv6VrfId(readValue.getIpv6VrfId())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing> getCfgId(
+ final InstanceIdentifier<Routing> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Routing.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceStatisticsCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceStatisticsCustomizer.java
new file mode 100644
index 000000000..bfcb3ee52
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/InterfaceStatisticsCustomizer.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceStatisticsManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.jvpp.stats.dto.InterfaceStatistics;
+import io.fd.jvpp.stats.dto.InterfaceStatisticsDetails;
+import io.fd.jvpp.stats.dto.InterfaceStatisticsDetailsReplyDump;
+import io.fd.jvpp.stats.dto.InterfaceStatisticsDump;
+import io.fd.jvpp.stats.future.FutureJVppStatsFacade;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces._interface.Statistics;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces._interface.StatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InterfaceStatisticsCustomizer implements ReaderCustomizer<Statistics, StatisticsBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceStatisticsCustomizer.class);
+
+ private final NamingContext ifcNamingCtx;
+ private final FutureJVppStatsFacade jvppStats;
+ private final InterfaceStatisticsManager statisticsManager;
+
+ public InterfaceStatisticsCustomizer(final NamingContext ifcNamingCtx,
+ final FutureJVppStatsFacade jvppStats,
+ final InterfaceStatisticsManager statisticsManager) {
+ this.ifcNamingCtx = checkNotNull(ifcNamingCtx, "Naming context should not be null");
+ this.jvppStats = checkNotNull(jvppStats, "JVpp Stats facade should not be null");
+ this.statisticsManager = checkNotNull(statisticsManager, "Statistics Manager should not be null");
+ }
+
+ @Nonnull
+ @Override
+ public StatisticsBuilder getBuilder(@Nonnull final InstanceIdentifier<Statistics> instanceIdentifier) {
+ return new StatisticsBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Statistics> instanceIdentifier,
+ @Nonnull final StatisticsBuilder statisticsBuilder,
+ @Nonnull final ReadContext readContext)
+ throws ReadFailedException {
+ if (!statisticsManager.isStatisticsEnabled()) return;
+
+ final InterfaceKey key = instanceIdentifier.firstKeyOf(Interface.class);
+ final int index = ifcNamingCtx.getIndex(key.getName(), readContext.getMappingContext());
+ InterfaceStatisticsDetails stats = getStatisticsDump(instanceIdentifier);
+ if (stats != null) {
+ Optional<InterfaceStatistics> statsDetail =
+ Arrays.asList(stats.interfaceStatistics).stream().filter(elt -> elt.swIfIndex == index).findFirst();
+ if (statsDetail.isPresent()) {
+ InterfaceStatistics detail = statsDetail.get();
+ statisticsBuilder.setOutOctets(new Counter64(BigInteger.valueOf(detail.outBytes)))
+ .setOutUnicastPkts(new Counter64(BigInteger.valueOf(detail.outUnicastPkts)))
+ .setOutMulticastPkts(new Counter64(BigInteger.valueOf(detail.outMulticastPkts)))
+ .setOutBroadcastPkts(new Counter64(BigInteger.valueOf(detail.outBroadcastPkts)))
+ .setOutErrors(new Counter32(new Long(detail.outErrors)))
+ .setInOctets(new Counter64(BigInteger.valueOf(detail.inBytes)))
+ .setInUnicastPkts(new Counter64(BigInteger.valueOf(detail.inUnicastPkts)))
+ .setInMulticastPkts(new Counter64(BigInteger.valueOf(detail.inMulticastPkts)))
+ .setInBroadcastPkts(new Counter64(BigInteger.valueOf(detail.inBroadcastPkts)))
+ .setInErrors(new Counter32(new Long(detail.inErrors)));
+ }
+ }
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final Statistics statistics) {
+ ((InterfaceBuilder) builder).setStatistics(statistics);
+ }
+
+ private InterfaceStatisticsDetails getStatisticsDump(InstanceIdentifier<Statistics> id) throws ReadFailedException {
+ LOG.debug("Sending InterfaceStatisticsDump request...");
+ final InterfaceStatisticsDump request = new InterfaceStatisticsDump();
+
+ final Future<InterfaceStatisticsDetailsReplyDump> replyFuture =
+ jvppStats.interfaceStatisticsDump(request).toCompletableFuture();
+ final InterfaceStatisticsDetailsReplyDump reply;
+ try {
+ reply = replyFuture.get();
+ } catch (Exception e) {
+ throw new ReadFailedException(id, e);
+ }
+
+ if (reply == null || reply.interfaceStatisticsDetails == null) {
+ throw new ReadFailedException(id,
+ new IllegalStateException("Received null response for empty dump: " + reply));
+ }
+ return reply.interfaceStatisticsDetails;
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/L2Customizer.java
new file mode 100644
index 000000000..13440ef63
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/L2Customizer.java
@@ -0,0 +1,119 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2Builder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.BridgeBasedBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.XconnectBased;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.XconnectBasedBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading ietf-interfaces:interfaces/interface/iface_name/v3po:l2
+ */
+public class L2Customizer extends FutureJVppCustomizer implements InitializingReaderCustomizer<L2, L2Builder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
+ private final InterconnectionReadUtils icReadUtils;
+
+ public L2Customizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ super(futureJVppCore);
+ this.icReadUtils =
+ new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext, dumpManager);
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final L2 readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setL2(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public L2Builder getBuilder(@Nonnull final InstanceIdentifier<L2> id) {
+ return new L2Builder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2Builder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+
+ LOG.debug("Reading attributes for L2: {}", id);
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final String ifaceName = key.getName();
+ builder.setInterconnection(icReadUtils.readInterconnection(id, ifaceName, ctx));
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2> init(
+ @Nonnull final InstanceIdentifier<L2> id,
+ @Nonnull final L2 readValue,
+ @Nonnull final ReadContext ctx) {
+ final org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2Builder
+ l2Builder =
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2Builder();
+
+ final Interconnection interconnection = readValue.getInterconnection();
+ if (interconnection != null) {
+ if (interconnection instanceof XconnectBased) {
+ final XconnectBasedBuilder xconnectBasedBuilder = new XconnectBasedBuilder();
+ xconnectBasedBuilder.setXconnectOutgoingInterface(
+ ((XconnectBased) interconnection).getXconnectOutgoingInterface());
+ l2Builder.setInterconnection(xconnectBasedBuilder.build());
+ } else if (interconnection instanceof BridgeBased) {
+ final BridgeBasedBuilder bridgeBasedBuilder = new BridgeBasedBuilder();
+ bridgeBasedBuilder.setBridgeDomain(((BridgeBased) interconnection).getBridgeDomain());
+ bridgeBasedBuilder
+ .setBridgedVirtualInterface(((BridgeBased) interconnection).isBridgedVirtualInterface());
+ bridgeBasedBuilder.setSplitHorizonGroup(((BridgeBased) interconnection).getSplitHorizonGroup());
+ l2Builder.setInterconnection(bridgeBasedBuilder.build());
+ }
+ }
+
+ return Initialized.create(getCfgId(id), l2Builder.build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2> getCfgId(
+ final InstanceIdentifier<L2> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.L2.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RewriteCustomizer.java
new file mode 100644
index 000000000..54164cc10
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RewriteCustomizer.java
@@ -0,0 +1,142 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import io.fd.hc2vpp.common.translate.util.TagRewriteOperation;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.hc2vpp.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319._802dot1ad;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319._802dot1q;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.rewrite.attributes.Rewrite;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.rewrite.attributes.RewriteBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2Builder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.tag.rewrite.PushTags;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.tag.rewrite.PushTagsBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.tag.rewrite.PushTagsKey;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTagBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading vlan tag-rewrite configuration state form the VPP.
+ */
+public class RewriteCustomizer
+ implements ReaderCustomizer<Rewrite, RewriteBuilder>, InterfaceDataTranslator {
+
+ // No initialization necessary since its parent Subinterface L2 customzier sets the entire subtree during
+ // initialization
+
+ private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class);
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public RewriteCustomizer(@Nonnull final InterfaceCacheDumpManager dumpManager) {
+ this.dumpManager = checkNotNull(dumpManager, "dumpManager should not be null");
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
+ @Nonnull final Rewrite readValue) {
+ ((L2Builder) parentBuilder).setRewrite(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public RewriteBuilder getBuilder(@Nonnull final InstanceIdentifier<Rewrite> id) {
+ return new RewriteBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Rewrite> id,
+ @Nonnull final RewriteBuilder builder, @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ final String subInterfaceName = getSubInterfaceName(id);
+ LOG.debug("Reading attributes for sub interface: {}", subInterfaceName);
+
+ final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, subInterfaceName);
+ LOG.debug("VPP sub-interface details: {}", iface);
+
+ checkState(isSubInterface(iface), "Interface returned by the VPP is not a sub-interface");
+
+ final TagRewriteOperation operation = TagRewriteOperation.get(iface.vtrOp);
+ if (TagRewriteOperation.disabled == operation) {
+ LOG.debug("Tag rewrite operation is disabled for ");
+ return;
+ }
+
+ builder.setVlanType(iface.vtrPushDot1Q == 1
+ ? _802dot1q.class
+ : _802dot1ad.class);
+
+ setPushTags(builder, iface);
+ setPopTags(builder, operation);
+ }
+
+ private static String getSubInterfaceName(final InstanceIdentifier<Rewrite> id) {
+ return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(),
+ Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier()));
+ }
+
+ private void setPopTags(final RewriteBuilder builder, final TagRewriteOperation operation) {
+ final byte numberOfTagsToPop = operation.getPopTags();
+ if (numberOfTagsToPop != 0) {
+ builder.setPopTags(Short.valueOf(numberOfTagsToPop));
+ }
+ }
+
+ private void setPushTags(final RewriteBuilder builder, final SwInterfaceDetails iface) {
+ final List<PushTags> tags = new ArrayList<>();
+ if (iface.vtrTag1 != 0) {
+ tags.add(buildTag((short) 0, SVlan.class, iface.vtrTag1));
+ }
+ if (iface.vtrTag2 != 0) {
+ tags.add(buildTag((short) 1, CVlan.class, iface.vtrTag2));
+ }
+ if (tags.size() > 0) {
+ builder.setPushTags(tags);
+ }
+ }
+
+ private PushTags buildTag(final short index, final Class<? extends Dot1qTagVlanType> tagType, final int vlanId) {
+ final PushTagsBuilder tag = new PushTagsBuilder();
+ tag.setIndex(index);
+ tag.withKey(new PushTagsKey(index));
+ final Dot1qTagBuilder dtag = new Dot1qTagBuilder();
+ dtag.setTagType(tagType);
+ dtag.setVlanId(new Dot1qVlanId(vlanId));
+ tag.setDot1qTag(dtag.build());
+ return tag.build();
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RoutingCustomizer.java
new file mode 100644
index 000000000..2ac172af6
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/RoutingCustomizer.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read;
+
+import com.google.common.primitives.UnsignedInts;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.jvpp.core.dto.SwInterfaceGetTable;
+import io.fd.jvpp.core.dto.SwInterfaceGetTableReply;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.function.Consumer;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.RoutingBaseAttributes;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+abstract class RoutingCustomizer extends FutureJVppCustomizer implements JvppReplyConsumer {
+ private final NamingContext interfaceContext;
+
+ protected RoutingCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJVppCore);
+ this.interfaceContext = interfaceContext;
+ }
+
+ protected void readInterfaceRouting(@Nonnull final InstanceIdentifier<? extends RoutingBaseAttributes> id,
+ @Nonnull final Consumer<VniReference> v4VrfConsumer,
+ @Nonnull final Consumer<VniReference> v6VrfConsumer,
+ @Nonnull final ReadContext ctx, final String interfaceName)
+ throws ReadFailedException {
+ final SwInterfaceGetTable request = new SwInterfaceGetTable();
+ request.swIfIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext());
+ request.isIpv6 = 0;
+ final SwInterfaceGetTableReply
+ ip4Reply = getReplyForRead(getFutureJVpp().swInterfaceGetTable(request).toCompletableFuture(), id);
+
+ request.isIpv6 = 1;
+ final SwInterfaceGetTableReply ip6Reply =
+ getReplyForRead(getFutureJVpp().swInterfaceGetTable(request).toCompletableFuture(), id);
+
+ if (ip4Reply.vrfId != 0) {
+ v4VrfConsumer.accept(new VniReference(UnsignedInts.toLong(ip4Reply.vrfId)));
+ }
+ if (ip6Reply.vrfId != 0) {
+ v6VrfConsumer.accept(new VniReference(UnsignedInts.toLong(ip6Reply.vrfId)));
+ }
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceCustomizer.java
new file mode 100644
index 000000000..f4bba6d2c
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceCustomizer.java
@@ -0,0 +1,243 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.hc2vpp.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.SubInterfaceStatus;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.SubinterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.SubInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.match.attributes.match.type.DefaultBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.match.attributes.match.type.UntaggedBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.Match;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.MatchBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.Tags;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.TagsBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.tags.Tag;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.tags.TagBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.base.attributes.tags.TagKey;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTagBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading sub interfaces form the VPP.
+ */
+public class SubInterfaceCustomizer extends FutureJVppCustomizer
+ implements InitializingListReaderCustomizer<SubInterface, SubInterfaceKey, SubInterfaceBuilder>,
+ ByteDataTranslator,
+ InterfaceDataTranslator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class);
+ private static final Dot1qTag.VlanId ANY_VLAN_ID = new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any);
+ private final NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public SubInterfaceCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ super(jvpp);
+ this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
+ this.dumpManager = checkNotNull(dumpManager, "dumpManager should not be null");
+ }
+
+ private static String getSubInterfaceName(final InstanceIdentifier<SubInterface> id) {
+ return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(),
+ Math.toIntExact(id.firstKeyOf(id.getTargetType()).getIdentifier()));
+ }
+
+ private static Tag buildTag(final short index, final Class<? extends Dot1qTagVlanType> tagType,
+ final Dot1qTag.VlanId vlanId) {
+ TagBuilder tag = new TagBuilder();
+ tag.setIndex(index);
+ tag.withKey(new TagKey(index));
+ final Dot1qTagBuilder dtag = new Dot1qTagBuilder();
+ dtag.setTagType(tagType);
+ dtag.setVlanId(vlanId);
+ tag.setDot1qTag(dtag.build());
+ return tag.build();
+ }
+
+ private static Dot1qTag.VlanId buildVlanId(final short vlanId) {
+ // treat vlanId as unsigned value:
+ return new Dot1qTag.VlanId(new Dot1qVlanId(0xffff & vlanId));
+ }
+
+ @Nonnull
+ @Override
+ public List<SubInterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<SubInterface> id,
+ @Nonnull final ReadContext context) throws ReadFailedException {
+ // Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
+ // to fill in the context with initial ifc mapping
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final String ifaceName = key.getName();
+ final int ifaceId = interfaceContext.getIndex(ifaceName, context.getMappingContext());
+
+ final List<SubInterfaceKey> interfacesKeys = dumpManager.getInterfaces(id,context)
+ .filter(Objects::nonNull)
+ // accept only sub-interfaces for current iface:
+ .filter(elt -> isSubInterface(elt) && elt.supSwIfIndex == ifaceId)
+ .map(details -> new SubInterfaceKey(new Long(details.subId)))
+ .collect(Collectors.toList());
+
+ LOG.debug("Sub-interfaces of {} found in VPP: {}", ifaceName, interfacesKeys);
+ return interfacesKeys;
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> builder,
+ @Nonnull final List<SubInterface> readData) {
+ ((SubInterfacesBuilder) builder).setSubInterface(readData);
+ }
+
+ @Nonnull
+ @Override
+ public SubInterfaceBuilder getBuilder(@Nonnull final InstanceIdentifier<SubInterface> id) {
+ return new SubInterfaceBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
+ @Nonnull final SubInterfaceBuilder builder, @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ final String subInterfaceName = getSubInterfaceName(id);
+ LOG.debug("Reading attributes for sub interface: {}", subInterfaceName);
+
+ final SwInterfaceDetails iface = dumpManager.getInterfaceDetail(id, ctx, subInterfaceName);
+ LOG.debug("VPP sub-interface details: {}", iface);
+
+ checkState(isSubInterface(iface), "Interface returned by the VPP is not a sub-interface");
+
+ builder.setIdentifier((long) iface.subId);
+ builder.withKey(new SubInterfaceKey(builder.getIdentifier()));
+
+ // sub-interface-base-attributes:
+ builder.setTags(readTags(iface));
+ builder.setMatch(readMatch(iface));
+
+ // sub-interface-operational-attributes:
+ builder.setAdminStatus(1 == iface.adminUpDown
+ ? SubInterfaceStatus.Up
+ : SubInterfaceStatus.Down);
+ builder.setOperStatus(1 == iface.linkUpDown
+ ? SubInterfaceStatus.Up
+ : SubInterfaceStatus.Down);
+ builder.setIfIndex(vppIfIndexToYang(iface.swIfIndex));
+ if (iface.l2AddressLength == 6) {
+ builder.setPhysAddress(new PhysAddress(vppPhysAddrToYang(iface.l2Address)));
+ }
+ if (0 != iface.linkSpeed) {
+ builder.setSpeed(vppInterfaceSpeedToYang(iface.linkSpeed));
+ }
+ }
+
+ private Tags readTags(final SwInterfaceDetails iface) {
+ final TagsBuilder tags = new TagsBuilder();
+ final List<Tag> list = new ArrayList<>();
+ if (iface.subNumberOfTags > 0) {
+ if (iface.subOuterVlanIdAny == 1) {
+ list.add(buildTag((short) 0, SVlan.class, ANY_VLAN_ID));
+ } else {
+ list.add(buildTag((short) 0, SVlan.class, buildVlanId(iface.subOuterVlanId)));
+ }
+ // inner tag (customer tag):
+ if (iface.subNumberOfTags == 2) {
+ if (iface.subInnerVlanIdAny == 1) {
+ list.add(buildTag((short) 1, CVlan.class, ANY_VLAN_ID));
+ } else {
+ list.add(buildTag((short) 1, CVlan.class, buildVlanId(iface.subInnerVlanId)));
+ }
+ }
+ }
+ tags.setTag(list);
+ return tags.build();
+ }
+
+ private Match readMatch(final SwInterfaceDetails iface) {
+ final MatchBuilder match = new MatchBuilder();
+ if (iface.subDefault == 1) {
+ match.setMatchType(new DefaultBuilder().build());
+ } else if (iface.subNumberOfTags == 0) {
+ match.setMatchType(new UntaggedBuilder().build());
+ } else {
+ final VlanTaggedBuilder tagged = new VlanTaggedBuilder();
+ tagged.setMatchExactTags(byteToBoolean(iface.subExactMatch));
+ match.setMatchType(
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.match.attributes.match.type.VlanTaggedBuilder()
+ .setVlanTagged(tagged.build()).build());
+ }
+ return match.build();
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface> init(
+ @Nonnull final InstanceIdentifier<SubInterface> id, @Nonnull final SubInterface readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceBuilder()
+ .setEnabled(SubInterfaceStatus.Up.equals(readValue.getAdminStatus()))
+ .setIdentifier(readValue.getIdentifier())
+ .setMatch(readValue.getMatch())
+ .setTags(readValue.getTags())
+ .setVlanType(readValue.getVlanType())
+ .build());
+ }
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface> getCfgId(
+ final InstanceIdentifier<SubInterface> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(SubinterfaceAugmentation.class)
+ .child(SubInterfaces.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface.class,
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceKey(
+ id.firstKeyOf(SubInterface.class).getIdentifier()));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceL2Customizer.java
new file mode 100644
index 000000000..598f3d5ac
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceL2Customizer.java
@@ -0,0 +1,119 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.XconnectBased;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading vlan sub interface L2 operational state
+ */
+public class SubInterfaceL2Customizer
+ implements InitializingReaderCustomizer<L2, L2Builder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class);
+ private final InterconnectionReadUtils icReadUtils;
+
+ public SubInterfaceL2Customizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ this.icReadUtils =
+ new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext, dumpManager);
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final L2 readValue) {
+ ((SubInterfaceBuilder) parentBuilder).setL2(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public L2Builder getBuilder(@Nonnull final InstanceIdentifier<L2> id) {
+ return new L2Builder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2Builder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ LOG.debug("Reading attributes for sub-interface L2: {}", id);
+ final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class);
+ final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class);
+ final String subInterfaceName =
+ getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue());
+
+ builder.setInterconnection(icReadUtils.readInterconnection(id, subInterfaceName, ctx));
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2> init(
+ @Nonnull final InstanceIdentifier<L2> id,
+ @Nonnull final L2 readValue,
+ @Nonnull final ReadContext ctx) {
+
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2Builder
+ builder =
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2Builder();
+
+ if (readValue.getInterconnection() instanceof XconnectBased) {
+ XconnectBased state = (XconnectBased) readValue.getInterconnection();
+ builder.setInterconnection(
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.XconnectBasedBuilder()
+ .setXconnectOutgoingInterface(state.getXconnectOutgoingInterface())
+ .build());
+ } else {
+ BridgeBased state = (BridgeBased) readValue.getInterconnection();
+ builder.setInterconnection(
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.l2.config.attributes.interconnection.BridgeBasedBuilder()
+ .setBridgeDomain(state.getBridgeDomain())
+ .setBridgedVirtualInterface(state.isBridgedVirtualInterface())
+ .setSplitHorizonGroup(state.getSplitHorizonGroup())
+ .build());
+ }
+
+ return Initialized.create(getCfgId(id), builder.setRewrite(readValue.getRewrite()).build());
+ }
+
+ static InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2> getCfgId(
+ final InstanceIdentifier<L2> id) {
+ return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class))
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.l2.config.attributes.L2.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceRoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceRoutingCustomizer.java
new file mode 100644
index 000000000..831da821c
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/SubInterfaceRoutingCustomizer.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read;
+
+import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.subInterfaceFullNameOperational;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.Routing;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.sub._interface.routing.attributes.RoutingBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+
+public class SubInterfaceRoutingCustomizer extends RoutingCustomizer implements
+ InitializingReaderCustomizer<Routing, RoutingBuilder> {
+ public SubInterfaceRoutingCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJVppCore, interfaceContext);
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<Routing> instanceIdentifier,
+ @Nonnull final Routing routing,
+ @Nonnull final ReadContext readContext) {
+ return Initialized.create(instanceIdentifier, routing);
+ }
+
+ @Nonnull
+ @Override
+ public RoutingBuilder getBuilder(@Nonnull final InstanceIdentifier<Routing> instanceIdentifier) {
+ return new RoutingBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> instanceIdentifier,
+ @Nonnull final RoutingBuilder routingBuilder,
+ @Nonnull final ReadContext readContext)
+ throws ReadFailedException {
+ readInterfaceRouting(instanceIdentifier, routingBuilder::setIpv4VrfId, routingBuilder::setIpv6VrfId,
+ readContext, subInterfaceFullNameOperational(instanceIdentifier));
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final Routing routing) {
+ ((SubInterfaceBuilder)builder).setRouting(routing);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/TapV2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/TapV2Customizer.java
new file mode 100644
index 000000000..902440a34
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/TapV2Customizer.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2018 Pantheon Technologies 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.MacTranslator;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.StaticCacheKeyFactory;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.jvpp.core.dto.SwInterfaceTapV2Details;
+import io.fd.jvpp.core.dto.SwInterfaceTapV2DetailsReplyDump;
+import io.fd.jvpp.core.dto.SwInterfaceTapV2Dump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.TapV2;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.TapV2Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class TapV2Customizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<TapV2, TapV2Builder>, InterfaceDataTranslator, JvppReplyConsumer,
+ MacTranslator, Ipv4Translator, Ipv6Translator{
+
+ private static final Logger LOG = LoggerFactory.getLogger(TapV2Customizer.class);
+ private NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+ private final DumpCacheManager<SwInterfaceTapV2DetailsReplyDump, Void> tapV2DumpManager;
+
+ public TapV2Customizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ this.dumpManager = dumpManager;
+ this.tapV2DumpManager = new DumpCacheManager.DumpCacheManagerBuilder<SwInterfaceTapV2DetailsReplyDump, Void>()
+ .withCacheKeyFactory(new StaticCacheKeyFactory(TapV2Customizer.class.getName() + "_dump",
+ SwInterfaceTapV2DetailsReplyDump.class))
+ .withExecutor((identifier, params) -> {
+ // Full TapV2 dump has to be performed here, no filter or anything is here to help so at least we cache it
+ return getReplyForRead(getFutureJVpp()
+ .swInterfaceTapV2Dump(new SwInterfaceTapV2Dump()).toCompletableFuture(), identifier);
+ }).build();
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull TapV2 readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setTapV2(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public TapV2Builder getBuilder(@Nonnull InstanceIdentifier<TapV2> id) {
+ return new TapV2Builder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<TapV2> id,
+ @Nonnull final TapV2Builder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(dumpManager, id, ctx,
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.TapV2.class)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for tapV2 interface: {}", key.getName());
+ final SwInterfaceTapV2DetailsReplyDump reply = tapV2DumpManager.getDump(id, ctx.getModificationCache())
+ .orElse(new SwInterfaceTapV2DetailsReplyDump());
+
+ final Optional<SwInterfaceTapV2Details> detail = reply.swInterfaceTapV2Details.stream()
+ .filter(d -> d.swIfIndex == index)
+ .findAny();
+
+ checkState(detail.isPresent(), "TapV2 interface for index %s not found", index);
+ final SwInterfaceTapV2Details swInterfaceTapV2Details = detail.get();
+
+ LOG.trace("TapV2 interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapV2Details);
+ if (swInterfaceTapV2Details.devName != null && swInterfaceTapV2Details.devName[0] != 0) {
+ builder.setDeviceName(toString(swInterfaceTapV2Details.devName));
+ } else {
+ builder.setDeviceName(null);
+ }
+
+ if (swInterfaceTapV2Details.hostBridge != null && swInterfaceTapV2Details.hostBridge[0] != 0) {
+ builder.setHostBridge(toString(swInterfaceTapV2Details.hostBridge));
+ } else {
+ builder.setHostBridge(null);
+ }
+
+ if (swInterfaceTapV2Details.hostMacAddr != null &&
+ !ByteDataTranslator.INSTANCE.isArrayZeroed(swInterfaceTapV2Details.hostMacAddr)) {
+ builder.setHostMac(toPhysAddress(swInterfaceTapV2Details.hostMacAddr));
+ } else {
+ builder.setHostMac(null);
+ }
+
+ if (swInterfaceTapV2Details.hostIfName != null && swInterfaceTapV2Details.hostIfName[0] != 0) {
+ builder.setHostInterfaceName(toString(swInterfaceTapV2Details.hostIfName));
+ } else {
+ builder.setHostInterfaceName(null);
+ }
+
+ if (swInterfaceTapV2Details.hostIp4Addr != null && swInterfaceTapV2Details.hostIp4PrefixLen != 0) {
+ builder.setHostIpv4Address(
+ toIpv4Prefix(swInterfaceTapV2Details.hostIp4Addr, swInterfaceTapV2Details.hostIp4PrefixLen));
+ } else {
+ builder.setHostIpv4Address(null);
+ }
+
+ if (swInterfaceTapV2Details.hostIp6Addr != null && swInterfaceTapV2Details.hostIp6PrefixLen != 0) {
+ builder.setHostIpv6Address(
+ toIpv6Prefix(swInterfaceTapV2Details.hostIp6Addr,
+ Byte.toUnsignedInt(swInterfaceTapV2Details.hostIp6PrefixLen)));
+ } else {
+ builder.setHostIpv6Address(null);
+ }
+
+ if (swInterfaceTapV2Details.hostNamespace != null && swInterfaceTapV2Details.hostNamespace[0] != 0) {
+ builder.setHostNamespace(toString(swInterfaceTapV2Details.hostNamespace));
+ } else {
+ builder.setHostNamespace(null);
+ }
+
+
+ builder.setRxRingSize(Short.toUnsignedInt(swInterfaceTapV2Details.rxRingSz));
+ builder.setTxRingSize(Short.toUnsignedInt(swInterfaceTapV2Details.txRingSz));
+ final SwInterfaceDetails ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName());
+
+ if (ifcDetails.tag[0] != 0) { // tag supplied
+ builder.setTag(toString(ifcDetails.tag));
+ }
+ LOG.debug("TapV2 interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.TapV2> init(
+ @Nonnull final InstanceIdentifier<TapV2> id, @Nonnull final TapV2 readValue,
+ @Nonnull final ReadContext ctx) {
+ // The MAC address & tag is set from interface details, those details are retrieved from cache
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+
+ final SwInterfaceDetails ifcDetails;
+ try {
+ ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName());
+ } catch (ReadFailedException e) {
+ throw new IllegalStateException(format("Unable to read interface %s", key.getName()), e);
+ }
+
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.TapV2Builder()
+ .setMac(new PhysAddress(vppPhysAddrToYang(ifcDetails.l2Address)))
+ .setHostInterfaceName(readValue.getHostInterfaceName())
+ .setTag(ifcDetails.tag[0] == 0
+ ? null
+ : toString(ifcDetails.tag))
+ .setHostBridge(readValue.getHostBridge())
+ .setHostIpv4Address(readValue.getHostIpv4Address())
+ .setHostIpv6Address(readValue.getHostIpv6Address())
+ .setRxRingSize(readValue.getRxRingSize())
+ .setTxRingSize(readValue.getTxRingSize())
+ .setHostMac(readValue.getHostMac())
+ .setHostNamespace(readValue.getHostNamespace())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.TapV2> getCfgId(
+ final InstanceIdentifier<TapV2> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.TapV2.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VhostUserCustomizer.java
new file mode 100644
index 000000000..58f395511
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VhostUserCustomizer.java
@@ -0,0 +1,167 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static java.lang.String.format;
+
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.StaticCacheKeyFactory;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.jvpp.core.dto.SwInterfaceVhostUserDetails;
+import io.fd.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump;
+import io.fd.jvpp.core.dto.SwInterfaceVhostUserDump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.math.BigInteger;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VhostUserRole;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUser;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUserBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VhostUserCustomizer implements InitializingReaderCustomizer<VhostUser, VhostUserBuilder>,
+ InterfaceDataTranslator, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class);
+ private NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+ private final DumpCacheManager<SwInterfaceVhostUserDetailsReplyDump, Void> vhostDumpManager;
+
+ public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ this.interfaceContext = interfaceContext;
+ this.dumpManager = dumpManager;
+ this.vhostDumpManager =
+ new DumpCacheManager.DumpCacheManagerBuilder<SwInterfaceVhostUserDetailsReplyDump, Void>()
+ .withCacheKeyFactory(new StaticCacheKeyFactory(VhostUserCustomizer.class.getName() + "_dump",
+ SwInterfaceVhostUserDetailsReplyDump.class))
+ .withExecutor((identifier, params) -> {
+ final CompletionStage<SwInterfaceVhostUserDetailsReplyDump>
+ swInterfaceVhostUserDetailsReplyDumpCompletionStage =
+ jvpp.swInterfaceVhostUserDump(new SwInterfaceVhostUserDump());
+ return getReplyForRead(
+ swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture(),
+ identifier);
+ }).build();
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull VhostUser readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setVhostUser(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public VhostUserBuilder getBuilder(@Nonnull InstanceIdentifier<VhostUser> id) {
+ return new VhostUserBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id,
+ @Nonnull final VhostUserBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ final SwInterfaceDetails ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName());
+
+
+ if (!isInterfaceOfType(
+ org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VhostUser.class,
+ ifcDetails)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for vhpost user interface: {}", key.getName());
+
+
+ final SwInterfaceVhostUserDetailsReplyDump dump =
+ vhostDumpManager.getDump(id, ctx.getModificationCache())
+ .orElse(new SwInterfaceVhostUserDetailsReplyDump());
+
+ // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
+ final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = dump.swInterfaceVhostUserDetails.stream()
+ .filter(detail -> detail.swIfIndex == index)
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException(
+ format("Vhost user for interface %s not found", key.getName())));
+ 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));
+ builder.setNumMemoryRegions((long) swInterfaceVhostUserDetails.numRegions);
+ builder.setSocket(toString(swInterfaceVhostUserDetails.sockFilename));
+ builder.setVirtioNetHdrSize((long) swInterfaceVhostUserDetails.virtioNetHdrSz);
+ // TODO: map error code to meaningful message after VPP-436 is done
+ builder.setConnectError(Integer.toString(swInterfaceVhostUserDetails.sockErrno));
+ if (ifcDetails.tag[0] != 0) { // tag supplied
+ builder.setTag(toString(ifcDetails.tag));
+ }
+
+ LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUser> init(
+ @Nonnull final InstanceIdentifier<VhostUser> id,
+ @Nonnull final VhostUser readValue,
+ @Nonnull final ReadContext ctx) {
+ // The tag is set from interface details, those details are retrieved from cache
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final SwInterfaceDetails ifcDetails;
+ try {
+ ifcDetails = dumpManager.getInterfaceDetail(id, ctx, key.getName());
+ } catch (ReadFailedException e) {
+ throw new IllegalStateException(format("Unable to find VHost interface %s", key.getName()), e);
+ }
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUserBuilder()
+ .setRole(readValue.getRole())
+ .setSocket(readValue.getSocket())
+ .setTag(ifcDetails.tag[0] == 0
+ ? null
+ : toString(ifcDetails.tag))
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUser> getCfgId(
+ final InstanceIdentifier<VhostUser> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VhostUser.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanCustomizer.java
new file mode 100644
index 000000000..f2376bb45
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanCustomizer.java
@@ -0,0 +1,164 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.primitives.UnsignedInts;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.dto.VxlanTunnelDetails;
+import io.fd.jvpp.core.dto.VxlanTunnelDetailsReplyDump;
+import io.fd.jvpp.core.dto.VxlanTunnelDump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.L2Input;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.NshProxy;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanTunnel;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanVni;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Vxlan;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VxlanCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<Vxlan, VxlanBuilder>, InterfaceDataTranslator, JvppReplyConsumer,
+ Ipv4Translator, Ipv6Translator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
+ private final NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public VxlanCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ this.dumpManager = dumpManager;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull Vxlan readValue) {
+ ((VppInterfaceAugmentationBuilder) parentBuilder).setVxlan(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public VxlanBuilder getBuilder(@Nonnull InstanceIdentifier<Vxlan> id) {
+ return new VxlanBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id,
+ @Nonnull final VxlanBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(dumpManager, id, ctx, VxlanTunnel.class)) {
+ return;
+ }
+
+ 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 =
+ getReplyForRead(swInterfaceVxlanDetailsReplyDumpCompletionStage.toCompletableFuture(), id);
+
+ // 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;
+ }
+
+ 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) {
+ builder.setDst(new IpAddressNoZone(arrayToIpv6AddressNoZone(swInterfaceVxlanDetails.dstAddress)));
+ builder.setSrc(new IpAddressNoZone(arrayToIpv6AddressNoZone(swInterfaceVxlanDetails.srcAddress)));
+ } else {
+ builder.setDst(new IpAddressNoZone(arrayToIpv4AddressNoZone(swInterfaceVxlanDetails.dstAddress)));
+ builder.setSrc(new IpAddressNoZone(arrayToIpv4AddressNoZone(swInterfaceVxlanDetails.srcAddress)));
+ }
+ builder.setEncapVrfId(new VniReference(UnsignedInts.toLong(swInterfaceVxlanDetails.encapVrfId)));
+ builder.setVni(new VxlanVni(UnsignedInts.toLong(swInterfaceVxlanDetails.vni)));
+ switch (swInterfaceVxlanDetails.decapNextIndex) {
+ case 1:
+ builder.setDecapNext(L2Input.class);
+ break;
+ case 2:
+ builder.setDecapNext(NshProxy.class);
+ break;
+ default:
+ LOG.trace("Unsupported decap next index for vxlan: {}", swInterfaceVxlanDetails.decapNextIndex);
+ return;
+ }
+ LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Vxlan> init(
+ @Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanBuilder()
+ .setDst(readValue.getDst())
+ .setSrc(readValue.getSrc())
+ .setEncapVrfId(readValue.getEncapVrfId())
+ .setVni(new VxlanVni(readValue.getVni()))
+ .setDecapNext(readValue.getDecapNext())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Vxlan> getCfgId(
+ final InstanceIdentifier<Vxlan> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Vxlan.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanGpeCustomizer.java
new file mode 100644
index 000000000..eb7269c4b
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/VxlanGpeCustomizer.java
@@ -0,0 +1,155 @@
+/*
+ * 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.hc2vpp.v3po.read;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.cache.InterfaceCacheDumpManager;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.dto.VxlanGpeTunnelDetails;
+import io.fd.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump;
+import io.fd.jvpp.core.dto.VxlanGpeTunnelDump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanGpeNextProtocol;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanGpeTunnel;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VxlanGpeVni;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpe;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VxlanGpeCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<VxlanGpe, VxlanGpeBuilder>, InterfaceDataTranslator, JvppReplyConsumer,
+ Ipv4Translator, Ipv6Translator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class);
+ private final NamingContext interfaceContext;
+ private final InterfaceCacheDumpManager dumpManager;
+
+ public VxlanGpeCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final InterfaceCacheDumpManager dumpManager) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ this.dumpManager = dumpManager;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull VxlanGpe readValue) {
+ ((VppInterfaceAugmentationBuilder) 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);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(dumpManager, id, ctx, 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 =
+ getReplyForRead(swInterfaceVxlanGpeDetailsReplyDumpCompletionStage.toCompletableFuture(),
+ id);
+
+ // 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) {
+ builder.setRemote(new IpAddressNoZone(arrayToIpv6AddressNoZone(swInterfaceVxlanGpeDetails.remote)));
+ builder.setLocal(new IpAddressNoZone(arrayToIpv6AddressNoZone(swInterfaceVxlanGpeDetails.local)));
+ } else {
+ builder.setRemote(new IpAddressNoZone(arrayToIpv4AddressNoZone(swInterfaceVxlanGpeDetails.remote)));
+ builder.setLocal(new IpAddressNoZone(arrayToIpv4AddressNoZone(swInterfaceVxlanGpeDetails.local)));
+ }
+ builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni));
+ builder.setNextProtocol(VxlanGpeNextProtocol.forValue(swInterfaceVxlanGpeDetails.protocol));
+ builder.setEncapVrfId((long) swInterfaceVxlanGpeDetails.encapVrfId);
+ builder.setDecapVrfId((long) swInterfaceVxlanGpeDetails.decapVrfId);
+ LOG.debug("VxlanGpe tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpe> init(
+ @Nonnull final InstanceIdentifier<VxlanGpe> id, @Nonnull final VxlanGpe readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpeBuilder()
+ .setLocal(readValue.getLocal())
+ .setRemote(readValue.getRemote())
+ .setVni(new VxlanGpeVni(readValue.getVni()))
+ .setNextProtocol(readValue.getNextProtocol())
+ .setEncapVrfId(readValue.getEncapVrfId())
+ .setDecapVrfId(readValue.getDecapVrfId())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpe> getCfgId(
+ final InstanceIdentifier<VxlanGpe> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.VxlanGpe.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManager.java
new file mode 100644
index 000000000..3d8df7e6c
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManager.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read.cache;
+
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Manager for dump data of interfaces. The main purpose of this manager is to cache common interface data between
+ * various classes that process this kind of data. If reader does not use this utility, it introduces a big overhead
+ * because of size/complexity of interfaces dump
+ */
+public interface InterfaceCacheDumpManager {
+
+ /**
+ * Provides stream of all currently configured vpp interfaces
+ *
+ * @param identifier id of currently processed data
+ * @param ctx context of current transaction
+ * @return {@link Stream} of currently configured interfaces
+ * @throws ReadFailedException if dumping of data was unsuccessful
+ */
+ @Nonnull
+ Stream<SwInterfaceDetails> getInterfaces(@Nonnull final InstanceIdentifier<?> identifier,
+ @Nonnull final ReadContext ctx) throws ReadFailedException;
+
+ /**
+ * Provides details of interface
+ *
+ * @param identifier id of currently processed data
+ * @param ctx context of current transaction
+ * @param interfaceName name of requested interface
+ * @return {@link SwInterfaceDetails} of requested interface
+ * @throws ReadFailedException if dumping of data was unsuccessful
+ */
+ @Nullable
+ SwInterfaceDetails getInterfaceDetail(@Nonnull final InstanceIdentifier<?> identifier,
+ @Nonnull final ReadContext ctx,
+ @Nonnull final String interfaceName) throws ReadFailedException;
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerImpl.java
new file mode 100644
index 000000000..0aee8e459
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerImpl.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read.cache;
+
+import static io.fd.hc2vpp.common.translate.util.JvppReplyConsumer.INSTANCE;
+import static java.util.stream.Collectors.toMap;
+
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.honeycomb.translate.util.read.cache.StaticCacheKeyFactory;
+import io.fd.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.jvpp.core.dto.SwInterfaceDump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import io.fd.jvpp.core.types.InterfaceIndex;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manager for dump data of interfaces/sub-interfaces
+ */
+final class InterfaceCacheDumpManagerImpl implements InterfaceCacheDumpManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceCacheDumpManagerImpl.class);
+
+ // byNameIndex must be cached, not held as reference here, to have it destroyed with cache after transaction
+ static final String BY_NAME_INDEX_KEY = InterfaceCacheDumpManagerImpl.class.getName() + "_byNameIndex";
+ private NamingContext namingContext;
+ private final DumpCacheManager<SwInterfaceDetailsReplyDump, String> specificDumpManager;
+ private final DumpCacheManager<SwInterfaceDetailsReplyDump, Void> fullDumpManager;
+
+ InterfaceCacheDumpManagerImpl(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext namingContext) {
+ this.namingContext = namingContext;
+ specificDumpManager = specificInterfaceDumpManager(jvpp);
+ fullDumpManager = fullInterfaceDumpManager(jvpp,
+ new StaticCacheKeyFactory(InterfaceCacheDumpManagerImpl.class.getName() + "_dump", SwInterfaceDetailsReplyDump.class));
+ }
+
+ @Override
+ @Nonnull
+ public synchronized Stream<SwInterfaceDetails> getInterfaces(@Nonnull final InstanceIdentifier<?> identifier,
+ @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ LOG.debug("Reading all interfaces[{}]", identifier);
+ return initMapAndGet(identifier, ctx).entrySet().stream().map(Map.Entry::getValue);
+ }
+
+ @Override
+ @Nullable
+ public synchronized SwInterfaceDetails getInterfaceDetail(@Nonnull final InstanceIdentifier<?> identifier,
+ @Nonnull final ReadContext ctx,
+ @Nonnull final String interfaceName)
+ throws ReadFailedException {
+ final Map<String, SwInterfaceDetails> interfaceIndex = getMap(ctx);
+
+ // does not attempt to cover cases with concurrent updates, as tx should be atomic
+ if (interfaceIndex != null) {
+ // tries to find interface in map
+ return interfaceIndex.get(interfaceName);
+ } else {
+ // if map is not present, use specific dump(it will be cached standard way, under key constructed from IID)
+ return dumpSpecificDetail(identifier, ctx, interfaceName);
+ }
+ }
+
+ private SwInterfaceDetails dumpSpecificDetail(@Nonnull final InstanceIdentifier<?> identifier,
+ @Nonnull final ReadContext ctx,
+ @Nonnull final String interfaceName)
+ throws ReadFailedException {
+ LOG.debug("Interface {} not present in cached data, performing specific dump[{}]", interfaceName,
+ identifier);
+ final SwInterfaceDetailsReplyDump reply =
+ specificDumpManager.getDump(identifier, ctx.getModificationCache(), interfaceName)
+ .orElse(new SwInterfaceDetailsReplyDump());
+
+ if (reply.swInterfaceDetails.isEmpty()) {
+ return null;
+ }
+
+ return reply.swInterfaceDetails.get(0);
+ }
+
+ private Map<String, SwInterfaceDetails> initMapAndGet(final InstanceIdentifier<?> identifier, final ReadContext ctx)
+ throws ReadFailedException {
+
+ final ModificationCache cache = ctx.getModificationCache();
+ if (!cache.containsKey(BY_NAME_INDEX_KEY)) {
+ LOG.debug("Performing dump[{}]", identifier);
+ final SwInterfaceDetailsReplyDump dump =
+ fullDumpManager.getDump(identifier, cache)
+ .orElse(new SwInterfaceDetailsReplyDump());
+
+ // naming context initialization must be done here, as it is uses getName in next step, therefore it would
+ // create artificial mapping for every interface, because this happens before interface dump is processed
+ dump.swInterfaceDetails.forEach((elt) -> {
+ // Store interface name from VPP in context if not yet present
+ if (!namingContext.containsName(elt.swIfIndex, ctx.getMappingContext())) {
+ namingContext.addName(elt.swIfIndex, ByteDataTranslator.INSTANCE.toString(elt.interfaceName),
+ ctx.getMappingContext());
+ }
+ LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP",
+ getInterfaceName(ctx, elt),
+ elt.interfaceName,
+ elt.swIfIndex);
+ });
+
+ final Map<String, SwInterfaceDetails> freshIndex = dump.swInterfaceDetails.stream()
+ .collect(toMap(detail -> getInterfaceName(ctx, detail),
+ detail -> detail));
+ putMap(freshIndex, ctx);
+ }
+
+ return getMap(ctx);
+ }
+
+ private String getInterfaceName(final ReadContext ctx, final SwInterfaceDetails elt) {
+ return namingContext.getName(elt.swIfIndex, ctx.getMappingContext());
+ }
+
+ private static Map<String, SwInterfaceDetails> getMap(final ReadContext ctx) {
+ return (Map<String, SwInterfaceDetails>) ctx.getModificationCache().get(BY_NAME_INDEX_KEY);
+ }
+
+ private static void putMap(final Map<String, SwInterfaceDetails> map, final ReadContext ctx) {
+ ctx.getModificationCache().put(BY_NAME_INDEX_KEY, map);
+ }
+
+
+ private static DumpCacheManager<SwInterfaceDetailsReplyDump, Void> fullInterfaceDumpManager(
+ final FutureJVppCore jvpp,
+ final StaticCacheKeyFactory cacheKeyFactory) {
+ return new DumpCacheManager.DumpCacheManagerBuilder<SwInterfaceDetailsReplyDump, Void>()
+ .withExecutor(fullInterfaceDumpExecutor(jvpp))
+ .withCacheKeyFactory(cacheKeyFactory)
+ .acceptOnly(SwInterfaceDetailsReplyDump.class)
+ .build();
+ }
+
+ private static DumpCacheManager<SwInterfaceDetailsReplyDump, String> specificInterfaceDumpManager(
+ final FutureJVppCore jvpp) {
+ return new DumpCacheManager.DumpCacheManagerBuilder<SwInterfaceDetailsReplyDump, String>()
+ .withExecutor(specificInterfaceDumpExecutor(jvpp))
+ .acceptOnly(SwInterfaceDetailsReplyDump.class)
+ .build();
+ }
+
+ private static EntityDumpExecutor<SwInterfaceDetailsReplyDump, Void> fullInterfaceDumpExecutor(
+ final FutureJVppCore api) {
+ return (identifier, params) -> {
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.swIfIndex = new InterfaceIndex();
+ request.swIfIndex.interfaceindex = ~0;
+ request.nameFilter = "".getBytes();
+ request.nameFilterValid = 0;
+
+ final CompletableFuture<SwInterfaceDetailsReplyDump>
+ swInterfaceDetailsReplyDumpCompletableFuture = api.swInterfaceDump(request).toCompletableFuture();
+ return INSTANCE.getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, identifier);
+ };
+ }
+
+ private static EntityDumpExecutor<SwInterfaceDetailsReplyDump, String> specificInterfaceDumpExecutor(
+ final FutureJVppCore api) {
+ return (identifier, ifaceName) -> {
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.swIfIndex = new InterfaceIndex();
+ request.swIfIndex.interfaceindex =~0;
+ request.nameFilter = ifaceName.getBytes();
+ request.nameFilterValid = 1;
+
+ final CompletableFuture<SwInterfaceDetailsReplyDump>
+ swInterfaceDetailsReplyDumpCompletableFuture = api.swInterfaceDump(request).toCompletableFuture();
+ return INSTANCE.getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, identifier);
+ };
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerProvider.java
new file mode 100644
index 000000000..6fb4f730f
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceCacheDumpManagerProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read.cache;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import javax.inject.Named;
+
+public class InterfaceCacheDumpManagerProvider implements Provider<InterfaceCacheDumpManager> {
+
+ @Inject
+ private FutureJVppCore jvpp;
+
+ @Inject
+ @Named("interface-context")
+ private NamingContext namingContext;
+
+ @Override
+ public InterfaceCacheDumpManager get() {
+ return new InterfaceCacheDumpManagerImpl(jvpp, namingContext);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManager.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManager.java
new file mode 100644
index 000000000..d23f06eac
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManager.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.hc2vpp.v3po.read.cache;
+
+public interface InterfaceStatisticsManager {
+
+ boolean isStatisticsEnabled();
+
+ void enableStatistics();
+
+ void disableStatistics();
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerImpl.java
new file mode 100644
index 000000000..8450d3484
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerImpl.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.hc2vpp.v3po.read.cache;
+
+public class InterfaceStatisticsManagerImpl implements InterfaceStatisticsManager {
+
+ private boolean isEnabled;
+
+ @Override
+ public boolean isStatisticsEnabled() {
+ return isEnabled;
+ }
+
+ @Override
+ public void enableStatistics() {
+ isEnabled = true;
+ }
+
+ @Override
+ public void disableStatistics() {
+ isEnabled = false;
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerProvider.java
new file mode 100644
index 000000000..b62487b56
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/cache/InterfaceStatisticsManagerProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech.
+ *
+ * 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.hc2vpp.v3po.read.cache;
+
+import com.google.inject.Provider;
+
+public class InterfaceStatisticsManagerProvider implements Provider<InterfaceStatisticsManager> {
+
+ @Override
+ public InterfaceStatisticsManager get() {
+ return new InterfaceStatisticsManagerImpl();
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/pbb/PbbRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/pbb/PbbRewriteCustomizer.java
new file mode 100644
index 000000000..a77a7db7d
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/pbb/PbbRewriteCustomizer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.hc2vpp.v3po.read.pbb;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.PbbRewriteInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewrite;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.pbb.rev161214.interfaces._interface.PbbRewriteBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class PbbRewriteCustomizer extends FutureJVppCustomizer
+ implements ReaderCustomizer<PbbRewrite, PbbRewriteBuilder> {
+
+ public PbbRewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore) {
+ super(futureJVppCore);
+ }
+
+ @Nonnull
+ @Override
+ public PbbRewriteBuilder getBuilder(@Nonnull final InstanceIdentifier<PbbRewrite> id) {
+ return new PbbRewriteBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<PbbRewrite> id,
+ @Nonnull final PbbRewriteBuilder builder, @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ //TODO implement read after https://jira.fd.io/browse/VPP-468 + init
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
+ @Nonnull final PbbRewrite readValue) {
+ ((PbbRewriteInterfaceAugmentationBuilder) parentBuilder).setPbbRewrite(readValue);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/AbstractMirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/AbstractMirroredInterfacesCustomizer.java
new file mode 100644
index 000000000..12dcbe3cc
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/AbstractMirroredInterfacesCustomizer.java
@@ -0,0 +1,114 @@
+/*
+ * 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.hc2vpp.v3po.read.span;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer;
+import io.fd.jvpp.core.dto.SwInterfaceSpanDetailsReplyDump;
+import io.fd.jvpp.core.dto.SwInterfaceSpanDump;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.SpanState;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterface;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class AbstractMirroredInterfacesCustomizer
+ extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<MirroredInterfaces, MirroredInterfacesBuilder>, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractMirroredInterfacesCustomizer.class);
+
+ private final NamingContext ifcContext;
+ private final Function<InstanceIdentifier<MirroredInterfaces>, String> destinationInterfaceNameExtractor;
+
+ protected AbstractMirroredInterfacesCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext ifcContext,
+ @Nonnull final Function<InstanceIdentifier<MirroredInterfaces>, String> destinationInterfaceNameExtractor) {
+ super(futureJVppCore);
+ this.ifcContext = ifcContext;
+ this.destinationInterfaceNameExtractor = destinationInterfaceNameExtractor;
+ }
+
+ @Nonnull
+ @Override
+ public MirroredInterfacesBuilder getBuilder(@Nonnull final InstanceIdentifier<MirroredInterfaces> id) {
+ return new MirroredInterfacesBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<MirroredInterfaces> id,
+ @Nonnull final MirroredInterfacesBuilder builder, @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ LOG.trace("Reading mirrored interfaces under: {}", id);
+ final int dstId = destinationInterfaceIndex(id, ctx.getMappingContext());
+
+ final SwInterfaceSpanDetailsReplyDump replyForRead;
+ if (ctx.getModificationCache().containsKey(getCacheKey())) {
+ replyForRead = (SwInterfaceSpanDetailsReplyDump) ctx.getModificationCache().get(getCacheKey());
+ } else {
+ replyForRead = getReplyForRead(getFutureJVpp().swInterfaceSpanDump(
+ new SwInterfaceSpanDump()).toCompletableFuture(), id);
+ ctx.getModificationCache().put(getCacheKey(), replyForRead);
+ }
+
+ final List<MirroredInterface> mirroredInterfaces =
+ replyForRead.swInterfaceSpanDetails.stream()
+ .filter(detail -> detail.swIfIndexTo == dstId)
+ .filter(detail -> detail.state != 0) // filters disabled(we use disabled as delete)
+ .map(detail -> {
+ final String interfaceName =
+ ifcContext.getName(detail.swIfIndexFrom, ctx.getMappingContext());
+ return new MirroredInterfaceBuilder()
+ .setIfaceRef(interfaceName)
+ .withKey(new MirroredInterfaceKey(interfaceName))
+ .setState(SpanState.forValue(detail.state))
+ .build();
+ }
+ )
+ .collect(Collectors.toList());
+
+ LOG.debug("Mirrored interfaces for: {} read as: {}", id, mirroredInterfaces);
+
+ if (!mirroredInterfaces.isEmpty()) {
+ builder.setMirroredInterface(mirroredInterfaces);
+ }
+ }
+
+ private String getCacheKey() {
+ return getClass().getName();
+ }
+
+ private int destinationInterfaceIndex(@Nonnull final InstanceIdentifier<MirroredInterfaces> id,
+ @Nonnull final MappingContext mappingContext) {
+ final String destinationInterfaceName = destinationInterfaceNameExtractor.apply(id);
+ return ifcContext.getIndex(destinationInterfaceName, mappingContext);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/InterfaceMirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/InterfaceMirroredInterfacesCustomizer.java
new file mode 100644
index 000000000..841ee85da
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/InterfaceMirroredInterfacesCustomizer.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read.span;
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.InterfaceCustomizer;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.SpanBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev180220.interfaces.Interface;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Provides interface-specific logic to read/init port mirroring configuration
+ */
+public class InterfaceMirroredInterfacesCustomizer extends AbstractMirroredInterfacesCustomizer {
+
+ public InterfaceMirroredInterfacesCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext ifcContext) {
+ super(futureJVppCore, ifcContext, id -> id.firstKeyOf(Interface.class).getName());
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<MirroredInterfaces> id,
+ @Nonnull final MirroredInterfaces readValue,
+ @Nonnull final ReadContext ctx) {
+ final InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces> cfgId =
+ InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.interfaces._interface.Span.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces.class);
+ final org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces
+ cfgValue = new MirroredInterfacesBuilder()
+ .setMirroredInterface(Optional.ofNullable(readValue.getMirroredInterface()).orElse(Collections.emptyList())
+ .stream()
+ .map(mirroredInterface -> new MirroredInterfaceBuilder()
+ .setState(mirroredInterface.getState())
+ .withKey(new MirroredInterfaceKey(mirroredInterface.key().getIfaceRef()))
+ .setIfaceRef(mirroredInterface.getIfaceRef())
+ .build())
+ .collect(Collectors.toList()))
+ .build();
+ return Initialized.create(cfgId, cfgValue);
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull MirroredInterfaces mirroredInterfaces) {
+ ((SpanBuilder) builder).setMirroredInterfaces(mirroredInterfaces);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/SubInterfaceMirroredInterfacesCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/SubInterfaceMirroredInterfacesCustomizer.java
new file mode 100644
index 000000000..308edee8e
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/read/span/SubInterfaceMirroredInterfacesCustomizer.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 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.hc2vpp.v3po.read.span;
+
+
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.read.SubInterfaceCustomizer;
+import io.fd.hc2vpp.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.spi.read.Initialized;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.subinterface.span.rev170607.VppSubinterfaceSpanAugmentation;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.subinterface.span.rev170607.interfaces._interface.sub.interfaces.sub._interface.Span;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.subinterface.span.rev170607.interfaces._interface.sub.interfaces.sub._interface.SpanBuilder;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.vlan.rev180319.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Provides sub-interface-specific logic to read/init port mirroring configuration
+ */
+public class SubInterfaceMirroredInterfacesCustomizer extends AbstractMirroredInterfacesCustomizer {
+
+ public SubInterfaceMirroredInterfacesCustomizer(@Nonnull FutureJVppCore futureJVppCore, NamingContext ifcContext) {
+ super(futureJVppCore, ifcContext, SubInterfaceUtils::subInterfaceFullNameOperational);
+ }
+
+ @Nonnull
+ @Override
+ public Initialized<? extends DataObject> init(@Nonnull InstanceIdentifier<MirroredInterfaces> id,
+ @Nonnull MirroredInterfaces readValue,
+ @Nonnull ReadContext readContext) {
+ final InstanceIdentifier<org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces> cfgId =
+ SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class))
+ .augmentation(VppSubinterfaceSpanAugmentation.class)
+ .child(Span.class)
+ .child(org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces.class);
+
+ final org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfaces
+ cfgValue = new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.MirroredInterfacesBuilder()
+ .setMirroredInterface(
+ Optional.ofNullable(readValue.getMirroredInterface()).orElse(Collections.emptyList())
+ .stream()
+ .map(mirroredInterface -> new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceBuilder()
+ .withKey(new org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.v3po.rev190502.span.attributes.mirrored.interfaces.MirroredInterfaceKey(mirroredInterface.key().getIfaceRef()))
+ .setIfaceRef(mirroredInterface.getIfaceRef())
+ .setState(mirroredInterface.getState())
+ .build())
+ .collect(Collectors.toList()))
+ .build();
+
+ return Initialized.create(cfgId, cfgValue);
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull MirroredInterfaces mirroredInterfaces) {
+ ((SpanBuilder) builder).setMirroredInterfaces(mirroredInterfaces);
+ }
+}