summaryrefslogtreecommitdiffstats
path: root/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java')
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java191
1 files changed, 17 insertions, 174 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java
index f1cccba92..b1186440d 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/AceIp6Writer.java
@@ -19,142 +19,39 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl.ingress;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.annotations.VisibleForTesting;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.BitSet;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
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;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv6;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
-import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession;
-import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable;
-import io.fd.vpp.jvpp.core.dto.InputAclSetInterface;
-import io.fd.vpp.jvpp.core.future.FutureJVppCore;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-final class AceIp6Writer extends AbstractAceWriter<AceIp> {
+final class AceIp6Writer implements AceWriter<AceIp>, AclTranslator, Ip6AclTranslator {
@VisibleForTesting
static final int MATCH_N_VECTORS = 4; // number of 16B vectors
- private static final Logger LOG = LoggerFactory.getLogger(AceIp6Writer.class);
private static final int TABLE_MASK_LENGTH = 64;
- private static final int IP6_MASK_BIT_LENGTH = 128;
-
- private static final int ETHER_TYPE_OFFSET = 12; // first 14 bytes represent L2 header (2x6)
- private static final int IP_VERSION_OFFSET = ETHER_TYPE_OFFSET+2;
- private static final int DSCP_MASK1 = 0x0f;
- private static final int DSCP_MASK2 = 0xc0;
- private static final int IP_PROTOCOL_OFFSET = IP_VERSION_OFFSET+6;
- private static final int IP_PROTOCOL_MASK = 0xff;
- private static final int IP6_LEN = 16;
- private static final int SRC_IP_OFFSET = IP_VERSION_OFFSET + 8;
- private static final int DST_IP_OFFSET = SRC_IP_OFFSET + IP6_LEN;
-
- public AceIp6Writer(@Nonnull final FutureJVppCore futureJVppCore) {
- super(futureJVppCore);
- }
-
- private static byte[] toByteMask(final int prefixLength) {
- final BitSet mask = new BitSet(IP6_MASK_BIT_LENGTH);
- mask.set(0, prefixLength, true);
- if (prefixLength < IP6_MASK_BIT_LENGTH) {
- mask.set(prefixLength, IP6_MASK_BIT_LENGTH, false);
- }
- return mask.toByteArray();
- }
-
- private static byte[] toByteMask(final Ipv6Prefix ipv6Prefix) {
- final int prefixLength = Short.valueOf(ipv6Prefix.getValue().split("/")[1]);
- return toByteMask(prefixLength);
- }
-
- private static byte[] toMatchValue(final Ipv6Prefix ipv6Prefix) {
- final String[] split = ipv6Prefix.getValue().split("/");
- final byte[] addressBytes;
- try {
- addressBytes = InetAddress.getByName(split[0]).getAddress();
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException("Invalid IP6 address", e);
- }
- final byte[] mask = toByteMask(Short.valueOf(split[1]));
- int pos = 0;
- for (; pos < mask.length; ++pos) {
- addressBytes[pos] &= mask[pos];
- }
- // mask can be shorter that address, so we need to clear rest of the address:
- for (; pos < addressBytes.length; ++pos) {
- addressBytes[pos] = 0;
- }
- return addressBytes;
- }
+ private static final Logger LOG = LoggerFactory.getLogger(AceIp6Writer.class);
@Override
- public ClassifyAddDelTable createClassifyTable(@Nonnull final AceIp aceIp,
- @Nullable final InterfaceMode mode,
- final int nextTableIndex,
- final int vlanTags) {
+ public ClassifyAddDelTable createTable(@Nonnull final AceIp aceIp,
+ @Nullable final InterfaceMode mode,
+ final int nextTableIndex,
+ final int vlanTags) {
checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp);
final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion();
- final ClassifyAddDelTable request = createClassifyTable(nextTableIndex);
+ final ClassifyAddDelTable request = createTable(nextTableIndex);
request.skipNVectors = 0; // match entire L2 and L3 header
request.matchNVectors = MATCH_N_VECTORS;
-
- boolean aceIsEmpty = true;
request.mask = new byte[TABLE_MASK_LENGTH];
final int baseOffset = getVlanTagsLen(vlanTags);
-
- if (InterfaceMode.L2.equals(mode)) {
- // in L2 mode we need to match ether type
- request.mask[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0xff;
- request.mask[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xff;
- }
-
- if (aceIp.getDscp() != null) {
- aceIsEmpty = false;
- // DCSP (bits 4-9 of IP6 header)
- request.mask[baseOffset + IP_VERSION_OFFSET] |= DSCP_MASK1;
- request.mask[baseOffset + IP_VERSION_OFFSET + 1] |= DSCP_MASK2;
- }
-
- if (aceIp.getProtocol() != null) {
- aceIsEmpty = false;
- request.mask[baseOffset + IP_PROTOCOL_OFFSET] = (byte) IP_PROTOCOL_MASK;
- }
-
- if (aceIp.getSourcePortRange() != null) {
- LOG.warn("L4 Header fields are not supported. Ignoring {}", aceIp.getSourcePortRange());
- }
-
- if (aceIp.getDestinationPortRange() != null) {
- LOG.warn("L4 Header fields are not supported. Ignoring {}", aceIp.getDestinationPortRange());
- }
-
- if (ipVersion.getFlowLabel() != null) {
- aceIsEmpty = false;
- // bits 12-31
- 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, baseOffset + SRC_IP_OFFSET, mask.length);
- }
-
- if (ipVersion.getDestinationIpv6Network() != null) {
- aceIsEmpty = false;
- final byte[] mask = toByteMask(ipVersion.getDestinationIpv6Network());
- System.arraycopy(mask, 0, request.mask, baseOffset + DST_IP_OFFSET, mask.length);
- }
-
+ boolean aceIsEmpty = ip6Mask(baseOffset, mode, aceIp, ipVersion, request, LOG);
if (aceIsEmpty) {
throw new IllegalArgumentException(
String.format("Ace %s does not define packet field match values", aceIp.toString()));
@@ -165,68 +62,19 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
}
@Override
- public ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action,
- @Nonnull final AceIp aceIp,
- @Nullable final InterfaceMode mode,
- final int tableIndex,
- final int vlanTags) {
+ public ClassifyAddDelSession createSession(@Nonnull final PacketHandling action,
+ @Nonnull final AceIp aceIp,
+ @Nullable final InterfaceMode mode,
+ final int tableIndex,
+ final int vlanTags) {
checkArgument(aceIp.getAceIpVersion() instanceof AceIpv6, "Expected AceIpv6 version, but was %", aceIp);
final AceIpv6 ipVersion = (AceIpv6) aceIp.getAceIpVersion();
- final ClassifyAddDelSession request = createClassifySession(action, tableIndex);
+ final ClassifyAddDelSession request = createSession(action, tableIndex);
request.match = new byte[TABLE_MASK_LENGTH];
- boolean noMatch = true;
final int baseOffset = getVlanTagsLen(vlanTags);
-
- if (InterfaceMode.L2.equals(mode)) {
- // match IP6 etherType (0x86dd)
- request.match[baseOffset + ETHER_TYPE_OFFSET] = (byte) 0x86;
- request.match[baseOffset + ETHER_TYPE_OFFSET + 1] = (byte) 0xdd;
- }
-
- if (aceIp.getDscp() != null) {
- noMatch = false;
- final int dscp = aceIp.getDscp().getValue();
- // set bits 4-9 of IP6 header:
- 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.getProtocol() != null) {
- noMatch = false;
- request.match[baseOffset + IP_PROTOCOL_OFFSET] = (byte) (IP_PROTOCOL_MASK & aceIp.getProtocol());
- }
-
- if (aceIp.getSourcePortRange() != null) {
- LOG.warn("L4 Header fields are not supported. Ignoring {}", aceIp.getSourcePortRange());
- }
-
- if (aceIp.getDestinationPortRange() != null) {
- LOG.warn("L4 Header fields are not supported. Ignoring {}", aceIp.getDestinationPortRange());
- }
-
- if (ipVersion.getFlowLabel() != null) {
- noMatch = false;
- final int flowLabel = ipVersion.getFlowLabel().getValue().intValue();
- // bits 12-31
- 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, baseOffset + SRC_IP_OFFSET, IP6_LEN);
- }
-
- if (ipVersion.getDestinationIpv6Network() != null) {
- noMatch = false;
- final byte[] match = toMatchValue(ipVersion.getDestinationIpv6Network());
- System.arraycopy(match, 0, request.match, baseOffset + DST_IP_OFFSET, IP6_LEN);
- }
-
+ boolean noMatch = ip6Match(baseOffset, mode, aceIp, ipVersion, request, LOG);
if (noMatch) {
throw new IllegalArgumentException(
String.format("Ace %s does not define packet field match values", aceIp.toString()));
@@ -235,9 +83,4 @@ final class AceIp6Writer extends AbstractAceWriter<AceIp> {
LOG.debug("ACE action={}, rule={} translated to session={}.", action, aceIp, request);
return request;
}
-
- @Override
- protected void setClassifyTable(@Nonnull final InputAclSetInterface request, final int tableIndex) {
- request.ip6TableIndex = tableIndex;
- }
}