summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces')
-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
6 files changed, 564 insertions, 308 deletions
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);
- }
- }
-}