summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2016-09-05 13:31:39 +0200
committerMarek Gradzki <mgradzki@cisco.com>2016-09-05 11:45:18 +0000
commit3196c5888d01a41aaa9cba115a4e92572e8890ae (patch)
tree6f0953410486b7530be9d602f877eea6b4d237b3
parent2cda5681838704cfdf3ac8b89314b697272c1b37 (diff)
HONEYCOMB-153: fix acls for sub-interfaces
Change-Id: Ia75c2ebd62fb371fd60f860fe12761926f443b98 Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizer.java9
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java21
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java27
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java6
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java32
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6Writer.java44
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceWriter.java4
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAClWriter.java9
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/Readme.adoc5
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/SubInterfaceIetfAclCustomizer.java11
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/util/SubInterfaceUtils.java (renamed from vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/SubInterfaceUtils.java)24
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriterTest.java4
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4WriterTest.java70
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6WriterTest.java68
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIpWriterTestUtils.java34
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/util/SubinterfaceUtilsTest.java (renamed from vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/SubinterfaceUtilsTest.java)0
16 files changed, 278 insertions, 90 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizer.java
index d4a3998..962801a 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizer.java
@@ -18,13 +18,13 @@ package io.fd.honeycomb.translate.v3po.interfaces;
import static com.google.common.base.Preconditions.checkNotNull;
+import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils;
import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException;
import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
-import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
-import io.fd.honeycomb.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils;
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;
@@ -47,7 +47,8 @@ public class SubInterfaceAclCustomizer extends FutureJVppCustomizer
private final NamingContext interfaceContext;
private final NamingContext classifyTableContext;
- public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore vppApi, @Nonnull final NamingContext interfaceContext,
+ public SubInterfaceAclCustomizer(@Nonnull final FutureJVppCore vppApi,
+ @Nonnull final NamingContext interfaceContext,
@Nonnull final NamingContext classifyTableContext) {
super(vppApi);
this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null");
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java
index 38164bf..bfaa42e 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceCustomizer.java
@@ -17,18 +17,18 @@
package io.fd.honeycomb.translate.v3po.interfaces;
import static com.google.common.base.Preconditions.checkState;
+import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getNumberOfTags;
import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName;
import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.booleanToByte;
import com.google.common.base.Preconditions;
import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
-import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException;
-import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.v3po.util.NamingContext;
import io.fd.honeycomb.translate.v3po.util.TranslateUtils;
+import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException;
+import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
-import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletionStage;
import javax.annotation.Nonnull;
@@ -44,7 +44,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan
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.InstanceIdentifier;
import org.openvpp.jvpp.VppBaseCallException;
@@ -108,7 +107,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
request.subId = Math.toIntExact(subInterface.getIdentifier().intValue());
request.swIfIndex = swIfIndex;
- final int numberOfTags = getNumberOfTags(subInterface);
+ final int numberOfTags = getNumberOfTags(subInterface.getTags());
switch (numberOfTags) {
case 0:
request.noTags = 1;
@@ -155,18 +154,6 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
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 short dot1qVlanIdToShort(@Nullable Dot1qVlanId dot1qVlanId) {
if (dot1qVlanId == null) {
return 0; // tell VPP that optional argument is missing
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java
index 21a7107..eeabff4 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java
@@ -16,14 +16,17 @@
package io.fd.honeycomb.translate.v3po.interfaces.acl;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.VisibleForTesting;
import io.fd.honeycomb.translate.util.RWUtils;
import io.fd.honeycomb.translate.v3po.util.TranslateUtils;
import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException;
import java.util.List;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collector;
+import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling;
@@ -53,6 +56,9 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter {
// classify table needs 16*(1 + match_n_vectors) bytes, but this does not quite work, so setting 8K for now
protected static final int TABLE_MEM_SIZE = 8 * 1024;
+ @VisibleForTesting
+ static final int VLAN_TAG_LEN = 4;
+
private static final Collector<PacketHandling, ?, PacketHandling> SINGLE_ITEM_COLLECTOR =
RWUtils.singleItemCollector();
@@ -68,11 +74,13 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter {
* @param action packet handling action (permit/deny)
* @param ace ACE to be translated
* @param nextTableIndex classify table index
+ * @param vlanTags number of vlan tags
* @return classify table that represents given ACE
*/
protected abstract ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action,
@Nonnull final T ace,
- final int nextTableIndex);
+ final int nextTableIndex,
+ final int vlanTags);
/**
* Creates classify session for given ACE.
@@ -80,11 +88,13 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter {
* @param action packet handling action (permit/deny)
* @param ace ACE to be translated
* @param tableIndex classify table index for the given session
+ * @param vlanTags number of vlan tags
* @return classify session that represents given ACE
*/
protected abstract ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action,
@Nonnull final T ace,
- final int tableIndex);
+ final int tableIndex,
+ final int vlanTags);
/**
* Sets classify table index for input_acl_set_interface request.
@@ -94,21 +104,24 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter {
*/
protected abstract void setClassifyTable(@Nonnull final InputAclSetInterface request, final int tableIndex);
+ @Override
public final void write(@Nonnull final InstanceIdentifier<?> id, @Nonnull final List<Ace> aces,
- @Nonnull final InputAclSetInterface request)
+ @Nonnull final InputAclSetInterface request, @Nonnegative final int vlanTags)
throws VppBaseCallException, WriteTimeoutException {
final PacketHandling action = aces.stream().map(ace -> ace.getActions().getPacketHandling()).distinct()
.collect(SINGLE_ITEM_COLLECTOR);
+ checkArgument(vlanTags >= 0 && vlanTags <= 2, "Number of vlan tags %s is not in [0,2] range");
+
int nextTableIndex = -1;
for (final Ace ace : aces) {
// Create table + session per entry
final ClassifyAddDelTable ctRequest =
- createClassifyTable(action, (T) ace.getMatches().getAceType(), nextTableIndex);
+ createClassifyTable(action, (T) ace.getMatches().getAceType(), nextTableIndex, vlanTags);
nextTableIndex = createClassifyTable(id, ctRequest);
createClassifySession(id,
- createClassifySession(action, (T) ace.getMatches().getAceType(), nextTableIndex));
+ createClassifySession(action, (T) ace.getMatches().getAceType(), nextTableIndex, vlanTags));
}
setClassifyTable(request, nextTableIndex);
}
@@ -160,4 +173,8 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter {
return request;
}
+
+ protected int getVlanTagsLen(final int vlanTags) {
+ return vlanTags * VLAN_TAG_LEN;
+ }
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java
index 1240a29..d204e16 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriter.java
@@ -43,7 +43,8 @@ final class AceEthWriter extends AbstractAceWriter<AceEth> {
@Override
public ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action,
@Nonnull final AceEth aceEth,
- @Nonnull final int nextTableIndex) {
+ @Nonnull final int nextTableIndex,
+ final int vlanTags) {
final ClassifyAddDelTable request = createClassifyTable(action, nextTableIndex);
request.mask = new byte[16];
@@ -101,7 +102,8 @@ final class AceEthWriter extends AbstractAceWriter<AceEth> {
@Override
public ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action,
@Nonnull final AceEth aceEth,
- @Nonnull final int tableIndex) {
+ @Nonnull final int tableIndex,
+ final int vlanTags) {
final ClassifyAddDelSession request = createClassifySession(action, tableIndex);
request.match = new byte[16];
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java
index b2a9613..857f003 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4Writer.java
@@ -77,7 +77,8 @@ final class AceIp4Writer extends AbstractAceWriter<AceIp> {
@Override
public ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action,
@Nonnull final AceIp aceIp,
- final int nextTableIndex) {
+ final int nextTableIndex,
+ final int vlanTags) {
checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp);
final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion();
@@ -88,14 +89,16 @@ final class AceIp4Writer extends AbstractAceWriter<AceIp> {
boolean aceIsEmpty = true;
request.mask = new byte[TABLE_MASK_LENGTH];
+ final int baseOffset = getVlanTagsLen(vlanTags);
+
// First 14 bytes represent l2 header (2x6 + etherType(2))
if (aceIp.getProtocol() != null) { // Internet Protocol number
- request.mask[IP_VERSION_OFFSET] = (byte) IP_VERSION_MASK; // first 4 bits
+ request.mask[baseOffset + IP_VERSION_OFFSET] = (byte) IP_VERSION_MASK; // first 4 bits
}
if (aceIp.getDscp() != null) {
aceIsEmpty = false;
- request.mask[DSCP_OFFSET] = (byte) DSCP_MASK; // first 6 bits
+ request.mask[baseOffset + DSCP_OFFSET] = (byte) DSCP_MASK; // first 6 bits
}
if (aceIp.getSourcePortRange() != null) {
@@ -108,13 +111,15 @@ final class AceIp4Writer extends AbstractAceWriter<AceIp> {
if (ipVersion.getSourceIpv4Network() != null) {
aceIsEmpty = false;
- System.arraycopy(toByteMask(ipVersion.getSourceIpv4Network()), 0, request.mask, SRC_IP_OFFSET, IP4_LEN);
+ System.arraycopy(toByteMask(ipVersion.getSourceIpv4Network()), 0, request.mask, baseOffset + SRC_IP_OFFSET,
+ IP4_LEN);
}
if (ipVersion.getDestinationIpv4Network() != null) {
aceIsEmpty = false;
System
- .arraycopy(toByteMask(ipVersion.getDestinationIpv4Network()), 0, request.mask, DST_IP_OFFSET, IP4_LEN);
+ .arraycopy(toByteMask(ipVersion.getDestinationIpv4Network()), 0, request.mask,
+ baseOffset + DST_IP_OFFSET, IP4_LEN);
}
if (aceIsEmpty) {
@@ -132,7 +137,8 @@ final class AceIp4Writer extends AbstractAceWriter<AceIp> {
@Override
public ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action,
@Nonnull final AceIp aceIp,
- final int tableIndex) {
+ final int tableIndex,
+ final int vlanTags) {
checkArgument(aceIp.getAceIpVersion() instanceof AceIpv4, "Expected AceIpv4 version, but was %", aceIp);
final AceIpv4 ipVersion = (AceIpv4) aceIp.getAceIpVersion();
@@ -141,13 +147,16 @@ final class AceIp4Writer extends AbstractAceWriter<AceIp> {
request.match = new byte[TABLE_MASK_LENGTH];
boolean noMatch = true;
+ final int baseOffset = getVlanTagsLen(vlanTags);
+
if (aceIp.getProtocol() != null) {
- request.match[IP_VERSION_OFFSET] = (byte) (IP_VERSION_MASK & (aceIp.getProtocol().intValue() << 4));
+ request.match[baseOffset + IP_VERSION_OFFSET] =
+ (byte) (IP_VERSION_MASK & (aceIp.getProtocol().intValue() << 4));
}
if (aceIp.getDscp() != null) {
noMatch = false;
- request.match[DSCP_OFFSET] = (byte) (DSCP_MASK & (aceIp.getDscp().getValue() << 2));
+ request.match[baseOffset + DSCP_OFFSET] = (byte) (DSCP_MASK & (aceIp.getDscp().getValue() << 2));
}
if (aceIp.getSourcePortRange() != null) {
@@ -160,12 +169,15 @@ final class AceIp4Writer extends AbstractAceWriter<AceIp> {
if (ipVersion.getSourceIpv4Network() != null) {
noMatch = false;
- System.arraycopy(toMatchValue(ipVersion.getSourceIpv4Network()), 0, request.match, SRC_IP_OFFSET, IP4_LEN);
+ System
+ .arraycopy(toMatchValue(ipVersion.getSourceIpv4Network()), 0, request.match, baseOffset + SRC_IP_OFFSET,
+ IP4_LEN);
}
if (ipVersion.getDestinationIpv4Network() != null) {
noMatch = false;
- System.arraycopy(toMatchValue(ipVersion.getDestinationIpv4Network()), 0, request.match, DST_IP_OFFSET,
+ System.arraycopy(toMatchValue(ipVersion.getDestinationIpv4Network()), 0, request.match,
+ baseOffset + DST_IP_OFFSET,
IP4_LEN);
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6Writer.java
index c46f2e1..d847ed8 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6Writer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6Writer.java
@@ -92,7 +92,8 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
@Override
public ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action,
@Nonnull final AceIp aceIp,
- final int nextTableIndex) {
+ final int nextTableIndex,
+ final int vlanTags) {
checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp);
final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion();
@@ -102,15 +103,18 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
boolean aceIsEmpty = true;
request.mask = new byte[TABLE_MASK_LENGTH];
+
+ final int baseOffset = getVlanTagsLen(vlanTags);
+
if (aceIp.getProtocol() != null) {
- request.mask[IP_VERSION_OFFSET] |= IP_VERSION_MASK;
+ request.mask[baseOffset + IP_VERSION_OFFSET] |= IP_VERSION_MASK;
}
if (aceIp.getDscp() != null) {
aceIsEmpty = false;
// DCSP (bits 4-9 of IP6 header)
- request.mask[IP_VERSION_OFFSET] |= DSCP_MASK1;
- request.mask[IP_VERSION_OFFSET + 1] |= DSCP_MASK2;
+ request.mask[baseOffset + IP_VERSION_OFFSET] |= DSCP_MASK1;
+ request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= DSCP_MASK2;
}
if (aceIp.getSourcePortRange() != null) {
@@ -124,21 +128,21 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
if (ipVersion.getFlowLabel() != null) {
aceIsEmpty = false;
// bits 12-31
- request.mask[IP_VERSION_OFFSET + 1] |= (byte) 0x0f;
- request.mask[IP_VERSION_OFFSET + 2] = (byte) 0xff;
- request.mask[IP_VERSION_OFFSET + 3] = (byte) 0xff;
+ request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) 0x0f;
+ request.mask[baseOffset + IP_VERSION_OFFSET + 2] = (byte) 0xff;
+ request.mask[baseOffset + IP_VERSION_OFFSET + 3] = (byte) 0xff;
}
if (ipVersion.getSourceIpv6Network() != null) {
aceIsEmpty = false;
final byte[] mask = toByteMask(ipVersion.getSourceIpv6Network());
- System.arraycopy(mask, 0, request.mask, SRC_IP_OFFSET, mask.length);
+ System.arraycopy(mask, 0, request.mask, baseOffset + SRC_IP_OFFSET, mask.length);
}
if (ipVersion.getDestinationIpv6Network() != null) {
aceIsEmpty = false;
final byte[] mask = toByteMask(ipVersion.getDestinationIpv6Network());
- System.arraycopy(mask, 0, request.mask, DST_IP_OFFSET, mask.length);
+ System.arraycopy(mask, 0, request.mask, baseOffset + DST_IP_OFFSET, mask.length);
}
if (aceIsEmpty) {
@@ -157,7 +161,8 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
@Override
public ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action,
@Nonnull final AceIp aceIp,
- final int tableIndex) {
+ final int tableIndex,
+ final int vlanTags) {
checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp);
final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion();
@@ -165,16 +170,19 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
request.match = new byte[TABLE_MASK_LENGTH];
boolean noMatch = true;
+ final int baseOffset = getVlanTagsLen(vlanTags);
+
if (aceIp.getProtocol() != null) {
- request.match[IP_VERSION_OFFSET] |= (byte) (IP_VERSION_MASK & (aceIp.getProtocol().intValue() << 4));
+ request.match[baseOffset + IP_VERSION_OFFSET] |=
+ (byte) (IP_VERSION_MASK & (aceIp.getProtocol().intValue() << 4));
}
if (aceIp.getDscp() != null) {
noMatch = false;
final int dscp = aceIp.getDscp().getValue();
// set bits 4-9 of IP6 header:
- request.match[IP_VERSION_OFFSET] |= (byte) (DSCP_MASK1 & (dscp >> 2));
- request.match[IP_VERSION_OFFSET + 1] |= (byte) (DSCP_MASK2 & (dscp << 6));
+ request.match[baseOffset + IP_VERSION_OFFSET] |= (byte) (DSCP_MASK1 & (dscp >> 2));
+ request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (DSCP_MASK2 & (dscp << 6));
}
if (aceIp.getSourcePortRange() != null) {
@@ -189,21 +197,21 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
noMatch = false;
final int flowLabel = ipVersion.getFlowLabel().getValue().intValue();
// bits 12-31
- request.match[IP_VERSION_OFFSET + 1] |= (byte) (0x0f & (flowLabel >> 16));
- request.match[IP_VERSION_OFFSET + 2] = (byte) (0xff & (flowLabel >> 8));
- request.match[IP_VERSION_OFFSET + 3] = (byte) (0xff & flowLabel);
+ request.match[baseOffset + IP_VERSION_OFFSET + 1] |= (byte) (0x0f & (flowLabel >> 16));
+ request.match[baseOffset + IP_VERSION_OFFSET + 2] = (byte) (0xff & (flowLabel >> 8));
+ request.match[baseOffset + IP_VERSION_OFFSET + 3] = (byte) (0xff & flowLabel);
}
if (ipVersion.getSourceIpv6Network() != null) {
noMatch = false;
final byte[] match = toMatchValue(ipVersion.getSourceIpv6Network());
- System.arraycopy(match, 0, request.match, SRC_IP_OFFSET, IP6_LEN);
+ System.arraycopy(match, 0, request.match, baseOffset + SRC_IP_OFFSET, IP6_LEN);
}
if (ipVersion.getDestinationIpv6Network() != null) {
noMatch = false;
final byte[] match = toMatchValue(ipVersion.getDestinationIpv6Network());
- System.arraycopy(match, 0, request.match, DST_IP_OFFSET, IP6_LEN);
+ System.arraycopy(match, 0, request.match, baseOffset + DST_IP_OFFSET, IP6_LEN);
}
if (noMatch) {
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceWriter.java
index 2d66619..9343186 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceWriter.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceWriter.java
@@ -18,6 +18,7 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl;
import io.fd.honeycomb.translate.v3po.util.WriteTimeoutException;
import java.util.List;
+import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -39,5 +40,6 @@ interface AceWriter {
* @param request input_acl_set_interface request DTO
*/
void write(@Nonnull final InstanceIdentifier<?> id, @Nonnull final List<Ace> aces,
- @Nonnull final InputAclSetInterface request) throws VppBaseCallException, WriteTimeoutException;
+ @Nonnull final InputAclSetInterface request, @Nonnegative final int vlanTags)
+ throws VppBaseCallException, WriteTimeoutException;
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAClWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAClWriter.java
index f4ba56d..a25ddac 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAClWriter.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/IetfAClWriter.java
@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey;
@@ -121,6 +122,12 @@ public final class IetfAClWriter {
void write(@Nonnull final InstanceIdentifier<?> id, final int swIfIndex, @Nonnull final List<Acl> acls,
@Nonnull final WriteContext writeContext)
throws VppBaseCallException, WriteTimeoutException {
+ write(id, swIfIndex, acls, writeContext, 0);
+ }
+
+ void write(@Nonnull final InstanceIdentifier<?> id, final int swIfIndex, @Nonnull final List<Acl> acls,
+ @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags)
+ throws VppBaseCallException, WriteTimeoutException {
// filter ACE entries and group by AceType
final Map<AclType, List<Ace>> acesByType = acls.stream()
@@ -147,7 +154,7 @@ public final class IetfAClWriter {
if (aceWriter == null) {
LOG.warn("AceProcessor for {} not registered. Skipping ACE.", aceType);
} else {
- aceWriter.write(id, aces, request);
+ aceWriter.write(id, aces, request, numberOfTags);
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/Readme.adoc b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/Readme.adoc
index e59f72a..15b1b8c 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/Readme.adoc
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/Readme.adoc
@@ -26,7 +26,4 @@ To check how ietf-acl model was translated to classify tables/session, low-level
VPP classfier works in form of offsets and masks of 16B units.
The offset always starts at the beginning of L2 Ethernet header
of input packet. Because IP header can have variable length,
-source/destination port matching (L4 features of ietf-acl model) is not possible.
-
-Current implementation also assumes constant Ethernet header size
-(802.1Q headers are not supported). \ No newline at end of file
+source/destination port matching (L4 features of ietf-acl model) is not possible. \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/SubInterfaceIetfAclCustomizer.java
index 8942691..989aeb5 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/SubInterfaceIetfAclCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/SubInterfaceIetfAclCustomizer.java
@@ -18,7 +18,10 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils.getNumberOfTags;
+import com.google.common.base.Optional;
import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
import io.fd.honeycomb.translate.v3po.util.NamingContext;
import io.fd.honeycomb.translate.v3po.util.SubInterfaceUtils;
@@ -73,8 +76,14 @@ public class SubInterfaceIetfAclCustomizer implements WriterCustomizer<IetfAcl>
checkArgument(accessLists != null && accessLists.getAcl() != null,
"ietf-acl container does not define acl list");
+ final Optional<SubInterface> subInterfaceOptional =
+ writeContext.readAfter(id.firstIdentifierOf(SubInterface.class));
+ checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id);
+ final SubInterface subInterface = subInterfaceOptional.get();
+
try {
- aclWriter.write(id, subInterfaceIndex, accessLists.getAcl(), writeContext);
+ aclWriter.write(id, subInterfaceIndex, accessLists.getAcl(), writeContext,
+ getNumberOfTags(subInterface.getTags()));
} catch (VppBaseCallException e) {
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
}
diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/SubInterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/util/SubInterfaceUtils.java
index b325f7c..acef956 100644
--- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/SubInterfaceUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/util/SubInterfaceUtils.java
@@ -16,6 +16,12 @@
package io.fd.honeycomb.translate.v3po.util;
+import java.util.List;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nullable;
+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;
+
public final class SubInterfaceUtils {
private SubInterfaceUtils() {
@@ -25,4 +31,22 @@ public final class SubInterfaceUtils {
public static String getSubInterfaceName(final String superIfName, final int subIfaceId) {
return String.format("%s.%d", superIfName, subIfaceId);
}
+
+ /**
+ * Returns number of sub-interface tags.
+ *
+ * @param tags data object that represents sub-interface tags
+ * @return number of sub interface tags
+ */
+ @Nonnegative
+ public static int getNumberOfTags(@Nullable final Tags tags) {
+ if (tags == null) {
+ return 0;
+ }
+ final List<Tag> tagList = tags.getTag();
+ if (tagList == null) {
+ return 0;
+ }
+ return tagList.size();
+ }
}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriterTest.java
index a32659a..b5b85de 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriterTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceEthWriterTest.java
@@ -57,7 +57,7 @@ public class AceEthWriterTest {
@Test
public void testGetClassifyAddDelTableRequest() throws Exception {
final int nextTableIndex = 42;
- final ClassifyAddDelTable request = writer.createClassifyTable(action, aceEth, nextTableIndex);
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceEth, nextTableIndex, 0);
assertEquals(1, request.isAdd);
assertEquals(-1, request.tableIndex);
@@ -81,7 +81,7 @@ public class AceEthWriterTest {
@Test
public void testGetClassifyAddDelSessionRequest() throws Exception {
final int tableIndex = 123;
- final ClassifyAddDelSession request = writer.createClassifySession(action, aceEth, tableIndex);
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceEth, tableIndex, 0);
assertEquals(1, request.isAdd);
assertEquals(tableIndex, request.tableIndex);
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4WriterTest.java
index 95b8fc5..bc34a53 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4WriterTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp4WriterTest.java
@@ -16,7 +16,8 @@
package io.fd.honeycomb.translate.v3po.interfaces.acl;
-import static org.junit.Assert.assertArrayEquals;
+import static io.fd.honeycomb.translate.v3po.interfaces.acl.AbstractAceWriter.VLAN_TAG_LEN;
+import static io.fd.honeycomb.translate.v3po.interfaces.acl.AceIpWriterTestUtils.assertArrayEqualsWithOffset;
import static org.junit.Assert.assertEquals;
import static org.mockito.MockitoAnnotations.initMocks;
@@ -58,11 +59,8 @@ public class AceIp4WriterTest {
.build();
}
- @Test
- public void testGetClassifyAddDelTableRequest() throws Exception {
- final int nextTableIndex = 42;
- final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex);
-
+ private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex,
+ final int vlanTags) {
assertEquals(1, request.isAdd);
assertEquals(-1, request.tableIndex);
assertEquals(1, request.nbuckets);
@@ -77,14 +75,12 @@ public class AceIp4WriterTest {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- assertArrayEquals(expectedMask, request.mask);
- }
+ assertArrayEqualsWithOffset(expectedMask, request.mask, vlanTags * VLAN_TAG_LEN);
- @Test
- public void testGetClassifyAddDelSessionRequest() throws Exception {
- final int tableIndex = 123;
- final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex);
+ }
+ private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex,
+ final int vlanTags) {
assertEquals(1, request.isAdd);
assertEquals(tableIndex, request.tableIndex);
assertEquals(0, request.hitNextIndex);
@@ -94,7 +90,55 @@ public class AceIp4WriterTest {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 1, 2,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- assertArrayEquals(expectedMatch, request.match);
+ assertArrayEqualsWithOffset(expectedMatch, request.match, vlanTags * VLAN_TAG_LEN);
+
+ }
+
+ @Test
+ public void testGetClassifyAddDelTableRequest() throws Exception {
+ final int nextTableIndex = 42;
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex, 0);
+ verifyTableRequest(request, nextTableIndex, 0);
+ }
+
+ @Test
+ public void testGetClassifyAddDelTableRequest1VlanTag() throws Exception {
+ final int nextTableIndex = 42;
+ final int vlanTags = 1;
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex, vlanTags);
+ verifyTableRequest(request, nextTableIndex, vlanTags);
+ }
+
+ @Test
+ public void testGetClassifyAddDelTableRequest2VlanTags() throws Exception {
+ final int nextTableIndex = 42;
+ final int vlanTags = 2;
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex, vlanTags);
+ verifyTableRequest(request, nextTableIndex, vlanTags);
+ }
+
+ @Test
+ public void testGetClassifyAddDelSessionRequest() throws Exception {
+ final int tableIndex = 123;
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex, 0);
+ verifySessionRequest(request, tableIndex, 0);
+ }
+
+ @Test
+ public void testGetClassifyAddDelSessionRequest1VlanTag() throws Exception {
+ final int tableIndex = 123;
+ final int vlanTags = 1;
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex, vlanTags);
+ verifySessionRequest(request, tableIndex, vlanTags);
+ }
+
+ @Test
+ public void testGetClassifyAddDelSessionRequest2VlanTags() throws Exception {
+ final int tableIndex = 123;
+ final int vlanTags = 2;
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex, vlanTags);
+
+ verifySessionRequest(request, tableIndex, vlanTags);
}
@Test
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6WriterTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6WriterTest.java
index 1818468..4af240c 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6WriterTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIp6WriterTest.java
@@ -16,7 +16,8 @@
package io.fd.honeycomb.translate.v3po.interfaces.acl;
-import static org.junit.Assert.assertArrayEquals;
+import static io.fd.honeycomb.translate.v3po.interfaces.acl.AbstractAceWriter.VLAN_TAG_LEN;
+import static io.fd.honeycomb.translate.v3po.interfaces.acl.AceIpWriterTestUtils.assertArrayEqualsWithOffset;
import static org.junit.Assert.assertEquals;
import static org.mockito.MockitoAnnotations.initMocks;
@@ -60,11 +61,9 @@ public class AceIp6WriterTest {
.build();
}
- @Test
- public void testGetClassifyAddDelTableRequest() throws Exception {
- final int nextTableIndex = 42;
- final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex);
+ private static void verifyTableRequest(final ClassifyAddDelTable request, final int nextTableIndex,
+ final int vlanTags) {
assertEquals(1, request.isAdd);
assertEquals(-1, request.tableIndex);
assertEquals(1, request.nbuckets);
@@ -89,14 +88,12 @@ public class AceIp6WriterTest {
// padding to multiple of 16B:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- assertArrayEquals(expectedMask, request.mask);
- }
+ assertArrayEqualsWithOffset(expectedMask, request.mask, vlanTags * VLAN_TAG_LEN);
- @Test
- public void testGetClassifyAddDelSessionRequest() throws Exception {
- final int tableIndex = 123;
- final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex);
+ }
+ private static void verifySessionRequest(final ClassifyAddDelSession request, final int tableIndex,
+ final int vlanTags) {
assertEquals(1, request.isAdd);
assertEquals(tableIndex, request.tableIndex);
assertEquals(0, request.hitNextIndex);
@@ -116,7 +113,54 @@ public class AceIp6WriterTest {
// padding to multiple of 16B:
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
- assertArrayEquals(expectedMatch, request.match);
+ assertArrayEqualsWithOffset(expectedMatch, request.match, vlanTags * VLAN_TAG_LEN);
+
+ }
+
+ @Test
+ public void testGetClassifyAddDelTableRequest() throws Exception {
+ final int nextTableIndex = 42;
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex, 0);
+ verifyTableRequest(request, nextTableIndex, 0);
+ }
+
+ @Test
+ public void testGetClassifyAddDelTableRequest1VlanTag() throws Exception {
+ final int nextTableIndex = 42;
+ final int vlanTags = 1;
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex, vlanTags);
+ verifyTableRequest(request, nextTableIndex, vlanTags);
+ }
+
+ @Test
+ public void testGetClassifyAddDelTableRequest2VlanTag() throws Exception {
+ final int nextTableIndex = 42;
+ final int vlanTags = 2;
+ final ClassifyAddDelTable request = writer.createClassifyTable(action, aceIp, nextTableIndex, vlanTags);
+ verifyTableRequest(request, nextTableIndex, vlanTags);
+ }
+
+ @Test
+ public void testGetClassifyAddDelSessionRequest() throws Exception {
+ final int tableIndex = 123;
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex, 0);
+ verifySessionRequest(request, tableIndex, 0);
+ }
+
+ @Test
+ public void testGetClassifyAddDelSessionRequest1VlanTag() throws Exception {
+ final int tableIndex = 123;
+ final int vlanTags = 1;
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex, vlanTags);
+ verifySessionRequest(request, tableIndex, vlanTags);
+ }
+
+ @Test
+ public void testGetClassifyAddDelSessionRequest2VlanTag() throws Exception {
+ final int tableIndex = 123;
+ final int vlanTags = 2;
+ final ClassifyAddDelSession request = writer.createClassifySession(action, aceIp, tableIndex, vlanTags);
+ verifySessionRequest(request, tableIndex, vlanTags);
}
@Test
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIpWriterTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIpWriterTestUtils.java
new file mode 100644
index 0000000..6b176b6
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AceIpWriterTestUtils.java
@@ -0,0 +1,34 @@
+/*
+ * 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.translate.v3po.interfaces.acl;
+
+import static org.junit.Assert.assertArrayEquals;
+
+final class AceIpWriterTestUtils {
+
+ private AceIpWriterTestUtils() {
+ throw new UnsupportedOperationException("This utility class cannot be instantiated");
+ }
+
+ protected static void assertArrayEqualsWithOffset(final byte[] baseExpected, final byte[] actual,
+ final int offset) {
+ byte[] expected = new byte[baseExpected.length];
+ System.arraycopy(baseExpected, 0, expected, offset, expected.length - offset);
+
+ assertArrayEquals(expected, actual);
+ }
+}
diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/SubinterfaceUtilsTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/util/SubinterfaceUtilsTest.java
index fb8a806..fb8a806 100644
--- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/SubinterfaceUtilsTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/util/SubinterfaceUtilsTest.java