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;
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");
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;
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;
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;
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
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;
// 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();
* @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.
* @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.
*/
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);
}
return request;
}
+
+ protected int getVlanTagsLen(final int vlanTags) {
+ return vlanTags * VLAN_TAG_LEN;
+ }
}
@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];
@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];
@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();
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) {
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) {
@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();
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) {
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);
}
@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();
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) {
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) {
@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();
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) {
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) {
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;
* @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;
}
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;
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()
if (aceWriter == null) {
LOG.warn("AceProcessor for {} not registered. Skipping ACE.", aceType);
} else {
- aceWriter.write(id, aces, request);
+ aceWriter.write(id, aces, request, numberOfTags);
}
}
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
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;
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);
}
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() {
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();
+ }
}
@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);
@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);
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;
.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);
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);
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
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;
.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);
// 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);
// 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
--- /dev/null
+/*
+ * 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);
+ }
+}