summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-11-10 13:31:25 +0100
committerMarek Gradzki <mgradzki@cisco.com>2016-11-19 21:29:39 +0100
commit175197da8ea43335df3daeba4c6296fcd83a057c (patch)
tree110298a990c6191933c2ad65d1a06333bab76cee /v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate
parent1813bf59fa53e8eb913d34b212d45b227dead799 (diff)
Post split cleanup
- change groupIds - change packages - update poms Change-Id: I343c5a292a67de1dd50687870ca4ab5b7276e93e Signed-off-by: Maros Marsalek <mmarsale@cisco.com> Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate')
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java108
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java157
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java125
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java232
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java287
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java116
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java79
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java147
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java264
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java93
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java143
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java154
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java162
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java168
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java118
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java60
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java120
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java166
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java59
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java73
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java84
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java66
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java143
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java44
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java57
25 files changed, 3225 insertions, 0 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java
new file mode 100644
index 000000000..33b71b1e4
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/EthernetCustomizer.java
@@ -0,0 +1,108 @@
+/*
+ * 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.interfacesstate;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Ethernet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.EthernetBuilder;
+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 EthernetCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<Ethernet, EthernetBuilder>, InterfaceDataTranslator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class);
+ private NamingContext interfaceContext;
+
+ public EthernetCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
+ @Nonnull final Ethernet readValue) {
+ ((VppInterfaceStateAugmentationBuilder) 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 = getVppInterfaceDetails(getFutureJVpp(), id, key.getName(),
+ interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache(), LOG);
+
+ if (iface.linkMtu != 0) {
+ 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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.EthernetBuilder()
+ .setMtu(readValue.getMtu())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Ethernet.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java
new file mode 100644
index 000000000..b31ab74d5
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/GreCustomizer.java
@@ -0,0 +1,157 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.GreTunnelDetails;
+import io.fd.vpp.jvpp.core.dto.GreTunnelDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.GreTunnelDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Gre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.GreBuilder;
+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 {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GreCustomizer.class);
+ private NamingContext interfaceContext;
+
+ public GreCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull Gre readValue) {
+ ((VppInterfaceStateAugmentationBuilder) 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(getFutureJVpp(), ctx.getModificationCache(), id, index, GreTunnel.class, LOG)) {
+ 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.isIpv6 == 1) {
+ final Ipv6Address dstIpv6 =
+ new Ipv6Address(parseAddress(swInterfaceGreDetails.dstAddress).getHostAddress());
+ builder.setDst(new IpAddress(dstIpv6));
+ final Ipv6Address srcIpv6 =
+ new Ipv6Address(parseAddress(swInterfaceGreDetails.srcAddress).getHostAddress());
+ builder.setSrc(new IpAddress(srcIpv6));
+ } else {
+ final byte[] dstBytes = Arrays.copyOfRange(swInterfaceGreDetails.dstAddress, 0, 4);
+ final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress());
+ builder.setDst(new IpAddress(dstIpv4));
+ final byte[] srcBytes = Arrays.copyOfRange(swInterfaceGreDetails.srcAddress, 0, 4);
+ final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress());
+ builder.setSrc(new IpAddress(srcIpv4));
+ }
+ builder.setOuterFibId((long) swInterfaceGreDetails.outerFibId);
+ LOG.debug("Gre tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Nonnull
+ private static InetAddress parseAddress(@Nonnull final byte[] addr) {
+ try {
+ return InetAddress.getByAddress(addr);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e);
+ }
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.GreBuilder()
+ .setDst(readValue.getDst())
+ .setSrc(readValue.getSrc())
+ .setOuterFibId(readValue.getOuterFibId())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Gre.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java
new file mode 100644
index 000000000..3893d37a1
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterconnectionReadUtils.java
@@ -0,0 +1,125 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDump;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainSwIfDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.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 FutureJVppCore futureJVppCore;
+ private final NamingContext interfaceContext;
+ private final NamingContext bridgeDomainContext;
+
+ InterconnectionReadUtils(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext) {
+ this.futureJVppCore = 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");
+ }
+
+ @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 = getVppInterfaceDetails(futureJVppCore, id, ifaceName,
+ ifaceId, ctx.getModificationCache(), LOG);
+ LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface);
+
+ final BridgeDomainDetailsReplyDump dumpReply = getDumpReply(id);
+ final Optional<BridgeDomainSwIfDetails> bdForInterface = getBridgeDomainForInterface(ifaceId, dumpReply);
+ if (bdForInterface.isPresent()) {
+ final BridgeDomainSwIfDetails bdSwIfDetails = bdForInterface.get();
+ final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder();
+ bbBuilder.setBridgeDomain(bridgeDomainContext.getName(bdSwIfDetails.bdId, ctx.getMappingContext()));
+
+ // Set BVI if the bridgeDomainDetails.bviSwIfIndex == current sw if index
+ final Optional<BridgeDomainDetails> bridgeDomainForInterface =
+ getBridgeDomainForInterface(dumpReply, bdForInterface.get().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 (bdSwIfDetails.shg != 0) {
+ bbBuilder.setSplitHorizonGroup((short) bdSwIfDetails.shg);
+ }
+ return bbBuilder.build();
+ }
+ // TODO HONEYCOMB-190 is there a way to check if interconnection is XconnectBased?
+
+ return null;
+ }
+
+ private Optional<BridgeDomainSwIfDetails> getBridgeDomainForInterface(final int ifaceId,
+ final BridgeDomainDetailsReplyDump reply) {
+ if (null == reply || null == reply.bridgeDomainSwIfDetails || reply.bridgeDomainSwIfDetails.isEmpty()) {
+ return Optional.empty();
+ }
+ // interface can be added to only one BD only
+ return reply.bridgeDomainSwIfDetails.stream().filter(a -> a.swIfIndex == ifaceId).findFirst();
+ }
+
+ private Optional<BridgeDomainDetails> getBridgeDomainForInterface(final BridgeDomainDetailsReplyDump reply,
+ int bdId) {
+ return reply.bridgeDomainDetails.stream().filter(a -> a.bdId == bdId).findFirst();
+ }
+
+ private BridgeDomainDetailsReplyDump getDumpReply(@Nonnull final InstanceIdentifier<?> id)
+ throws ReadFailedException {
+ // We need to perform full bd dump, because there is no way
+ // to ask VPP for BD details given interface id/name (TODO HONEYCOMB-190 add it to vpp.api?)
+ // TODO HONEYCOMB-190 cache dump result
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = -1;
+
+ final CompletableFuture<BridgeDomainDetailsReplyDump> bdCompletableFuture =
+ futureJVppCore.bridgeDomainSwIfDump(request).toCompletableFuture();
+ return getReplyForRead(bdCompletableFuture, id);
+
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java
new file mode 100644
index 000000000..70bc0c62b
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceCustomizer.java
@@ -0,0 +1,232 @@
+/*
+ * 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.interfacesstate;
+
+import io.fd.hc2vpp.v3po.DisabledInterfacesManager;
+import io.fd.honeycomb.translate.MappingContext;
+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.spi.read.Initialized;
+import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer;
+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.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.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-state/interface.
+ */
+public class InterfaceCustomizer extends FutureJVppCustomizer
+ implements InitializingListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder>, ByteDataTranslator,
+ InterfaceDataTranslator {
+
+ public static final String DUMPED_IFCS_CONTEXT_KEY =
+ InterfaceCustomizer.class.getName() + "dumpedInterfacesDuringGetAllIds";
+ private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class);
+ private final NamingContext interfaceNamingContext;
+ private final DisabledInterfacesManager interfaceDisableContext;
+
+ public InterfaceCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceNamingContext,
+ @Nonnull final DisabledInterfacesManager interfaceDisableContext) {
+ super(jvpp);
+ this.interfaceNamingContext = interfaceNamingContext;
+ this.interfaceDisableContext = interfaceDisableContext;
+ }
+
+ public static void cacheInterfaceDump(final @Nonnull ReadContext context, final SwInterfaceDetailsReplyDump ifaces) {
+ context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream()
+ .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)));
+ }
+
+ @Nonnull
+ @SuppressWarnings("unchecked")
+ public static Map<Integer, SwInterfaceDetails> getCachedInterfaceDump(@Nonnull final ModificationCache ctx) {
+ return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null
+ ? new HashMap<>()
+ // allow customizers to update the cache
+ : (Map<Integer, SwInterfaceDetails>) ctx.get(DUMPED_IFCS_CONTEXT_KEY);
+ }
+
+ private static boolean isRegularInterface(final SwInterfaceDetails iface) {
+ return iface.subId == 0;
+ }
+
+ @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;
+ }
+
+ // Pass cached details from getAllIds to getDetails to avoid additional dumps
+ final SwInterfaceDetails iface = getVppInterfaceDetails(getFutureJVpp(), id, ifaceName,
+ index, ctx.getModificationCache(), LOG);
+ 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 SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilter = "".getBytes();
+ request.nameFilterValid = 0;
+
+ final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture =
+ getFutureJVpp().swInterfaceDump(request).toCompletableFuture();
+ final SwInterfaceDetailsReplyDump ifaces =
+ getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id);
+
+ if (null == ifaces || null == ifaces.swInterfaceDetails) {
+ LOG.debug("No interfaces for :{} found in VPP", id);
+ return Collections.emptyList();
+ }
+
+ // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes
+ cacheInterfaceDump(context, ifaces);
+
+ final MappingContext mappingCtx = context.getMappingContext();
+ final Set<Integer> interfacesIdxs = ifaces.swInterfaceDetails.stream()
+ .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))
+ .map((elt) -> {
+ // Store interface name from VPP in context if not yet present
+ if (!interfaceNamingContext.containsName(elt.swIfIndex, mappingCtx)) {
+ interfaceNamingContext.addName(elt.swIfIndex, toString(elt.interfaceName),
+ mappingCtx);
+ }
+ LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP",
+ interfaceNamingContext.getName(elt.swIfIndex, mappingCtx),
+ elt.interfaceName,
+ elt.swIfIndex);
+
+ return elt;
+ })
+ // filter out sub-interfaces
+ .filter(InterfaceCustomizer::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) {
+ ((InterfacesStateBuilder) builder).setInterface(readData);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.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.rev140508.interfaces.InterfaceBuilder()
+ .setName(readValue.getName())
+ .setType(readValue.getType())
+ .setEnabled(AdminStatus.Up.equals(readValue.getAdminStatus()))
+ // Not present in interfaces-state
+ // .setLinkUpDownTrapEnable()
+ .build());
+ }
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.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.rev140508.interfaces.Interface.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey(
+ id.firstKeyOf(Interface.class).getName()));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java
new file mode 100644
index 000000000..a0d292a4f
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/InterfaceDataTranslator.java
@@ -0,0 +1,287 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.math.BigInteger;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CompletionStage;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Gauge64;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.GreTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Loopback;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+
+public interface InterfaceDataTranslator extends ByteDataTranslator, JvppReplyConsumer {
+
+ Gauge64 vppLinkSpeed0 = new Gauge64(BigInteger.ZERO);
+ Gauge64 vppLinkSpeed1 = new Gauge64(BigInteger.valueOf(10L * 1000000));
+ Gauge64 vppLinkSpeed2 = new Gauge64(BigInteger.valueOf(100L * 1000000));
+ Gauge64 vppLinkSpeed4 = new Gauge64(BigInteger.valueOf(1000L * 1000000));
+ Gauge64 vppLinkSpeed8 = new Gauge64(BigInteger.valueOf(10000L * 1000000));
+ Gauge64 vppLinkSpeed16 = new Gauge64(BigInteger.valueOf(40000L * 1000000));
+ Gauge64 vppLinkSpeed32 = new Gauge64(BigInteger.valueOf(100000L * 1000000));
+
+ char[] HEX_CHARS = "0123456789abcdef".toCharArray();
+
+ int PHYSICAL_ADDRESS_LENGTH = 6;
+
+ Collector<SwInterfaceDetails, ?, SwInterfaceDetails> SINGLE_ITEM_COLLECTOR =
+ RWUtils.singleItemCollector();
+
+ /**
+ * Convert VPP's link speed bitmask to Yang type. 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G
+ *
+ * @param vppLinkSpeed Link speed in bitmask format from VPP.
+ * @return Converted value from VPP link speed
+ */
+ default Gauge64 vppInterfaceSpeedToYang(byte vppLinkSpeed) {
+ switch (vppLinkSpeed) {
+ case 1:
+ return vppLinkSpeed1;
+ case 2:
+ return vppLinkSpeed2;
+ case 4:
+ return vppLinkSpeed4;
+ case 8:
+ return vppLinkSpeed8;
+ case 16:
+ return vppLinkSpeed16;
+ case 32:
+ return vppLinkSpeed32;
+ default:
+ return vppLinkSpeed0;
+ }
+ }
+
+ default void appendHexByte(final StringBuilder sb, final byte b) {
+ final int v = b & 0xFF;
+ sb.append(HEX_CHARS[v >>> 4]);
+ sb.append(HEX_CHARS[v & 15]);
+ }
+
+ /**
+ * 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 < 6
+ */
+ default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) {
+ return vppPhysAddrToYang(vppPhysAddress, 0);
+ }
+
+ default String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress, final int startIndex) {
+ Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes");
+ final int endIndex = startIndex + PHYSICAL_ADDRESS_LENGTH;
+ checkArgument(endIndex <= vppPhysAddress.length,
+ "Invalid physical address size (%s) for given startIndex (%s), expected >= %s", vppPhysAddress.length,
+ startIndex, endIndex);
+ return printHexBinary(vppPhysAddress, startIndex, endIndex);
+ }
+
+ default String printHexBinary(@Nonnull final byte[] bytes) {
+ Objects.requireNonNull(bytes, "bytes array should not be null");
+ return printHexBinary(bytes, 0, bytes.length);
+ }
+
+ default String printHexBinary(@Nonnull final byte[] bytes, final int startIndex, final int endIndex) {
+ StringBuilder str = new StringBuilder();
+
+ appendHexByte(str, bytes[startIndex]);
+ for (int i = startIndex + 1; i < endIndex; i++) {
+ str.append(":");
+ appendHexByte(str, bytes[i]);
+ }
+
+ return str.toString();
+ }
+
+ /**
+ * 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;
+ }
+
+
+ /**
+ * Queries VPP for interface description given interface key.
+ *
+ * @param futureJVppCore VPP Java Future API
+ * @param id InstanceIdentifier, which is passed in ReadFailedException
+ * @param name interface name
+ * @param index VPP index of the interface
+ * @param ctx per-tx scope context containing cached dump with all the interfaces. If the cache is not
+ * available or outdated, another dump will be performed.
+ * @return SwInterfaceDetails DTO or null if interface was not found
+ * @throws IllegalArgumentException If interface cannot be found
+ * @throws ReadFailedException If read operation had failed
+ */
+ @Nonnull
+ default SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final InstanceIdentifier<?> id,
+ @Nonnull final String name, final int index,
+ @Nonnull final ModificationCache ctx,
+ @Nonnull final Logger callerLogger)
+ throws ReadFailedException {
+ requireNonNull(futureJVppCore, "futureJVppCore should not be null");
+ requireNonNull(name, "name should not be null");
+ requireNonNull(ctx, "ctx should not be null");
+
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilter = name.getBytes();
+ request.nameFilterValid = 1;
+
+ final Map<Integer, SwInterfaceDetails> allInterfaces = InterfaceCustomizer.getCachedInterfaceDump(ctx);
+
+ // Returned cached if available
+ if (allInterfaces.containsKey(index)) {
+ return allInterfaces.get(index);
+ }
+
+ SwInterfaceDetailsReplyDump ifaces;
+
+ CompletionStage<SwInterfaceDetailsReplyDump> requestFuture = futureJVppCore.swInterfaceDump(request);
+ ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id);
+ if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) {
+ request.nameFilterValid = 0;
+
+ callerLogger.warn("VPP returned null instead of interface by key {} and its not cached", name);
+ callerLogger.warn("Iterating through all the interfaces to find interface: {}", name);
+
+ // Or else just perform full dump and do inefficient filtering
+ requestFuture = futureJVppCore.swInterfaceDump(request);
+ ifaces = getReplyForRead(requestFuture.toCompletableFuture(), id);
+
+ // Update the cache
+ allInterfaces.clear();
+ allInterfaces
+ .putAll(ifaces.swInterfaceDetails.stream().collect(Collectors.toMap(d -> d.swIfIndex, d -> d)));
+
+ if (allInterfaces.containsKey(index)) {
+ return allInterfaces.get(index);
+ }
+ throw new IllegalArgumentException("Unable to find interface " + name);
+ }
+
+ // SwInterfaceDump's name filter does prefix match, so we need additional filtering:
+ final SwInterfaceDetails iface =
+ ifaces.swInterfaceDetails.stream().filter(d -> d.swIfIndex == index).collect(SINGLE_ITEM_COLLECTOR);
+ allInterfaces.put(index, iface); // update the cache
+ return iface;
+ }
+
+ /**
+ * 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 Tap.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("loop")) {
+ return Loopback.class;
+ }
+
+ return EthernetCsmacd.class;
+ }
+
+ /**
+ * Check interface type. Uses interface details from VPP to determine. Uses {@link
+ * #getVppInterfaceDetails(FutureJVppCore, InstanceIdentifier, String, int, ModificationCache, Logger)} internally
+ * so tries to utilize cache before asking VPP.
+ */
+ default boolean isInterfaceOfType(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final ModificationCache cache,
+ @Nonnull final InstanceIdentifier<?> id,
+ final int index,
+ @Nonnull final Class<? extends InterfaceType> ifcType,
+ @Nonnull final Logger callerLogger)
+ throws ReadFailedException {
+ final String name = id.firstKeyOf(Interface.class).getName();
+ final SwInterfaceDetails vppInterfaceDetails =
+ getVppInterfaceDetails(jvpp, id, name, index, cache, callerLogger);
+
+ return isInterfaceOfType(ifcType, vppInterfaceDetails);
+ }
+
+ default boolean isInterfaceOfType(final Class<? extends InterfaceType> ifcType,
+ final SwInterfaceDetails cachedDetails) {
+ return ifcType.equals(getInterfaceType(toString(cachedDetails.interfaceName)));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java
new file mode 100644
index 000000000..ed88370f5
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/L2Customizer.java
@@ -0,0 +1,116 @@
+/*
+ * 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.interfacesstate;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.L2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBasedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.XconnectBasedBuilder;
+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-state/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) {
+ super(futureJVppCore);
+ this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext);
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final L2 readValue) {
+ ((VppInterfaceStateAugmentationBuilder) 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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2> init(
+ @Nonnull final InstanceIdentifier<L2> id,
+ @Nonnull final L2 readValue,
+ @Nonnull final ReadContext ctx) {
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2Builder
+ l2Builder =
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.L2.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java
new file mode 100644
index 000000000..028e8e0d8
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ProxyArpCustomizer.java
@@ -0,0 +1,79 @@
+/*
+ * 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.interfacesstate;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProxyArpCustomizer extends FutureJVppCustomizer
+ implements ReaderCustomizer<ProxyArp,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArpBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class);
+ private final NamingContext interfaceContext;
+
+ public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) {
+ super(vppApi);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214
+ .interfaces.state._interface.ProxyArp readValue) {
+
+ ((VppInterfaceStateAugmentationBuilder) parentBuilder).setProxyArp(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state
+ ._interface.ProxyArpBuilder getBuilder(
+ @Nonnull InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight
+ .params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp> id) {
+
+ return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces
+ .state._interface.ProxyArpBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight
+ .params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.ProxyArp> id,
+ @Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po
+ .rev161214.interfaces.state._interface.ProxyArpBuilder builder,
+ @Nonnull ReadContext ctx) throws ReadFailedException {
+
+ //TODO: VPP-225 Implement fully when VPP Proxy ARP read API is available + add initializing
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ LOG.warn("Reading of ARP data not (yet) supported by VPP API");
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java
new file mode 100644
index 000000000..6906ebc0c
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/RewriteCustomizer.java
@@ -0,0 +1,147 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Preconditions;
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.util.SubInterfaceUtils;
+import io.fd.hc2vpp.common.translate.util.TagRewriteOperation;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+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.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1ad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214._802dot1q;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.Rewrite;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.l2.RewriteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTagsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.tag.rewrite.PushTagsKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading vlan tag-rewrite configuration state form the VPP.
+ */
+public class RewriteCustomizer extends FutureJVppCustomizer
+ 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 NamingContext interfaceContext;
+
+ public RewriteCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJVppCore);
+ this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext 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 = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName,
+ interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG);
+ LOG.debug("VPP sub-interface details: {}", iface);
+
+ checkState(iface.subId != 0, "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.setKey(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/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java
new file mode 100644
index 000000000..9c13b382a
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceCustomizer.java
@@ -0,0 +1,264 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Preconditions;
+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.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.util.SubInterfaceUtils;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+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.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubInterfaceStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.SubinterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.SubInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.DefaultBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.UntaggedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Tags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.TagsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.Tag;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.tags.TagKey;
+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 NamingContext interfaceContext;
+
+ public SubInterfaceCustomizer(@Nonnull final FutureJVppCore jvpp,
+ @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext 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.setKey(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());
+
+ // TODO HONEYCOMB-189 if we know that full dump was already performed we could use cache
+ // (checking if getCachedInterfaceDump() returns non empty map is not enough, because
+ // we could be part of particular iface state read
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilter = "".getBytes();
+ request.nameFilterValid = 0;
+
+ final CompletableFuture<SwInterfaceDetailsReplyDump> swInterfaceDetailsReplyDumpCompletableFuture =
+ getFutureJVpp().swInterfaceDump(request).toCompletableFuture();
+ final SwInterfaceDetailsReplyDump ifaces =
+ getReplyForRead(swInterfaceDetailsReplyDumpCompletableFuture, id);
+
+ if (null == ifaces || null == ifaces.swInterfaceDetails) {
+ LOG.warn("Looking for sub-interfaces, but no interfaces found in VPP");
+ return Collections.emptyList();
+ }
+
+ // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes
+ context.getModificationCache()
+ .put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream()
+ .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)));
+
+ final List<SubInterfaceKey> interfacesKeys = ifaces.swInterfaceDetails.stream()
+ .filter(elt -> elt != null)
+ // accept only sub-interfaces for current iface:
+ .filter(elt -> elt.subId != 0 && 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 = getVppInterfaceDetails(getFutureJVpp(), id, subInterfaceName,
+ interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache(), LOG);
+ LOG.debug("VPP sub-interface details: {}", iface);
+
+ checkState(iface.subId != 0, "Interface returned by the VPP is not a sub-interface");
+
+ builder.setIdentifier(Long.valueOf(iface.subId));
+ builder.setKey(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.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.match.attributes.match.type.VlanTaggedBuilder()
+ .setVlanTagged(tagged.build()).build());
+ }
+ return match.build();
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.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.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.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.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.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.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface.class,
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey(
+ id.firstKeyOf(SubInterface.class).getIdentifier()));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java
new file mode 100644
index 000000000..1b98b41ef
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/SubInterfaceL2Customizer.java
@@ -0,0 +1,93 @@
+/*
+ * 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.interfacesstate;
+
+import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.L2Builder;
+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 extends FutureJVppCustomizer
+ 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) {
+ super(futureJVppCore);
+ this.icReadUtils = new InterconnectionReadUtils(futureJVppCore, interfaceContext, bridgeDomainContext);
+ }
+
+ @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<L2> init(
+ @Nonnull final InstanceIdentifier<L2> id,
+ @Nonnull final L2 readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id), readValue);
+ }
+
+ static InstanceIdentifier<L2> getCfgId(final InstanceIdentifier<L2> id) {
+ return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class))
+ .child(L2.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java
new file mode 100644
index 000000000..683450da3
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/TapCustomizer.java
@@ -0,0 +1,143 @@
+/*
+ * 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.interfacesstate;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceTapDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletionStage;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Tap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.TapBuilder;
+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 TapCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<Tap, TapBuilder>, InterfaceDataTranslator, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class);
+ public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds";
+ private NamingContext interfaceContext;
+
+ public TapCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull Tap readValue) {
+ ((VppInterfaceStateAugmentationBuilder) parentBuilder).setTap(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public TapBuilder getBuilder(@Nonnull InstanceIdentifier<Tap> id) {
+ return new TapBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id,
+ @Nonnull final TapBuilder 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(getFutureJVpp(), ctx.getModificationCache(), id, index,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Tap.class, LOG)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for tap interface: {}", key.getName());
+
+ @SuppressWarnings("unchecked")
+ Map<Integer, SwInterfaceTapDetails> mappedTaps =
+ (Map<Integer, SwInterfaceTapDetails>) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY);
+
+ if (mappedTaps == null) {
+ // Full Tap dump has to be performed here, no filter or anything is here to help so at least we cache it
+ final SwInterfaceTapDump request = new SwInterfaceTapDump();
+ final CompletionStage<SwInterfaceTapDetailsReplyDump> swInterfaceTapDetailsReplyDumpCompletionStage =
+ getFutureJVpp().swInterfaceTapDump(request);
+ final SwInterfaceTapDetailsReplyDump reply =
+ getReplyForRead(swInterfaceTapDetailsReplyDumpCompletionStage.toCompletableFuture(), id);
+
+ if (null == reply || null == reply.swInterfaceTapDetails) {
+ mappedTaps = Collections.emptyMap();
+ } else {
+ final List<SwInterfaceTapDetails> swInterfaceTapDetails = reply.swInterfaceTapDetails;
+ // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes
+ mappedTaps = swInterfaceTapDetails.stream()
+ .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails));
+ }
+
+ ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps);
+ }
+
+ final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index);
+ LOG.trace("Tap interface: {} attributes returned from VPP: {}", key.getName(), swInterfaceTapDetails);
+
+ builder.setTapName(toString(swInterfaceTapDetails.devName));
+ LOG.debug("Tap interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap> init(
+ @Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap readValue, @Nonnull final ReadContext ctx) {
+ // The MAC address is set from interface details, those details are retrieved from cache
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ final SwInterfaceDetails ifcDetails =
+ InterfaceCustomizer.getCachedInterfaceDump(ctx.getModificationCache()).get(index);
+
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.TapBuilder()
+ .setMac(new PhysAddress(vppPhysAddrToYang(ifcDetails.l2Address)))
+ .setTapName(readValue.getTapName())
+// tapBuilder.setDeviceInstance();
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap> getCfgId(
+ final InstanceIdentifier<Tap> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Tap.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java
new file mode 100644
index 000000000..6a918e842
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VhostUserCustomizer.java
@@ -0,0 +1,154 @@
+/*
+ * 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.interfacesstate;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceVhostUserDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletionStage;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUserRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VhostUserBuilder;
+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 extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<VhostUser, VhostUserBuilder>, InterfaceDataTranslator, JvppReplyConsumer {
+
+ public static final String DUMPED_VHOST_USERS_CONTEXT_KEY =
+ VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds";
+ private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class);
+ private NamingContext interfaceContext;
+
+ public VhostUserCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull VhostUser readValue) {
+ ((VppInterfaceStateAugmentationBuilder) 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());
+ if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VhostUser.class,
+ LOG)) {
+ return;
+ }
+
+ LOG.debug("Reading attributes for vhpost user interface: {}", key.getName());
+
+ @SuppressWarnings("unchecked")
+ Map<Integer, SwInterfaceVhostUserDetails> mappedVhostUsers =
+ (Map<Integer, SwInterfaceVhostUserDetails>) ctx.getModificationCache()
+ .get(DUMPED_VHOST_USERS_CONTEXT_KEY);
+
+ if (mappedVhostUsers == null) {
+ // Full VhostUser dump has to be performed here, no filter or anything is here to help so at least we cache it
+ final SwInterfaceVhostUserDump request = new SwInterfaceVhostUserDump();
+ final CompletionStage<SwInterfaceVhostUserDetailsReplyDump>
+ swInterfaceVhostUserDetailsReplyDumpCompletionStage =
+ getFutureJVpp().swInterfaceVhostUserDump(request);
+ final SwInterfaceVhostUserDetailsReplyDump reply =
+ getReplyForRead(swInterfaceVhostUserDetailsReplyDumpCompletionStage.toCompletableFuture(), id);
+
+ if (null == reply || null == reply.swInterfaceVhostUserDetails) {
+ mappedVhostUsers = Collections.emptyMap();
+ } else {
+ final List<SwInterfaceVhostUserDetails> swInterfaceVhostUserDetails =
+ reply.swInterfaceVhostUserDetails;
+ // Cache interfaces dump in per-tx context to later be used in readCurrentAttributes
+ mappedVhostUsers = swInterfaceVhostUserDetails.stream()
+ .collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails));
+ }
+
+ ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers);
+ }
+
+ // Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
+ final SwInterfaceVhostUserDetails swInterfaceVhostUserDetails = mappedVhostUsers.get(index);
+ 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));
+
+ LOG.debug("Vhost user interface: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser> init(
+ @Nonnull final InstanceIdentifier<VhostUser> id,
+ @Nonnull final VhostUser readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUserBuilder()
+ .setRole(readValue.getRole())
+ .setSocket(readValue.getSocket())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VhostUser.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java
new file mode 100644
index 000000000..d3174e643
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanCustomizer.java
@@ -0,0 +1,162 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetails;
+import io.fd.vpp.jvpp.core.dto.VxlanTunnelDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.VxlanTunnelDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.Vxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanBuilder;
+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 {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
+ private final NamingContext interfaceContext;
+
+ public VxlanCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull Vxlan readValue) {
+ ((VppInterfaceStateAugmentationBuilder) 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(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanTunnel.class, LOG)) {
+ 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) {
+ final Ipv6Address dstIpv6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanDetails.dstAddress).getHostAddress());
+ builder.setDst(new IpAddress(dstIpv6));
+ final Ipv6Address srcIpv6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanDetails.srcAddress).getHostAddress());
+ builder.setSrc(new IpAddress(srcIpv6));
+ } else {
+ final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.dstAddress, 0, 4);
+ final Ipv4Address dstIpv4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress());
+ builder.setDst(new IpAddress(dstIpv4));
+ final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanDetails.srcAddress, 0, 4);
+ final Ipv4Address srcIpv4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress());
+ builder.setSrc(new IpAddress(srcIpv4));
+ }
+ builder.setEncapVrfId((long) swInterfaceVxlanDetails.encapVrfId);
+ builder.setVni(new VxlanVni((long) swInterfaceVxlanDetails.vni));
+ LOG.debug("Vxlan tunnel: {}, id: {} attributes read as: {}", key.getName(), index, builder);
+ }
+
+ @Nonnull
+ private static InetAddress parseAddress(@Nonnull final byte[] addr) {
+ try {
+ return InetAddress.getByAddress(addr);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e);
+ }
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanBuilder()
+ .setDst(readValue.getDst())
+ .setSrc(readValue.getSrc())
+ .setEncapVrfId(readValue.getEncapVrfId())
+ .setVni(new VxlanVni(readValue.getVni()))
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Vxlan.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java
new file mode 100644
index 000000000..b10fef3e8
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/VxlanGpeCustomizer.java
@@ -0,0 +1,168 @@
+/*
+ * 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.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetails;
+import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.VxlanGpeTunnelDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeNextProtocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VxlanGpeVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.VxlanGpeBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VxlanGpeCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<VxlanGpe, VxlanGpeBuilder>, InterfaceDataTranslator, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class);
+ private NamingContext interfaceContext;
+
+ public VxlanGpeCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext) {
+ super(jvpp);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> parentBuilder,
+ @Nonnull VxlanGpe readValue) {
+ ((VppInterfaceStateAugmentationBuilder) parentBuilder).setVxlanGpe(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public VxlanGpeBuilder getBuilder(@Nonnull InstanceIdentifier<VxlanGpe> id) {
+ return new VxlanGpeBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VxlanGpe> id,
+ @Nonnull final VxlanGpeBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+
+ final InterfaceKey key = id.firstKeyOf(Interface.class);
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(getFutureJVpp(), ctx.getModificationCache(), id, index, VxlanGpeTunnel.class, LOG)) {
+ 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) {
+ final Ipv6Address remote6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.remote).getHostAddress());
+ builder.setRemote(new IpAddress(remote6));
+ final Ipv6Address local6 =
+ new Ipv6Address(parseAddress(swInterfaceVxlanGpeDetails.local).getHostAddress());
+ builder.setLocal(new IpAddress(local6));
+ } else {
+ final byte[] dstBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.remote, 0, 4);
+ final Ipv4Address remote4 = new Ipv4Address(parseAddress(dstBytes).getHostAddress());
+ builder.setRemote(new IpAddress(remote4));
+ final byte[] srcBytes = Arrays.copyOfRange(swInterfaceVxlanGpeDetails.local, 0, 4);
+ final Ipv4Address local4 = new Ipv4Address(parseAddress(srcBytes).getHostAddress());
+ builder.setLocal(new IpAddress(local4));
+ }
+ builder.setVni(new VxlanGpeVni((long) swInterfaceVxlanGpeDetails.vni));
+ builder.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);
+ }
+
+ @Nonnull
+ private static InetAddress parseAddress(@Nonnull final byte[] addr) {
+ try {
+ return InetAddress.getByAddress(addr);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Cannot create InetAddress from " + Arrays.toString(addr), e);
+ }
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.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.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.VxlanGpe.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java
new file mode 100644
index 000000000..713868d2e
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclCustomizer.java
@@ -0,0 +1,118 @@
+/*
+ * 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.interfacesstate.acl.ingress;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer;
+import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager;
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.Ingress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces.state._interface.acl.IngressBuilder;
+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 ingress ACLs enabled on given interface.
+ */
+public class AclCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<Ingress, IngressBuilder>, AclReader, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class);
+ private final NamingContext interfaceContext;
+ private final VppClassifierContextManager classifyTableContext;
+
+ public AclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext,
+ @Nonnull final VppClassifierContextManager classifyTableContext) {
+ super(jvpp);
+ this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
+ this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null");
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final Ingress readValue) {
+ ((AclBuilder) parentBuilder).setIngress(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier<Ingress> id) {
+ return new IngressBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ingress> id,
+ @Nonnull final IngressBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ LOG.debug("Reading attributes for interface ACL: {}", id);
+ final InterfaceKey interfaceKey = id.firstKeyOf(Interface.class);
+ checkArgument(interfaceKey != null, "No parent interface key found");
+
+ final ClassifyTableByInterface request = new ClassifyTableByInterface();
+ request.swIfIndex = interfaceContext.getIndex(interfaceKey.getName(), ctx.getMappingContext());
+
+ final ClassifyTableByInterfaceReply reply =
+ getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id);
+
+ builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext()));
+ builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext()));
+ builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext()));
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build());
+ }
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress> init(
+ @Nonnull final InstanceIdentifier<Ingress> id, @Nonnull final Ingress readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.IngressBuilder()
+ .setL2Acl(readValue.getL2Acl())
+ .setIp4Acl(readValue.getIp4Acl())
+ .setIp6Acl(readValue.getIp6Acl())
+ .build());
+ }
+
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress> getCfgId(
+ final InstanceIdentifier<Ingress> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(VppInterfaceAugmentation.class)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.Acl.class)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.interfaces._interface.acl.Ingress.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java
new file mode 100644
index 000000000..8f1b428b9
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/AclReader.java
@@ -0,0 +1,60 @@
+/*
+ * 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.interfacesstate.acl.ingress;
+
+import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager;
+import io.fd.honeycomb.translate.MappingContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip4AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.Ip6AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.base.attributes.L2AclBuilder;
+
+interface AclReader {
+
+ @Nonnull
+ default L2Acl readL2Acl(final int l2TableId, @Nonnull final VppClassifierContextManager classifyTableContext,
+ @Nonnull final MappingContext mappingContext) {
+ if (l2TableId == ~0) {
+ return null;
+ }
+ return new L2AclBuilder()
+ .setClassifyTable(classifyTableContext.getTableName(l2TableId, mappingContext)).build();
+ }
+
+ @Nonnull
+ default Ip4Acl readIp4Acl(final int ip4TableId, @Nonnull final VppClassifierContextManager classifyTableContext,
+ @Nonnull final MappingContext mappingContext) {
+ if (ip4TableId == ~0) {
+ return null;
+ }
+ return new Ip4AclBuilder()
+ .setClassifyTable(classifyTableContext.getTableName(ip4TableId, mappingContext)).build();
+ }
+
+ @Nonnull
+ default Ip6Acl readIp6Acl(final int ip6TableId, @Nonnull final VppClassifierContextManager classifyTableContext,
+ @Nonnull final MappingContext mappingContext) {
+ if (ip6TableId == ~0) {
+ return null;
+ }
+ return new Ip6AclBuilder()
+ .setClassifyTable(classifyTableContext.getTableName(ip6TableId, mappingContext)).build();
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java
new file mode 100644
index 000000000..4190619b8
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/acl/ingress/SubInterfaceAclCustomizer.java
@@ -0,0 +1,120 @@
+/*
+ * 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.interfacesstate.acl.ingress;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static io.fd.hc2vpp.v3po.util.SubInterfaceUtils.getSubInterfaceName;
+
+import io.fd.hc2vpp.v3po.vppclassifier.VppClassifierContextManager;
+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.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer;
+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.vpp.jvpp.core.dto.ClassifyTableByInterface;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.Ingress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.base.attributes.acl.IngressBuilder;
+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 ingress ACLs enabled on given sub-interface.
+ */
+public class SubInterfaceAclCustomizer extends FutureJVppCustomizer
+ implements InitializingReaderCustomizer<Ingress, IngressBuilder>, AclReader, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class);
+ private final NamingContext interfaceContext;
+ private final VppClassifierContextManager classifyTableContext;
+
+ public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore jvpp, @Nonnull final NamingContext interfaceContext,
+ @Nonnull final VppClassifierContextManager classifyTableContext) {
+ super(jvpp);
+ this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
+ this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null");
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final Ingress readValue) {
+ ((AclBuilder) parentBuilder).setIngress(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public IngressBuilder getBuilder(@Nonnull final InstanceIdentifier<Ingress> id) {
+ return new IngressBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ingress> id,
+ @Nonnull final IngressBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ LOG.debug("Reading attributes for sub-interface ACL: {}", id);
+ final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class);
+ checkArgument(parentInterfacekey != null, "No parent interface key found");
+ final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class);
+ checkArgument(subInterfacekey != null, "No sub-interface key found");
+ final String subInterfaceName =
+ getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue());
+
+ final ClassifyTableByInterface request = new ClassifyTableByInterface();
+ request.swIfIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext());
+
+ final ClassifyTableByInterfaceReply reply =
+ getReplyForRead(getFutureJVpp().classifyTableByInterface(request).toCompletableFuture(), id);
+
+ builder.setL2Acl(readL2Acl(reply.l2TableId, classifyTableContext, ctx.getMappingContext()));
+ builder.setIp4Acl(readIp4Acl(reply.ip4TableId, classifyTableContext, ctx.getMappingContext()));
+ builder.setIp6Acl(readIp6Acl(reply.ip6TableId, classifyTableContext, ctx.getMappingContext()));
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Attributes for ACL {} successfully read: {}", id, builder.build());
+ }
+ }
+
+ @Override
+ public Initialized<Ingress> init(
+ @Nonnull final InstanceIdentifier<Ingress> id,
+ @Nonnull final Ingress readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id), readValue);
+ }
+
+ static InstanceIdentifier<Ingress> getCfgId(
+ final InstanceIdentifier<Ingress> id) {
+ return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class))
+ .child(Acl.class)
+ .child(Ingress.class);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java
new file mode 100644
index 000000000..4a577ae60
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4AddressCustomizer.java
@@ -0,0 +1,166 @@
+/*
+ * 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.interfacesstate.ip;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.base.Preconditions;
+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.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory;
+import io.fd.hc2vpp.v3po.interfacesstate.InterfaceCustomizer;
+import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.core.dto.IpAddressDetails;
+import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.AddressKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLengthBuilder;
+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;
+
+/**
+ * Read customizer for interface Ipv4 addresses.
+ */
+public class Ipv4AddressCustomizer extends FutureJVppCustomizer
+ implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, Ipv4Reader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressCustomizer.class);
+ private static final String CACHE_KEY = Ipv4AddressCustomizer.class.getName();
+
+ private final NamingContext interfaceContext;
+ private final DumpCacheManager<IpAddressDetailsReplyDump, AddressDumpParams> dumpManager;
+
+ public Ipv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJVppCore);
+ this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
+ this.dumpManager =
+ new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, AddressDumpParams>()
+ .withExecutor(createExecutor(futureJVppCore))
+ // Key needs to contain interface ID to distinguish dumps between interfaces
+ .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(Interface.class)))
+ .build();
+ }
+
+ @Override
+ @Nonnull
+ public AddressBuilder getBuilder(@Nonnull InstanceIdentifier<Address> id) {
+ return new AddressBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull InstanceIdentifier<Address> id, @Nonnull AddressBuilder builder,
+ @Nonnull ReadContext ctx)
+ throws ReadFailedException {
+ LOG.debug("Reading attributes for interface address: {}", id);
+
+ final String interfaceName = id.firstKeyOf(Interface.class).getName();
+ final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext());
+ final Optional<IpAddressDetailsReplyDump> dumpOptional =
+ dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false));
+
+ if (!dumpOptional.isPresent() || dumpOptional.get().ipAddressDetails.isEmpty()) {
+ return;
+ }
+ final Optional<IpAddressDetails> ipAddressDetails =
+ findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp());
+
+ if (ipAddressDetails.isPresent()) {
+ final IpAddressDetails detail = ipAddressDetails.get();
+ builder.setIp(arrayToIpv4AddressNoZone(detail.ip))
+ .setSubnet(
+ new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Attributes for {} interface (id={}) address {} successfully read: {}",
+ interfaceName, interfaceIndex, id, builder.build());
+ }
+ }
+ }
+
+ @Override
+ public List<AddressKey> getAllIds(@Nonnull InstanceIdentifier<Address> id, @Nonnull ReadContext ctx)
+ throws ReadFailedException {
+ LOG.debug("Reading list of keys for interface addresses: {}", id);
+
+ final String interfaceName = id.firstKeyOf(Interface.class).getName();
+ final int interfaceIndex = interfaceContext.getIndex(interfaceName, ctx.getMappingContext());
+ final Optional<IpAddressDetailsReplyDump> dumpOptional =
+ dumpManager.getDump(id, ctx.getModificationCache(), new AddressDumpParams(interfaceIndex, false));
+
+ return getAllIpv4AddressIds(dumpOptional, AddressKey::new);
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull List<Address> readData) {
+ ((Ipv4Builder) builder).setAddress(readData);
+ }
+
+ @Override
+ public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address> init(
+ @Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id),
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder()
+ .setIp(readValue.getIp())
+ .setSubnet(getSubnet(readValue))
+ .build());
+ }
+
+ private static Subnet getSubnet(final Address address) {
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.Subnet
+ subnet = address.getSubnet();
+
+ // Only prefix length supported
+ Preconditions.checkArgument(
+ subnet instanceof org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength);
+
+ return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLengthBuilder()
+ .setPrefixLength(
+ ((org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength) subnet)
+ .getPrefixLength()).build();
+ }
+
+ static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address> getCfgId(
+ final InstanceIdentifier<Address> id) {
+ return InterfaceCustomizer.getCfgId(RWUtils.cutId(id, Interface.class))
+ .augmentation(Interface1.class)
+ .child(Ipv4.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey(id.firstKeyOf(Address.class).getIp()));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java
new file mode 100644
index 000000000..316f8ec47
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Customizer.java
@@ -0,0 +1,59 @@
+/*
+ * 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.interfacesstate.ip;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Ipv4Customizer extends FutureJVppCustomizer implements ReaderCustomizer<Ipv4, Ipv4Builder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class);
+
+ public Ipv4Customizer(@Nonnull final FutureJVppCore futureJVppCore) {
+ super(futureJVppCore);
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final Ipv4 readValue) {
+ ((Interface2Builder) parentBuilder).setIpv4(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public Ipv4Builder getBuilder(@Nonnull final InstanceIdentifier<Ipv4> id) {
+ return new Ipv4Builder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id, @Nonnull final Ipv4Builder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ LOG.debug("Reading Ipv4 leaves (mtu, forwarding) is not supported by VPP API");
+ }
+
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java
new file mode 100644
index 000000000..a32f8f20c
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4NeighbourCustomizer.java
@@ -0,0 +1,73 @@
+/*
+ * 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.interfacesstate.ip;
+
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.NeighborKey;
+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;
+
+/**
+ * Operational data read operation customizer for {@link Neighbor}<br>
+ * Currently not supported in jvpp, so this is only dummy implementation<br>
+ */
+public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer
+ implements ListReaderCustomizer<Neighbor, NeighborKey, NeighborBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Ipv4NeighbourCustomizer.class);
+
+ public Ipv4NeighbourCustomizer(FutureJVppCore futureJVppCore) {
+ super(futureJVppCore);
+ }
+
+ @Override
+ public NeighborBuilder getBuilder(InstanceIdentifier<Neighbor> id) {
+ return new NeighborBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(InstanceIdentifier<Neighbor> id, NeighborBuilder builder, ReadContext ctx)
+ throws ReadFailedException {
+ //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first + implement init
+ LOG.warn("Operation not supported");
+ }
+
+ @Override
+ public List<NeighborKey> getAllIds(InstanceIdentifier<Neighbor> id, ReadContext context)
+ throws ReadFailedException {
+ //TODO - not supported, implement https://jira.fd.io/browse/VPP-164 first
+ LOG.warn("Operation not supported,returning empty List");
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void merge(Builder<? extends DataObject> builder, List<Neighbor> readData) {
+ ((Ipv4Builder) builder).setNeighbor(readData);
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java
new file mode 100644
index 000000000..729ca097d
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv4Reader.java
@@ -0,0 +1,84 @@
+/*
+ * 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.interfacesstate.ip;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Optional;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.vpp.jvpp.core.dto.IpAddressDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import io.fd.vpp.jvpp.core.dto.IpAddressDetails;
+import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump;
+
+/**
+ * Utility class providing Ipv4 read support.
+ */
+interface Ipv4Reader extends Ipv4Translator, JvppReplyConsumer {
+
+ @Nonnull
+ default <T extends Identifier> List<T> getAllIpv4AddressIds(
+ final Optional<IpAddressDetailsReplyDump> dumpOptional,
+ @Nonnull final Function<Ipv4AddressNoZone, T> keyConstructor) {
+ if (dumpOptional.isPresent() && dumpOptional.get().ipAddressDetails != null) {
+ return dumpOptional.get().ipAddressDetails.stream()
+ .map(detail -> keyConstructor.apply(arrayToIpv4AddressNoZone(detail.ip)))
+ .collect(Collectors.toList());
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ default Optional<IpAddressDetails> findIpAddressDetailsByIp(
+ final Optional<IpAddressDetailsReplyDump> dump,
+ @Nonnull final Ipv4AddressNoZone ip) {
+ checkNotNull(ip, "ip address should not be null");
+
+ if (dump.isPresent() && dump.get().ipAddressDetails != null) {
+ final List<IpAddressDetails> details = dump.get().ipAddressDetails;
+
+ return Optional.of(details.stream()
+ .filter(singleDetail -> ip.equals(arrayToIpv4AddressNoZone(singleDetail.ip)))
+ .collect(RWUtils.singleItemCollector()));
+ }
+ return Optional.absent();
+ }
+
+ default EntityDumpExecutor<IpAddressDetailsReplyDump, AddressDumpParams> createExecutor(
+ @Nonnull final FutureJVppCore vppApi) {
+ return (identifier, params) -> {
+ checkNotNull(params, "Address dump params cannot be null");
+
+ final IpAddressDump dumpRequest = new IpAddressDump();
+ dumpRequest.isIpv6 = booleanToByte(params.isIpv6());
+ dumpRequest.swIfIndex = params.getInterfaceIndex();
+
+ return getReplyForRead(vppApi.ipAddressDump(dumpRequest).toCompletableFuture(), identifier);
+ };
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java
new file mode 100644
index 000000000..97f223a8c
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/Ipv6Customizer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.interfacesstate.ip;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv6Builder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+
+public class Ipv6Customizer extends FutureJVppCustomizer implements ReaderCustomizer<Ipv6, Ipv6Builder> {
+
+ private final NamingContext interfaceContext;
+
+ public Ipv6Customizer(@Nonnull final FutureJVppCore futureJVppCore, final NamingContext interfaceContext) {
+ super(futureJVppCore);
+ this.interfaceContext = interfaceContext;
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final Ipv6 readValue) {
+ ((Interface2Builder) parentBuilder).setIpv6(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public Ipv6Builder getBuilder(@Nonnull final InstanceIdentifier<Ipv6> id) {
+ return new Ipv6Builder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id, @Nonnull final Ipv6Builder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ // TODO HONEYCOMB-102 implement + init
+// final IpAddressDump dumpRequest = new IpAddressDump();
+// dumpRequest.isIpv6 = 1;
+// dumpRequest.swIfIndex = interfaceContext.getIndex(id.firstKeyOf(Interface.class).getName(),
+// ctx.getMappingContext());
+// final CompletionStage<IpAddressDetailsReplyDump> addressDumpFuture = getFutureJVpp().
+// ipAddressDump(dumpRequest);
+// final IpAddressDetailsReplyDump reply = TranslateUtils.getReply(addressDumpFuture.toCompletableFuture());
+ }
+
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java
new file mode 100644
index 000000000..eee49799b
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java
@@ -0,0 +1,143 @@
+/*
+ * 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.interfacesstate.ip;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import io.fd.hc2vpp.v3po.interfacesstate.SubInterfaceCustomizer;
+import io.fd.hc2vpp.v3po.interfacesstate.ip.dump.params.AddressDumpParams;
+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.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.v3po.util.SubInterfaceUtils;
+import io.fd.vpp.jvpp.core.dto.IpAddressDetails;
+import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder;
+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;
+
+/**
+ * Read customizer for sub-interface Ipv4 addresses.
+ */
+public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer
+ implements InitializingListReaderCustomizer<Address, AddressKey, AddressBuilder>, Ipv4Reader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIpv4AddressCustomizer.class);
+
+ private final NamingContext interfaceContext;
+ private final DumpCacheManager<IpAddressDetailsReplyDump, AddressDumpParams> dumpManager;
+
+ public SubInterfaceIpv4AddressCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJVppCore);
+ this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
+ this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<IpAddressDetailsReplyDump, AddressDumpParams>()
+ .withExecutor(createExecutor(futureJVppCore))
+ //same as with ipv4 addresses for interfaces, these must have cache scope of their parent sub-interface
+ .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class)))
+ .build();
+ }
+
+ @Override
+ @Nonnull
+ public AddressBuilder getBuilder(@Nonnull InstanceIdentifier<Address> id) {
+ return new AddressBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull InstanceIdentifier<Address> id, @Nonnull AddressBuilder builder,
+ @Nonnull ReadContext ctx)
+ throws ReadFailedException {
+ LOG.debug("Reading attributes for sub-interface address: {}", id);
+
+ final String subInterfaceName = getSubInterfaceName(id);
+ final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext());
+ final Optional<IpAddressDetailsReplyDump> dumpOptional = dumpManager
+ .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false));
+
+ final Optional<IpAddressDetails> ipAddressDetails =
+ findIpAddressDetailsByIp(dumpOptional, id.firstKeyOf(Address.class).getIp());
+
+ if (ipAddressDetails.isPresent()) {
+ final IpAddressDetails detail = ipAddressDetails.get();
+ builder.setIp(arrayToIpv4AddressNoZone(detail.ip));
+ builder.setSubnet(new PrefixLengthBuilder().setPrefixLength(Short.valueOf(detail.prefixLength)).build());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Attributes for {} sub-interface (id={}) address {} successfully read: {}",
+ subInterfaceName, subInterfaceIndex, id, builder.build());
+ }
+ }
+ }
+
+ @Override
+ public List<AddressKey> getAllIds(@Nonnull InstanceIdentifier<Address> id, @Nonnull ReadContext ctx)
+ throws ReadFailedException {
+ LOG.debug("Reading list of keys for sub-interface addresses: {}", id);
+
+ final String subInterfaceName = getSubInterfaceName(id);
+ final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext());
+ final Optional<IpAddressDetailsReplyDump> dumpOptional = dumpManager
+ .getDump(id, ctx.getModificationCache(), new AddressDumpParams(subInterfaceIndex, false));
+
+ return getAllIpv4AddressIds(dumpOptional, AddressKey::new);
+ }
+
+ @Override
+ public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull List<Address> readData) {
+ ((Ipv4Builder) builder).setAddress(readData);
+ }
+
+ private static String getSubInterfaceName(@Nonnull final InstanceIdentifier<Address> id) {
+ return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(),
+ Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier()));
+ }
+
+ @Override
+ public Initialized<Address> init(
+ @Nonnull final InstanceIdentifier<Address> id, @Nonnull final Address readValue,
+ @Nonnull final ReadContext ctx) {
+ return Initialized.create(getCfgId(id), readValue);
+ }
+
+ private InstanceIdentifier<Address> getCfgId(final InstanceIdentifier<Address> id) {
+ return SubInterfaceCustomizer.getCfgId(RWUtils.cutId(id, SubInterface.class))
+ .child(Ipv4.class)
+ .child(Address.class, new AddressKey(id.firstKeyOf(Address.class)));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java
new file mode 100644
index 000000000..cb80893be
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/ip/dump/params/AddressDumpParams.java
@@ -0,0 +1,44 @@
+/*
+ * 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.interfacesstate.ip.dump.params;
+
+public class AddressDumpParams {
+
+ private final int interfaceIndex;
+ private final boolean isIpv6;
+
+ public AddressDumpParams(final int interfaceIndex, final boolean isIpv6) {
+ this.interfaceIndex = interfaceIndex;
+ this.isIpv6 = isIpv6;
+ }
+
+ public int getInterfaceIndex() {
+ return interfaceIndex;
+ }
+
+ public boolean isIpv6() {
+ return isIpv6;
+ }
+
+ @Override
+ public String toString() {
+ return "AddressDumpParams{" +
+ "interfaceIndex=" + interfaceIndex +
+ ", isIpv6=" + isIpv6 +
+ '}';
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.java
new file mode 100644
index 000000000..4d560a55b
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/pbb/PbbRewriteStateCustomizer.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.interfacesstate.pbb;
+
+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.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.PbbRewriteStateInterfaceAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.pbb.rev161214.interfaces.state._interface.PbbRewriteStateBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class PbbRewriteStateCustomizer extends FutureJVppCustomizer
+ implements ReaderCustomizer<PbbRewriteState, PbbRewriteStateBuilder> {
+
+ public PbbRewriteStateCustomizer(@Nonnull final FutureJVppCore futureJVppCore) {
+ super(futureJVppCore);
+ }
+
+ @Nonnull
+ @Override
+ public PbbRewriteStateBuilder getBuilder(@Nonnull final InstanceIdentifier<PbbRewriteState> id) {
+ return new PbbRewriteStateBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<PbbRewriteState> id,
+ @Nonnull final PbbRewriteStateBuilder 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 PbbRewriteState readValue) {
+ ((PbbRewriteStateInterfaceAugmentationBuilder) parentBuilder).setPbbRewriteState(readValue);
+ }
+}