summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io/fd/honeycomb
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/honeycomb')
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java89
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java157
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java120
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java165
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java175
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java110
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java145
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java2
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java121
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java2
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java32
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java79
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java145
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java206
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java77
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java96
16 files changed, 1145 insertions, 576 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java
index db3d540c7..a41a6e87b 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/InterfacesInitializer.java
@@ -34,20 +34,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeVni;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.EthernetBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.SubInterfaceBuilder;
+// import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.SubInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.TapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.VlanTagRewriteBuilder;
+// import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.VlanTagRewriteBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Ethernet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterface;
+// import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Tap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VhostUser;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Vxlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpe;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.l2.VlanTagRewrite;
+// import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.l2.VlanTagRewrite;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;
@@ -122,10 +122,11 @@ public class InterfacesInitializer extends AbstractDataTreeConverter<InterfacesS
setL2(augmentBuilder, l2);
}
- final SubInterface subInterface = vppIfcAugmentation.getSubInterface();
- if(subInterface != null) {
- setSubinterface(augmentBuilder, subInterface);
- }
+ // FIXME new vlan model
+// final SubInterface subInterface = vppIfcAugmentation.getSubInterface();
+// if(subInterface != null) {
+// setSubinterface(augmentBuilder, subInterface);
+// }
final Ethernet ethernet = vppIfcAugmentation.getEthernet();
if(ethernet != null) {
@@ -140,32 +141,33 @@ public class InterfacesInitializer extends AbstractDataTreeConverter<InterfacesS
return builder.build();
}
- private static void setSubinterface(final VppInterfaceAugmentationBuilder augmentBuilder,
- final SubInterface subInterface) {
- final SubInterfaceBuilder subIfcBuilder = new SubInterfaceBuilder();
-
- if(subInterface.isDefaultSubif() != null) {
- subIfcBuilder.setDefaultSubif(subInterface.isDefaultSubif());
- }
- if(subInterface.isExactMatch() != null) {
- subIfcBuilder.setExactMatch(subInterface.isExactMatch());
- }
- if(subInterface.isMatchAnyInnerId() != null) {
- subIfcBuilder.setMatchAnyInnerId(subInterface.isMatchAnyInnerId());
- }
- if(subInterface.isMatchAnyOuterId() != null) {
- subIfcBuilder.setMatchAnyOuterId(subInterface.isMatchAnyOuterId());
- }
-
- subIfcBuilder.setIdentifier(subInterface.getIdentifier());
- subIfcBuilder.setInnerId(subInterface.getInnerId());
- subIfcBuilder.setNumberOfTags(subInterface.getNumberOfTags());
- subIfcBuilder.setOuterId(subInterface.getOuterId());
- subIfcBuilder.setSuperInterface(subInterface.getSuperInterface());
- subIfcBuilder.setVlanType(subInterface.getVlanType());
-
- augmentBuilder.setSubInterface(subIfcBuilder.build());
- }
+ // FIXME vlan new modele
+// private static void setSubinterface(final VppInterfaceAugmentationBuilder augmentBuilder,
+// final SubInterface subInterface) {
+// final SubInterfaceBuilder subIfcBuilder = new SubInterfaceBuilder();
+//
+// if(subInterface.isDefaultSubif() != null) {
+// subIfcBuilder.setDefaultSubif(subInterface.isDefaultSubif());
+// }
+// if(subInterface.isExactMatch() != null) {
+// subIfcBuilder.setExactMatch(subInterface.isExactMatch());
+// }
+// if(subInterface.isMatchAnyInnerId() != null) {
+// subIfcBuilder.setMatchAnyInnerId(subInterface.isMatchAnyInnerId());
+// }
+// if(subInterface.isMatchAnyOuterId() != null) {
+// subIfcBuilder.setMatchAnyOuterId(subInterface.isMatchAnyOuterId());
+// }
+//
+// subIfcBuilder.setIdentifier(subInterface.getIdentifier());
+// subIfcBuilder.setInnerId(subInterface.getInnerId());
+// subIfcBuilder.setNumberOfTags(subInterface.getNumberOfTags());
+// subIfcBuilder.setOuterId(subInterface.getOuterId());
+// subIfcBuilder.setSuperInterface(subInterface.getSuperInterface());
+// subIfcBuilder.setVlanType(subInterface.getVlanType());
+//
+// augmentBuilder.setSubInterface(subIfcBuilder.build());
+// }
private static void setEthernet(final VppInterfaceAugmentationBuilder augmentBuilder, final Ethernet ethernet) {
final EthernetBuilder ethernetBuilder = new EthernetBuilder();
@@ -193,15 +195,16 @@ public class InterfacesInitializer extends AbstractDataTreeConverter<InterfacesS
}
}
- final VlanTagRewrite vlanTagRewrite = l2.getVlanTagRewrite();
- if(vlanTagRewrite != null) {
- final VlanTagRewriteBuilder vlanTagRewriteBuilder = new VlanTagRewriteBuilder();
- vlanTagRewriteBuilder.setFirstPushed(vlanTagRewrite.getFirstPushed());
- vlanTagRewriteBuilder.setRewriteOperation(vlanTagRewrite.getRewriteOperation());
- vlanTagRewriteBuilder.setTag1(vlanTagRewrite.getTag1());
- vlanTagRewriteBuilder.setTag2(vlanTagRewrite.getTag2());
- l2Builder.setVlanTagRewrite(vlanTagRewriteBuilder.build());
- }
+ // FIXME new vlan model
+// final VlanTagRewrite vlanTagRewrite = l2.getVlanTagRewrite();
+// if(vlanTagRewrite != null) {
+// final VlanTagRewriteBuilder vlanTagRewriteBuilder = new VlanTagRewriteBuilder();
+// vlanTagRewriteBuilder.setFirstPushed(vlanTagRewrite.getFirstPushed());
+// vlanTagRewriteBuilder.setRewriteOperation(vlanTagRewrite.getRewriteOperation());
+// vlanTagRewriteBuilder.setTag1(vlanTagRewrite.getTag1());
+// vlanTagRewriteBuilder.setTag2(vlanTagRewrite.getTag2());
+// l2Builder.setVlanTagRewrite(vlanTagRewriteBuilder.build());
+// }
augmentBuilder.setL2(l2Builder.build());
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java
new file mode 100644
index 000000000..1463ca9e5
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterconnectionWriteUtils.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.XconnectBased;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2Bridge;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2BridgeReply;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2Xconnect;
+import org.openvpp.jvpp.dto.SwInterfaceSetL2XconnectReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class providing Interconnection CUD support.
+ */
+final class InterconnectionWriteUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterconnectionWriteUtils.class);
+
+ private final FutureJVpp futureJvpp;
+ private final NamingContext interfaceContext;
+ private final NamingContext bridgeDomainContext;
+
+ InterconnectionWriteUtils(@Nonnull final FutureJVpp futureJvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext) {
+ this.futureJvpp = requireNonNull(futureJvpp, "futureJvpp should not be null");
+ this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null");
+ this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null");
+ }
+
+ void setInterconnection(final InstanceIdentifier<? extends DataObject> id, final int swIfIndex,
+ final String ifcName,
+ final Interconnection ic, final WriteContext writeContext)
+ throws VppApiInvocationException, WriteFailedException {
+ if (ic == null) { // TODO in case of update we should delete interconnection
+ LOG.trace("Interconnection is not set. Skipping");
+ } else if (ic instanceof XconnectBased) {
+ setXconnectBasedL2(swIfIndex, ifcName, (XconnectBased) ic, writeContext);
+ } else if (ic instanceof BridgeBased) {
+ setBridgeBasedL2(swIfIndex, ifcName, (BridgeBased) ic, writeContext);
+ } else {
+ // FIXME how does choice extensibility work
+ // FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject
+ // FIXME we might need a choice customizer
+ // THis choice is already from augment, so its probably not possible to augment augmented choice
+ LOG.error("Unable to handle Interconnection of type {}", ic.getClass());
+ throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass());
+ }
+ }
+
+ private void setBridgeBasedL2(final int swIfIndex, final String ifcName, final BridgeBased bb,
+ final WriteContext writeContext)
+ throws VppApiInvocationException {
+
+ LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}", bb.getBridgeDomain(),
+ ifcName);
+
+ String bdName = bb.getBridgeDomain();
+
+ int bdId = bridgeDomainContext.getIndex(bdName, writeContext.getMappingContext());
+ checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist",
+ ifcName, bdName);
+
+ byte bvi = bb.isBridgedVirtualInterface()
+ ? (byte) 1
+ : (byte) 0;
+ byte shg = bb.getSplitHorizonGroup().byteValue();
+
+ final CompletionStage<SwInterfaceSetL2BridgeReply> swInterfaceSetL2BridgeReplyCompletionStage = futureJvpp
+ .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */));
+ final SwInterfaceSetL2BridgeReply reply =
+ TranslateUtils.getReply(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture());
+
+ if (reply.retval < 0) {
+ LOG.warn("Failed to update bridge based interconnection flags for: {}, interconnection: {}", ifcName, bb);
+ throw new VppApiInvocationException("swInterfaceSetL2Bridge", reply.context, reply.retval);
+ } else {
+ LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb);
+ }
+ }
+
+ private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg,
+ final byte bvi, final byte enabled) {
+ final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge();
+ swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex;
+ swInterfaceSetL2Bridge.bdId = bdId;
+ swInterfaceSetL2Bridge.shg = shg;
+ swInterfaceSetL2Bridge.bvi = bvi;
+ swInterfaceSetL2Bridge.enable = enabled;
+ return swInterfaceSetL2Bridge;
+ }
+
+ private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic,
+ final WriteContext writeContext)
+ throws VppApiInvocationException {
+ String outSwIfName = ic.getXconnectOutgoingInterface();
+ LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName, ifcName);
+
+ int outSwIfIndex = interfaceContext.getIndex(outSwIfName, writeContext.getMappingContext());
+ checkArgument(outSwIfIndex > 0,
+ "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist",
+ ifcName, outSwIfIndex);
+
+ final CompletionStage<SwInterfaceSetL2XconnectReply> swInterfaceSetL2XconnectReplyCompletionStage =
+ futureJvpp
+ .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, (byte) 1 /* enable */));
+ final SwInterfaceSetL2XconnectReply reply =
+ TranslateUtils.getReply(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture());
+
+ if (reply.retval < 0) {
+ LOG.warn("Failed to update xconnect based interconnection flags for: {}, interconnection: {}", ifcName, ic);
+ throw new VppApiInvocationException("swInterfaceSetL2Xconnect", reply.context, reply.retval);
+ } else {
+ LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic);
+ }
+ }
+
+ private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc,
+ final byte enabled) {
+
+ final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect();
+ swInterfaceSetL2Xconnect.enable = enabled;
+ swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc;
+ swInterfaceSetL2Xconnect.txSwIfIndex = txIfc;
+ return swInterfaceSetL2Xconnect;
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
index ccb54b3c4..c4c6ecc0a 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
@@ -16,30 +16,19 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.base.Optional;
import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
-import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.XconnectBased;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.jvpp.dto.SwInterfaceSetL2Bridge;
-import org.openvpp.jvpp.dto.SwInterfaceSetL2BridgeReply;
-import org.openvpp.jvpp.dto.SwInterfaceSetL2Xconnect;
-import org.openvpp.jvpp.dto.SwInterfaceSetL2XconnectReply;
import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,13 +37,13 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
private final NamingContext interfaceContext;
- private final NamingContext bridgeDomainContext;
+ private final InterconnectionWriteUtils icWriteUtils;
public L2Customizer(final FutureJVpp vppApi, final NamingContext interfaceContext,
final NamingContext bridgeDomainContext) {
super(vppApi);
this.interfaceContext = interfaceContext;
- this.bridgeDomainContext = bridgeDomainContext;
+ this.icWriteUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext);
}
@Nonnull
@@ -100,112 +89,11 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
// TODO implement delete (if possible)
}
- private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 vppL2,
+ private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 l2,
final WriteContext writeContext)
throws VppApiInvocationException, WriteFailedException {
LOG.debug("Setting L2 for interface: {}", ifcName);
// Nothing besides interconnection here
- setInterconnection(id, swIfIndex, ifcName, vppL2, writeContext);
- }
-
- private void setInterconnection(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName,
- final L2 vppL2, final WriteContext writeContext)
- throws VppApiInvocationException, WriteFailedException {
- Interconnection ic = vppL2.getInterconnection();
- if (ic instanceof XconnectBased) {
- setXconnectBasedL2(swIfIndex, ifcName, (XconnectBased) ic, writeContext);
- } else if (ic instanceof BridgeBased) {
- setBridgeBasedL2(swIfIndex, ifcName, (BridgeBased) ic, writeContext);
- } else {
- // FIXME how does choice extensibility work
- // FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject
- // FIXME we might need a choice customizer
- // THis choice is already from augment, so its probably not possible to augment augmented choice
- LOG.error("Unable to handle Interconnection of type {}", ic.getClass());
- throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass());
- }
- }
-
- private void setBridgeBasedL2(final int swIfIndex, final String ifcName, final BridgeBased bb,
- final WriteContext writeContext)
- throws VppApiInvocationException {
-
- LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}",
- bb.getBridgeDomain(), ifcName);
-
- String bdName = bb.getBridgeDomain();
-
- int bdId = bridgeDomainContext.getIndex(bdName, writeContext.getMappingContext());
- checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist",
- ifcName, bdName);
-
- byte bvi = bb.isBridgedVirtualInterface()
- ? (byte) 1
- : (byte) 0;
- byte shg = bb.getSplitHorizonGroup().byteValue();
-
- final CompletionStage<SwInterfaceSetL2BridgeReply> swInterfaceSetL2BridgeReplyCompletionStage = getFutureJVpp()
- .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */));
- final SwInterfaceSetL2BridgeReply reply =
- TranslateUtils.getReply(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture());
-
- if (reply.retval < 0) {
- LOG.warn("Failed to update bridge based interconnection flags for: {}, interconnection: {}", ifcName,
- bb);
- throw new VppApiInvocationException("swInterfaceSetL2Bridge", reply.context, reply.retval);
- } else {
- LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName,
- bb);
- }
- }
-
- private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg,
- final byte bvi, final byte enabled) {
- final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge();
- swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex;
- swInterfaceSetL2Bridge.bdId = bdId;
- swInterfaceSetL2Bridge.shg = shg;
- swInterfaceSetL2Bridge.bvi = bvi;
- swInterfaceSetL2Bridge.enable = enabled;
- return swInterfaceSetL2Bridge;
- }
-
- private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic,
- final WriteContext writeContext)
- throws VppApiInvocationException {
-
- String outSwIfName = ic.getXconnectOutgoingInterface();
- LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName,
- ifcName);
-
- int outSwIfIndex = interfaceContext.getIndex(outSwIfName, writeContext.getMappingContext());
- checkArgument(outSwIfIndex > 0,
- "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist",
- ifcName, outSwIfIndex);
-
- final CompletionStage<SwInterfaceSetL2XconnectReply> swInterfaceSetL2XconnectReplyCompletionStage =
- getFutureJVpp()
- .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, (byte) 1 /* enable */));
- final SwInterfaceSetL2XconnectReply reply =
- TranslateUtils.getReply(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture());
-
- if (reply.retval < 0) {
- LOG.warn("Failed to update xconnect based interconnection flags for: {}, interconnection: {}",
- ifcName, ic);
- throw new VppApiInvocationException("swInterfaceSetL2Xconnect", reply.context, reply.retval);
- } else {
- LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName,
- ic);
- }
- }
-
- private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc,
- final byte enabled) {
-
- final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect();
- swInterfaceSetL2Xconnect.enable = enabled;
- swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc;
- swInterfaceSetL2Xconnect.txSwIfIndex = txIfc;
- return swInterfaceSetL2Xconnect;
+ icWriteUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext);
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java
new file mode 100644
index 000000000..2309344c8
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+
+import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.TagRewriteOperation;
+import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.Rewrite;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.RewriteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTags;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewrite;
+import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewriteReply;
+import org.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Writer Customizer responsible for vlan tag rewrite.<br> Sends {@code l2_interface_vlan_tag_rewrite} message to
+ * VPP.<br> Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command.
+ */
+public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Rewrite> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(
+ io.fd.honeycomb.v3po.translate.v3po.interfacesstate.RewriteCustomizer.class);
+ private final NamingContext interfaceContext;
+
+ public RewriteCustomizer(@Nonnull final FutureJVpp futureJvpp,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJvpp);
+ this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
+ }
+
+ @Nonnull
+ @Override
+ public Optional<Rewrite> extract(@Nonnull final InstanceIdentifier<Rewrite> currentId,
+ @Nonnull final DataObject parentData) {
+ return Optional.fromNullable(((L2) parentData).getRewrite());
+ }
+
+ @Override
+ public void writeCurrentAttributes(final InstanceIdentifier<Rewrite> id, final Rewrite dataAfter,
+ final WriteContext writeContext)
+ throws WriteFailedException.CreateFailedException {
+
+ try {
+ setTagRewrite(getSubInterfaceName(id), dataAfter, writeContext);
+ } catch (VppApiInvocationException e) {
+ throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
+ }
+ }
+
+ 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 setTagRewrite(final String ifname, final Rewrite rewrite, final WriteContext writeContext)
+ throws VppApiInvocationException {
+ final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext());
+ LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite);
+
+ final CompletionStage<L2InterfaceVlanTagRewriteReply> replyCompletionStage =
+ getFutureJVpp().l2InterfaceVlanTagRewrite(getTagRewriteRequest(swIfIndex, rewrite));
+
+ final L2InterfaceVlanTagRewriteReply reply =
+ TranslateUtils.getReply(replyCompletionStage.toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.debug("Failed to set tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite);
+ throw new VppApiInvocationException("l2InterfaceVlanTagRewrite", reply.context, reply.retval);
+ } else {
+ LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite);
+ }
+ }
+
+ private L2InterfaceVlanTagRewrite getTagRewriteRequest(final int swIfIndex, final Rewrite rewrite) {
+ final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite();
+ request.swIfIndex = swIfIndex;
+ request.pushDot1Q = booleanToByte(_802dot1q.class == rewrite.getVlanType());
+
+ final List<PushTags> pushTags = rewrite.getPushTags();
+ final Short popTags = rewrite.getPopTags();
+
+ final int numberOfTagsToPop = popTags == null
+ ? 0
+ : popTags.intValue();
+ final int numberOfTagsToPush = pushTags == null
+ ? 0
+ : pushTags.size();
+
+ request.vtrOp = TagRewriteOperation.get(numberOfTagsToPop, numberOfTagsToPush).ordinal();
+
+ if (numberOfTagsToPush > 0) {
+ for (final PushTags tag : pushTags) {
+ if (tag.getIndex() == 0) {
+ request.tag1 = tag.getDot1qTag().getVlanId().getValue();
+ } else {
+ request.tag2 = tag.getDot1qTag().getVlanId().getValue();
+ }
+ }
+ }
+
+ LOG.debug("Generated tag rewrite request: {}", ReflectionToStringBuilder.toString(request));
+ return request;
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Rewrite> id,
+ @Nonnull final Rewrite dataBefore,
+ @Nonnull final Rewrite dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ try {
+ setTagRewrite(getSubInterfaceName(id), dataAfter, writeContext);
+ } catch (VppApiInvocationException e) {
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
+ }
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Rewrite> id,
+ @Nonnull final Rewrite dataBefore, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException.DeleteFailedException {
+ try {
+ final String subifName = getSubInterfaceName(id);
+ LOG.debug("Disabling tag rewrite for interface {}", subifName);
+ final Rewrite rewrite = new RewriteBuilder().build(); // rewrite without push and pops will cause delete
+ setTagRewrite(subifName, rewrite, writeContext);
+ } catch (VppApiInvocationException e) {
+ throw new WriteFailedException.DeleteFailedException(id, e);
+ }
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
index 499d98048..b6c8d9a59 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
@@ -16,39 +16,53 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+import static com.google.common.base.Preconditions.checkState;
+import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName;
import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.List;
+import java.util.Objects;
import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+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.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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanTag;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1ad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.MatchType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.Default;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.vlan.tagged.VlanTagged;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Tags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.Tag;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.openvpp.jvpp.dto.CreateSubif;
import org.openvpp.jvpp.dto.CreateSubifReply;
+import org.openvpp.jvpp.dto.SwInterfaceSetFlags;
+import org.openvpp.jvpp.dto.SwInterfaceSetFlagsReply;
import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Writer Customizer responsible for sub interface creation.<br>
- * Sends {@code create_subif} message to VPP.<br>
+ * Writer Customizer responsible for sub interface creation.<br> Sends {@code create_subif} message to VPP.<br>
* Equivalent of invoking {@code vppclt create subif} command.
*/
-public class SubInterfaceCustomizer extends AbstractInterfaceTypeCustomizer<SubInterface> {
+public class SubInterfaceCustomizer extends FutureJVppCustomizer
+ implements ListWriterCustomizer<SubInterface, SubInterfaceKey> {
private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class);
private final NamingContext interfaceContext;
@@ -60,18 +74,14 @@ public class SubInterfaceCustomizer extends AbstractInterfaceTypeCustomizer<SubI
@Nonnull
@Override
- public Optional<SubInterface> extract(@Nonnull final InstanceIdentifier<SubInterface> currentId,
- @Nonnull final DataObject parentData) {
- return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getSubInterface());
+ public List<SubInterface> extract(@Nonnull final InstanceIdentifier<SubInterface> currentId,
+ @Nonnull final DataObject parentData) {
+ return ((SubInterfaces) parentData).getSubInterface();
}
- @Override
- protected Class<? extends InterfaceType> getExpectedInterfaceType() {
- return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.SubInterface.class;
- }
@Override
- public void writeInterface(@Nonnull final InstanceIdentifier<SubInterface> id,
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
@Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext)
throws WriteFailedException.CreateFailedException {
try {
@@ -81,31 +91,36 @@ public class SubInterfaceCustomizer extends AbstractInterfaceTypeCustomizer<SubI
}
}
- private void createSubInterface(final String swIfName, final SubInterface subInterface,
- final WriteContext writeContext) throws VppApiInvocationException {
- final String superIfName = subInterface.getSuperInterface();
- final int swIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext());
- LOG.debug("Creating sub interface of {}(id={}): name={}, subInterface={}", superIfName, swIfIndex, swIfName, subInterface);
+ private void createSubInterface(@Nonnull final String superIfName,
+ @Nonnull final SubInterface subInterface, final WriteContext writeContext)
+ throws VppApiInvocationException {
+ final int superIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext());
+ LOG.debug("Creating sub interface of {}(id={}): subInterface={}", superIfName, superIfIndex, subInterface);
final CompletionStage<CreateSubifReply> createSubifReplyCompletionStage =
- getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, swIfIndex));
+ getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, superIfIndex));
final CreateSubifReply reply =
TranslateUtils.getReply(createSubifReplyCompletionStage.toCompletableFuture());
if (reply.retval < 0) {
- LOG.debug("Failed to create sub interface for: {}, subInterface: {}", swIfName, subInterface);
+ LOG.debug("Failed to create sub interface for: {}, subInterface: {}", superIfName, subInterface);
throw new VppApiInvocationException("createSubif", reply.context, reply.retval);
} else {
- LOG.debug("Sub interface created successfully for: {}, subInterface: {}", swIfName, subInterface);
- // Add new interface to our interface context
- interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
+ setInterfaceState(reply.swIfIndex, booleanToByte(subInterface.isEnabled()));
+ interfaceContext.addName(reply.swIfIndex,
+ getSubInterfaceName(superIfName, Math.toIntExact(subInterface.getIdentifier())),
+ writeContext.getMappingContext());
+ LOG.debug("Sub interface created successfully for: {}, subInterface: {}", superIfName, subInterface);
}
}
- private CreateSubif getCreateSubifRequest(final SubInterface subInterface, final int swIfIndex) {
+ private CreateSubif getCreateSubifRequest(@Nonnull final SubInterface subInterface, final int swIfIndex) {
+ // TODO add validation
CreateSubif request = new CreateSubif();
request.subId = Math.toIntExact(subInterface.getIdentifier().intValue());
request.swIfIndex = swIfIndex;
- switch (subInterface.getNumberOfTags()) {
+
+ final int numberOfTags = getNumberOfTags(subInterface);
+ switch (numberOfTags) {
case 0:
request.noTags = 1;
break;
@@ -116,38 +131,104 @@ public class SubInterfaceCustomizer extends AbstractInterfaceTypeCustomizer<SubI
request.twoTags = 1;
break;
}
- request.dot1Ad = booleanToByte(VlanType._802dot1ad.equals(subInterface.getVlanType()));
- request.exactMatch = booleanToByte(subInterface.isExactMatch());
- request.defaultSub = booleanToByte(subInterface.isDefaultSubif());
- request.outerVlanIdAny = booleanToByte(subInterface.isMatchAnyInnerId());
- request.innerVlanIdAny = booleanToByte(subInterface.isMatchAnyInnerId());
- request.outerVlanId = vlanTagToChar(subInterface.getOuterId());
- request.innerVlanId = vlanTagToChar(subInterface.getInnerId());
+ request.dot1Ad = booleanToByte(_802dot1ad.class == subInterface.getVlanType());
+
+ final MatchType matchType = subInterface.getMatch().getMatchType(); // todo match should be mandatory
+ request.exactMatch =
+ booleanToByte(matchType instanceof VlanTagged && ((VlanTagged) matchType).isMatchExactTags());
+ request.defaultSub = booleanToByte(matchType instanceof Default);
+
+ if (numberOfTags > 0) {
+ for (final Tag tag : subInterface.getTags().getTag()) {
+ if (tag.getIndex() == 0) {
+ setOuterTag(request, tag);
+ } else if (tag.getIndex() == 1) {
+ setInnerTag(request, tag);
+ }
+ }
+ }
return request;
}
- private static char vlanTagToChar(@Nullable VlanTag tag) {
- if (tag == null) {
+ private void setOuterTag(final CreateSubif request, final Tag outerTag) {
+ checkState(SVlan.class == outerTag.getDot1qTag().getTagType(), "Service Tag expected at index 0");
+ final Dot1qTag.VlanId vlanId = outerTag.getDot1qTag().getVlanId();
+
+ request.outerVlanId = dot1qVlanIdToChar(vlanId.getDot1qVlanId());
+ request.outerVlanIdAny = booleanToByte(Dot1qTag.VlanId.Enumeration.Any.equals(vlanId.getEnumeration()));
+ }
+
+ private void setInnerTag(final CreateSubif request, final Tag innerTag) {
+ checkState(CVlan.class == innerTag.getDot1qTag().getTagType(), "Customer Tag expected at index 1");
+ final Dot1qTag.VlanId vlanId = innerTag.getDot1qTag().getVlanId();
+
+ request.innerVlanId = dot1qVlanIdToChar(vlanId.getDot1qVlanId());
+ request.innerVlanIdAny = booleanToByte(Dot1qTag.VlanId.Enumeration.Any.equals(vlanId.getEnumeration()));
+ }
+
+ private static int getNumberOfTags(@Nonnull final SubInterface subInterface) {
+ final Tags tags = subInterface.getTags();
+ if (tags == null) {
+ return 0;
+ }
+ final List<Tag> tagList = tags.getTag();
+ if (tagList == null) {
+ return 0;
+ }
+ return tagList.size();
+ }
+
+ private static char dot1qVlanIdToChar(@Nullable Dot1qVlanId dot1qVlanId) {
+ if (dot1qVlanId == null) {
return 0; // tell VPP that optional argument is missing
} else {
- return (char)tag.getValue().intValue();
+ return (char) dot1qVlanId.getValue().intValue();
}
}
@Override
public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
@Nonnull final SubInterface dataBefore, @Nonnull final SubInterface dataAfter,
- @Nonnull final WriteContext writeContext) throws WriteFailedException.UpdateFailedException {
- if (dataBefore.equals(dataAfter)) {
- LOG.debug("dataBefore equals dataAfter, update will not be performed");
- return;
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException.UpdateFailedException {
+ if (Objects.equals(dataBefore.isEnabled(), dataAfter.isEnabled())) {
+ LOG.debug("No state update will be performed. Ignoring config");
+ return; // TODO shouldn't we throw exception here (if there will be dedicated L2 customizer)?
+ }
+ try {
+ final String subIfaceName = getSubInterfaceName(id.firstKeyOf(Interface.class).getName(),
+ Math.toIntExact(dataAfter.getIdentifier()));
+ setInterfaceState(interfaceContext.getIndex(subIfaceName, writeContext.getMappingContext()),
+ booleanToByte(dataAfter.isEnabled()));
+ } catch (VppApiInvocationException e) {
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
+ }
+ }
+
+ private void setInterfaceState(final int swIfIndex, final byte enabled) throws VppApiInvocationException {
+ final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags();
+ swInterfaceSetFlags.swIfIndex = swIfIndex;
+ swInterfaceSetFlags.adminUpDown = enabled;
+
+ final CompletionStage<SwInterfaceSetFlagsReply> swInterfaceSetFlagsReplyFuture =
+ getFutureJVpp().swInterfaceSetFlags(swInterfaceSetFlags);
+
+ LOG.debug("Updating interface state for: interface if={}, enabled: {}", swIfIndex, enabled);
+
+ SwInterfaceSetFlagsReply reply = TranslateUtils.getReply(swInterfaceSetFlagsReplyFuture.toCompletableFuture());
+ if (reply.retval < 0) {
+ LOG.warn("Failed to update interface state for: interface if={}, enabled: {}", swIfIndex, enabled);
+ throw new VppApiInvocationException("swInterfaceSetFlags", reply.context, reply.retval);
+ } else {
+ LOG.debug("Interface state updated successfully for: {}, index: {}, enabled: {}, ctxId: {}",
+ swIfIndex, enabled, reply.context);
}
- throw new UnsupportedOperationException("Sub interface update is not supported");
}
@Override
public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
- @Nonnull final SubInterface dataBefore, @Nonnull final WriteContext writeContext)
+ @Nonnull final SubInterface dataBefore,
+ @Nonnull final WriteContext writeContext)
throws WriteFailedException.DeleteFailedException {
throw new UnsupportedOperationException("Sub interface delete is not supported");
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java
new file mode 100644
index 000000000..a1957f5a0
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for writing vlan sub interface l2 configuration
+ */
+public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<L2> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class);
+ private final NamingContext interfaceContext;
+ private final InterconnectionWriteUtils icWriterUtils;
+
+ public SubInterfaceL2Customizer(final FutureJVpp vppApi, final NamingContext interfaceContext,
+ final NamingContext bridgeDomainContext) {
+ super(vppApi);
+ this.interfaceContext = interfaceContext;
+ this.icWriterUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext);
+ }
+
+ @Nonnull
+ @Override
+ public Optional<L2> extract(@Nonnull final InstanceIdentifier<L2> currentId, @Nonnull final DataObject parentData) {
+ return Optional.fromNullable(((SubInterface) parentData).getL2());
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter,
+ @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ final String subInterfaceName = getSubInterfaceName(id);
+ final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext());
+ try {
+ setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext);
+ } catch (VppApiInvocationException e) {
+ LOG.warn("Write of L2 failed", e);
+ throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
+ }
+ }
+
+ private String getSubInterfaceName(@Nonnull final InstanceIdentifier<L2> id) {
+ final InterfaceKey parentInterfacekey = id.firstKeyOf(Interface.class);
+ final SubInterfaceKey subInterfacekey = id.firstKeyOf(SubInterface.class);
+ return SubInterfaceUtils
+ .getSubInterfaceName(parentInterfacekey.getName(), subInterfacekey.getIdentifier().intValue());
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore,
+ @Nonnull final L2 dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+
+ final String subInterfaceName = getSubInterfaceName(id);
+ final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext());
+ // TODO handle update properly (if possible)
+ try {
+ setL2(id, subInterfaceIndex, subInterfaceName, dataAfter, writeContext);
+ } catch (VppApiInvocationException e) {
+ LOG.warn("Update of L2 failed", e);
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
+ }
+ }
+
+ @Override
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore,
+ @Nonnull final WriteContext writeContext) {
+ // TODO implement delete (if possible)
+ }
+
+ private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 l2,
+ final WriteContext writeContext)
+ throws VppApiInvocationException, WriteFailedException {
+ LOG.debug("Setting L2 for sub-interface: {}", ifcName);
+ icWriterUtils.setInterconnection(id, swIfIndex, ifcName, l2.getInterconnection(), writeContext);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java
deleted file mode 100644
index 721d15530..000000000
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.translate.v3po.interfaces;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
-import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.concurrent.CompletionStage;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.SubInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.TagRewriteOperation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanTag;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.VlanTagRewrite;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.VlanTagRewriteBuilder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewrite;
-import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewriteReply;
-import org.openvpp.jvpp.future.FutureJVpp;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Writer Customizer responsible for vlan tag rewrite.<br>
- * Sends {@code l2_interface_vlan_tag_rewrite} message to VPP.<br>
- * Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command.
- */
-public class VlanTagRewriteCustomizer extends AbstractInterfaceTypeCustomizer<VlanTagRewrite> {
-
- private static final Logger LOG = LoggerFactory.getLogger(VlanTagRewriteCustomizer.class);
- private final NamingContext interfaceContext;
-
- public VlanTagRewriteCustomizer(@Nonnull final FutureJVpp futureJvpp,
- @Nonnull final NamingContext interfaceContext) {
- super(futureJvpp);
- this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
- }
-
- @Nonnull
- @Override
- public Optional<VlanTagRewrite> extract(@Nonnull final InstanceIdentifier<VlanTagRewrite> currentId,
- @Nonnull final DataObject parentData) {
- return Optional.fromNullable(((L2) parentData).getVlanTagRewrite());
- }
-
- @Override
- protected Class<? extends InterfaceType> getExpectedInterfaceType() {
- return SubInterface.class;
- }
-
- @Override
- protected void writeInterface(final InstanceIdentifier<VlanTagRewrite> id, final VlanTagRewrite dataAfter,
- final WriteContext writeContext) throws WriteFailedException.CreateFailedException {
- try {
- setTagRewrite(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
- } catch (VppApiInvocationException e) {
- throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
- }
- }
-
- private void setTagRewrite(final String ifname, final VlanTagRewrite cfg, final WriteContext writeContext)
- throws VppApiInvocationException {
- final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext());
- LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, cfg);
-
- final CompletionStage<L2InterfaceVlanTagRewriteReply> replyCompletionStage =
- getFutureJVpp().l2InterfaceVlanTagRewrite(getTagRewriteRequest(swIfIndex, cfg));
-
- final L2InterfaceVlanTagRewriteReply reply = TranslateUtils.getReply(replyCompletionStage.toCompletableFuture());
- if (reply.retval < 0) {
- LOG.debug("Failed to set tag rewrite for interface {}(id=): {}", ifname, swIfIndex, cfg);
- throw new VppApiInvocationException("l2InterfaceVlanTagRewrite", reply.context, reply.retval);
- } else {
- LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, cfg);
- }
- }
-
- private L2InterfaceVlanTagRewrite getTagRewriteRequest(final int swIfIndex, final VlanTagRewrite cfg) {
- final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite();
- request.swIfIndex = swIfIndex;
-
- request.vtrOp = cfg.getRewriteOperation().getIntValue(); // TODO make mandatory
- request.pushDot1Q = (byte) (VlanType._802dot1q.equals(cfg.getFirstPushed())
- ? 1
- : 0);
- final VlanTag tag1 = cfg.getTag1();
- if (tag1 != null) {
- request.tag1 = tag1.getValue();
- }
- final VlanTag tag2 = cfg.getTag2();
- if (tag2 != null) {
- request.tag2 = tag2.getValue();
- }
- return request;
- }
-
- @Override
- public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<VlanTagRewrite> id,
- @Nonnull final VlanTagRewrite dataBefore,
- @Nonnull final VlanTagRewrite dataAfter, @Nonnull final WriteContext writeContext)
- throws WriteFailedException {
- try {
- setTagRewrite(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
- } catch (VppApiInvocationException e) {
- throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
- }
- }
-
- @Override
- public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VlanTagRewrite> id,
- @Nonnull final VlanTagRewrite dataBefore, @Nonnull final WriteContext writeContext)
- throws WriteFailedException.DeleteFailedException {
- try {
- // disable tag rewrite
- final VlanTagRewriteBuilder builder = new VlanTagRewriteBuilder();
- builder.setRewriteOperation(TagRewriteOperation.Disabled);
- setTagRewrite(id.firstKeyOf(Interface.class).getName(), builder.build(), writeContext);
- } catch (VppApiInvocationException e) {
- throw new WriteFailedException.DeleteFailedException(id, e);
- }
- }
-}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
index 49a6fd630..e1c3e2df6 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
@@ -66,7 +66,7 @@ public class EthernetCustomizer extends FutureJVppCustomizer
@Nonnull final ReadContext ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
- final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
+ final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key.getName(),
interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache());
if(iface.linkMtu != 0) {
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java
new file mode 100644
index 000000000..886549ac3
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterconnectionReadUtils.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+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.rev150105.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;
+import org.openvpp.jvpp.dto.BridgeDomainDetails;
+import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
+import org.openvpp.jvpp.dto.BridgeDomainDump;
+import org.openvpp.jvpp.dto.BridgeDomainSwIfDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class providing Interconnection read support.
+ */
+// FIXME this should be customizer, but it is not possible because Interconnection is not a DataObject
+final class InterconnectionReadUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(InterconnectionReadUtils.class);
+
+ private final FutureJVpp futureJvpp;
+ private final NamingContext interfaceContext;
+ private final NamingContext bridgeDomainContext;
+
+ InterconnectionReadUtils(@Nonnull final FutureJVpp futureJvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext) {
+ this.futureJvpp = requireNonNull(futureJvpp, "futureJvpp 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 String ifaceName, @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ final int ifaceId = interfaceContext.getIndex(ifaceName, ctx.getMappingContext());
+
+ final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(futureJvpp, ifaceName,
+ ifaceId, ctx.getModificationCache());
+ LOG.debug("Interface details for interface: {}, details: {}", ifaceName, iface);
+
+ final BridgeDomainDetailsReplyDump dumpReply = getDumpReply();
+ 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);
+ }
+
+ if (bdSwIfDetails.shg != 0) {
+ bbBuilder.setSplitHorizonGroup((short) bdSwIfDetails.shg);
+ }
+ return bbBuilder.build();
+ }
+ // TODO 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() {
+ // We need to perform full bd dump, because there is no way
+ // to ask VPP for BD details given interface id/name (TODO add it to vpp.api?)
+ // TODO cache dump result
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = -1;
+
+ final CompletableFuture<BridgeDomainDetailsReplyDump> bdCompletableFuture =
+ futureJvpp.bridgeDomainSwIfDump(request).toCompletableFuture();
+ return TranslateUtils.getReply(bdCompletableFuture);
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
index 4027941eb..d54929ea1 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
@@ -75,7 +75,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
final InterfaceKey key = id.firstKeyOf(id.getTargetType());
// Pass cached details from getAllIds to getDetails to avoid additional dumps
- final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
+ final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key.getName(),
interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache());
LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface);
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
index b031523d6..e0bae975f 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
@@ -18,20 +18,19 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import static com.google.common.base.Preconditions.checkNotNull;
import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.toList;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
import java.math.BigInteger;
import java.util.Map;
-import java.util.Objects;
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.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.InterfaceKey;
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.rev150105.SubInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap;
@@ -108,7 +107,7 @@ public final class InterfaceUtils {
* @throws IllegalArgumentException if vppPhysAddress.length < 6
*/
public static String vppPhysAddrToYang(@Nonnull final byte[] vppPhysAddress) {
- Objects.requireNonNull(vppPhysAddress, "Empty physical address bytes");
+ requireNonNull(vppPhysAddress, "Empty physical address bytes");
Preconditions.checkArgument(PHYSICAL_ADDRESS_LENGTH <= vppPhysAddress.length,
"Invalid physical address size %s, expected >= 6", vppPhysAddress.length);
StringBuilder physAddr = new StringBuilder();
@@ -149,7 +148,7 @@ public final class InterfaceUtils {
* Queries VPP for interface description given interface key.
*
* @param futureJvpp VPP Java Future API
- * @param key interface key
+ * @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.
@@ -158,10 +157,14 @@ public final class InterfaceUtils {
*/
@Nonnull
public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVpp futureJvpp,
- @Nonnull InterfaceKey key, final int index,
+ @Nonnull final String name, final int index,
@Nonnull final ModificationCache ctx) {
+ requireNonNull(futureJvpp, "futureJvpp 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 = key.getName().getBytes();
+ request.nameFilter = name.getBytes();
request.nameFilterValid = 1;
final Map<Integer, SwInterfaceDetails> allInterfaces = getCachedInterfaceDump(ctx);
@@ -176,8 +179,8 @@ public final class InterfaceUtils {
if (null == ifaces || null == ifaces.swInterfaceDetails || ifaces.swInterfaceDetails.isEmpty()) {
request.nameFilterValid = 0;
- LOG.warn("VPP returned null instead of interface by key {} and its not cached", key.getName());
- LOG.warn("Iterating through all the interfaces to find interface: {}", key.getName());
+ LOG.warn("VPP returned null instead of interface by key {} and its not cached", name);
+ LOG.warn("Iterating through all the interfaces to find interface: {}", name);
// Or else just perform full dump and do inefficient filtering
requestFuture = futureJvpp.swInterfaceDump(request);
@@ -191,10 +194,17 @@ public final class InterfaceUtils {
if (allInterfaces.containsKey(index)) {
return allInterfaces.get(index);
}
- throw new IllegalArgumentException("Unable to find interface " + key.getName());
+ throw new IllegalArgumentException("Unable to find interface " + name);
}
- final SwInterfaceDetails iface = Iterables.getOnlyElement(ifaces.swInterfaceDetails);
+ // SwInterfaceDump's name filter does prefix match, so we need additional filtering:
+ final SwInterfaceDetails iface = ifaces.swInterfaceDetails.stream().filter(d -> d.swIfIndex == index).collect(
+ Collectors.collectingAndThen(toList(), l -> {
+ if (l.size() == 1) {
+ return l.get(0);
+ }
+ throw new RuntimeException();
+ }));
allInterfaces.put(index, iface); // update the cache
return iface;
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
index 3fae8c713..63e51389c 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
@@ -16,32 +16,20 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Preconditions;
import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
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.rev150105.VppInterfaceStateAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.jvpp.dto.BridgeDomainDetails;
-import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
-import org.openvpp.jvpp.dto.BridgeDomainDump;
-import org.openvpp.jvpp.dto.BridgeDomainSwIfDetails;
-import org.openvpp.jvpp.dto.SwInterfaceDetails;
import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,19 +37,16 @@ import org.slf4j.LoggerFactory;
/**
* Customizer for reading ietf-interfaces:interfaces-state/interface/iface_name/v3po:l2
*/
-public class L2Customizer extends FutureJVppCustomizer
- implements ChildReaderCustomizer<L2, L2Builder> {
+public class L2Customizer extends FutureJVppCustomizer implements ChildReaderCustomizer<L2, L2Builder> {
private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
- private final NamingContext interfaceContext;
- private final NamingContext bridgeDomainContext;
+ private final InterconnectionReadUtils icReadUtils;
public L2Customizer(@Nonnull final FutureJVpp futureJvpp,
@Nonnull final NamingContext interfaceContext,
@Nonnull final NamingContext bridgeDomainContext) {
super(futureJvpp);
- this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
- this.bridgeDomainContext = Preconditions.checkNotNull(bridgeDomainContext, "bridgeDomainContext should not be null");
+ this.icReadUtils = new InterconnectionReadUtils(futureJvpp, interfaceContext, bridgeDomainContext);
}
@Override
@@ -80,62 +65,8 @@ public class L2Customizer extends FutureJVppCustomizer
@Nonnull final ReadContext ctx) throws ReadFailedException {
LOG.debug("Reading attributes for L2: {}", id);
final InterfaceKey key = id.firstKeyOf(Interface.class);
- final int ifaceId = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
-
- final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- ifaceId, ctx.getModificationCache());
- LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface);
-
- final BridgeDomainDetailsReplyDump dumpReply = getDumpReply();
- 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(ifaceId, 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);
- }
-
- if (bdSwIfDetails.shg != 0) {
- bbBuilder.setSplitHorizonGroup((short)bdSwIfDetails.shg);
- }
- builder.setInterconnection(bbBuilder.build());
- }
-
- // TODO is there a way to check if interconnection is XconnectBased?
- }
-
- 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 int ifaceId,
- final BridgeDomainDetailsReplyDump reply,
- int bdId) {
- return reply.bridgeDomainDetails.stream().filter(a -> a.bdId == bdId).findFirst();
- }
-
- private BridgeDomainDetailsReplyDump getDumpReply() {
- // We need to perform full bd dump, because there is no way
- // to ask VPP for BD details given interface id/name (TODO add it to vpp.api?)
- // TODO cache dump result
- final BridgeDomainDump request = new BridgeDomainDump();
- request.bdId = -1;
+ final String ifaceName = key.getName();
- final CompletableFuture<BridgeDomainDetailsReplyDump> bdCompletableFuture =
- getFutureJVpp().bridgeDomainSwIfDump(request).toCompletableFuture();
- return TranslateUtils.getReply(bdCompletableFuture);
+ builder.setInterconnection(icReadUtils.readInterconnection(ifaceName, ctx));
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java
new file mode 100644
index 000000000..143fb4d68
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Preconditions;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.TagRewriteOperation;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+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.rev150527._802dot1ad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.Rewrite;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.RewriteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTagsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTagsKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.future.FutureJVpp;
+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 ChildReaderCustomizer<Rewrite, RewriteBuilder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class);
+ private final NamingContext interfaceContext;
+
+ public RewriteCustomizer(@Nonnull final FutureJVpp futureJvpp,
+ @Nonnull final NamingContext interfaceContext) {
+ super(futureJvpp);
+ 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 = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), subInterfaceName,
+ interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache());
+ LOG.debug("VPP sub-interface details: {}", ReflectionToStringBuilder.toString(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/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java
index 45ef0b490..5adb43874 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java
@@ -16,27 +16,55 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
-import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
+import static com.google.common.base.Preconditions.checkState;
+import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY;
+import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.byteToBoolean;
import com.google.common.base.Preconditions;
import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
+import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
+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.apache.commons.lang3.builder.ReflectionToStringBuilder;
+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.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanTag;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterfaceBuilder;
+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.rev150527.SubInterfaceStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.SubInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.DefaultBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.UntaggedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Tags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.TagsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.Tag;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.TagBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.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.openvpp.jvpp.dto.SwInterfaceDetails;
+import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
+import org.openvpp.jvpp.dto.SwInterfaceDump;
import org.openvpp.jvpp.future.FutureJVpp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,10 +73,11 @@ import org.slf4j.LoggerFactory;
* Customizer for reading sub interfaces form the VPP.
*/
public class SubInterfaceCustomizer extends FutureJVppCustomizer
- implements ChildReaderCustomizer<SubInterface, SubInterfaceBuilder> {
+ implements ListReaderCustomizer<SubInterface, SubInterfaceKey, SubInterfaceBuilder> {
private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class);
private NamingContext interfaceContext;
+ private static final Dot1qTag.VlanId ANY_VLAN_ID = new Dot1qTag.VlanId(Dot1qTag.VlanId.Enumeration.Any);
public SubInterfaceCustomizer(@Nonnull final FutureJVpp jvpp,
@Nonnull final NamingContext interfaceContext) {
@@ -56,10 +85,53 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
}
+ @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 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 =
+ TranslateUtils.getReply(swInterfaceDetailsReplyDumpCompletableFuture);
+
+ 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(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> parentBuilder,
- @Nonnull final SubInterface readValue) {
- ((VppInterfaceStateAugmentationBuilder) parentBuilder).setSubInterface(readValue);
+ public void merge(@Nonnull final Builder<? extends DataObject> builder,
+ @Nonnull final List<SubInterface> readData) {
+ ((SubInterfacesBuilder) builder).setSubInterface(readData);
}
@Nonnull
@@ -72,44 +144,94 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
@Nonnull final SubInterfaceBuilder builder, @Nonnull final ReadContext ctx)
throws ReadFailedException {
- final InterfaceKey key = id.firstKeyOf(Interface.class);
- // Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
- // to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
- if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.SubInterface.class)) {
- return;
- }
+ final String subInterfaceName = getSubInterfaceName(id);
+ LOG.debug("Reading attributes for sub interface: {}", subInterfaceName);
- LOG.debug("Reading attributes for sub interface: {}", id);
- final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key, index, ctx.getModificationCache());
- LOG.debug("VPP interface details: {}", ReflectionToStringBuilder.toString(iface));
+ final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), subInterfaceName,
+ interfaceContext.getIndex(subInterfaceName, ctx.getMappingContext()), ctx.getModificationCache());
+ LOG.debug("VPP sub-interface details: {}", ReflectionToStringBuilder.toString(iface));
- if (iface.subId == 0) {
- // Not a sub interface type
- return;
- }
+ checkState(iface.subId != 0, "Interface returned by the VPP is not a sub-interface");
builder.setIdentifier(Long.valueOf(iface.subId));
- builder.setSuperInterface(interfaceContext.getName(iface.supSwIfIndex, ctx.getMappingContext()));
- builder.setNumberOfTags(Short.valueOf(iface.subNumberOfTags));
- builder.setVlanType(iface.subDot1Ad == 1 ? VlanType._802dot1ad : VlanType._802dot1q);
- if (iface.subExactMatch == 1) {
- builder.setExactMatch(true);
- }
- if (iface.subDefault == 1) {
- builder.setDefaultSubif(true);
- }
- if (iface.subOuterVlanIdAny == 1) {
- builder.setMatchAnyOuterId(true);
+ 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(InterfaceUtils.vppIfIndexToYang(iface.swIfIndex));
+ if (iface.l2AddressLength == 6) {
+ builder.setPhysAddress(new PhysAddress(InterfaceUtils.vppPhysAddrToYang(iface.l2Address)));
}
- if (iface.subOuterVlanIdAny == 1) {
- builder.setMatchAnyInnerId(true);
+ if (0 != iface.linkSpeed) {
+ builder.setSpeed(InterfaceUtils.vppInterfaceSpeedToYang(iface.linkSpeed));
}
- if (iface.subOuterVlanId != 0) { // optional
- builder.setOuterId(new VlanTag(Integer.valueOf(iface.subOuterVlanId)));
+ }
+
+ private static String getSubInterfaceName(final InstanceIdentifier<SubInterface> id) {
+ return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(),
+ Math.toIntExact(id.firstKeyOf(id.getTargetType()).getIdentifier()));
+ }
+
+ 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)));
+ }
+ }
}
- if (iface.subInnerVlanId != 0) { // optional
- builder.setInnerId(new VlanTag(Integer.valueOf(iface.subInnerVlanId)));
+ tags.setTag(list);
+ return tags.build();
+ }
+
+ 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 char vlanId) {
+ return new Dot1qTag.VlanId(new Dot1qVlanId((int) vlanId));
+ }
+
+ 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.rev150527.match.attributes.match.type.VlanTaggedBuilder()
+ .setVlanTagged(tagged.build()).build());
}
+ return match.build();
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java
new file mode 100644
index 000000000..baff29466
--- /dev/null
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+
+import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName;
+
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
+import 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.rev150527.interfaces.state._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.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.openvpp.jvpp.future.FutureJVpp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Customizer for reading vlan sub interface L2 operational state
+ */
+public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements ChildReaderCustomizer<L2, L2Builder> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class);
+ private final InterconnectionReadUtils icReadUtils;
+
+ public SubInterfaceL2Customizer(@Nonnull final FutureJVpp futureJvpp,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext bridgeDomainContext) {
+ super(futureJvpp);
+ this.icReadUtils = new InterconnectionReadUtils(futureJvpp, 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(subInterfaceName, ctx));
+ }
+}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java
deleted file mode 100644
index ac180719c..000000000
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
-
-import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
-
-import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import 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.rev150105.SubInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.TagRewriteOperation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanTag;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VlanType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.l2.VlanTagRewrite;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.l2.VlanTagRewriteBuilder;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.openvpp.jvpp.dto.SwInterfaceDetails;
-import org.openvpp.jvpp.future.FutureJVpp;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Customizer for reading vlan tag-rewrite configuration state form the VPP.
- */
-public class VlanTagRewriteCustomizer extends FutureJVppCustomizer
- implements ChildReaderCustomizer<VlanTagRewrite, VlanTagRewriteBuilder> {
-
- private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceCustomizer.class);
- private final NamingContext interfaceContext;
-
- public VlanTagRewriteCustomizer(@Nonnull final FutureJVpp futureJvpp,
- @Nonnull final NamingContext interfaceContext) {
- super(futureJvpp);
- this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
- @Nonnull final VlanTagRewrite readValue) {
- ((L2Builder) parentBuilder).setVlanTagRewrite(readValue);
- }
-
- @Nonnull
- @Override
- public VlanTagRewriteBuilder getBuilder(@Nonnull final InstanceIdentifier<VlanTagRewrite> id) {
- return new VlanTagRewriteBuilder();
- }
-
- @Override
- public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VlanTagRewrite> id,
- @Nonnull final VlanTagRewriteBuilder builder, @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- LOG.debug("Reading attributes for sub interface: {}", id);
- final InterfaceKey key = id.firstKeyOf(Interface.class);
-
- final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache());
-
- // Tag rewrite is only possible for subinterfaces
- if (!isInterfaceOfType(SubInterface.class, iface)) {
- return;
- }
-
- builder.setFirstPushed(iface.vtrPushDot1Q == 1 ? VlanType._802dot1q : VlanType._802dot1ad);
- builder.setRewriteOperation(TagRewriteOperation.forValue(iface.vtrOp));
- if (iface.vtrTag1 != 0) {
- builder.setTag1(new VlanTag(iface.vtrTag1));
- }
- if (iface.vtrTag2 != 0) {
- builder.setTag2(new VlanTag(iface.vtrTag2));
- }
- }
-}