diff options
Diffstat (limited to 'v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java')
-rw-r--r-- | v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/AbstractAceWriter.java | 104 |
1 files changed, 80 insertions, 24 deletions
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 9f27271b5..21a710701 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 @@ -27,6 +27,7 @@ import java.util.stream.Collector; 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; +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.packet.handling.Permit; 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.AceType; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.jvpp.VppBaseCallException; @@ -37,7 +38,21 @@ import org.openvpp.jvpp.core.dto.ClassifyAddDelTableReply; import org.openvpp.jvpp.core.dto.InputAclSetInterface; import org.openvpp.jvpp.core.future.FutureJVppCore; +/** + * Base writer for translation of ietf-acl model ACEs to VPP's classify tables and sessions. + * + * Creates one classify table with single session per ACE. + * + * @param <T> type of access control list entry + */ abstract class AbstractAceWriter<T extends AceType> implements AceWriter { + + // TODO: minimise memory used by classify tables (we create a lot of them to make ietf-acl model + // mapping more convenient): + // according to https://wiki.fd.io/view/VPP/Introduction_To_N-tuple_Classifiers#Creating_a_classifier_table, + // 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; + private static final Collector<PacketHandling, ?, PacketHandling> SINGLE_ITEM_COLLECTOR = RWUtils.singleItemCollector(); @@ -47,19 +62,36 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter { this.futureJVppCore = checkNotNull(futureJVppCore, "futureJVppCore should not be null"); } - @Nonnull - public FutureJVppCore getFutureJVppCore() { - return futureJVppCore; - } - - protected abstract ClassifyAddDelTable getClassifyAddDelTableRequest(@Nonnull final PacketHandling action, - @Nonnull final T ace, - final int nextTableIndex); - - protected abstract ClassifyAddDelSession getClassifyAddDelSessionRequest(@Nonnull final PacketHandling action, - @Nonnull final T ace, - final int nextTableIndex); - + /** + * Creates classify table for given ACE. + * + * @param action packet handling action (permit/deny) + * @param ace ACE to be translated + * @param nextTableIndex classify table index + * @return classify table that represents given ACE + */ + protected abstract ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action, + @Nonnull final T ace, + final int nextTableIndex); + + /** + * 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 + * @return classify session that represents given ACE + */ + protected abstract ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action, + @Nonnull final T ace, + final int tableIndex); + + /** + * Sets classify table index for input_acl_set_interface request. + * + * @param request request DTO + * @param tableIndex pointer to a chain of classify tables + */ protected abstract void setClassifyTable(@Nonnull final InputAclSetInterface request, final int tableIndex); public final void write(@Nonnull final InstanceIdentifier<?> id, @Nonnull final List<Ace> aces, @@ -68,24 +100,17 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter { final PacketHandling action = aces.stream().map(ace -> ace.getActions().getPacketHandling()).distinct() .collect(SINGLE_ITEM_COLLECTOR); - int firstTableIndex = -1; int nextTableIndex = -1; for (final Ace ace : aces) { - // Create table + session per entry. We actually need one table for each nonempty subset of params, - // so we could decrease number of tables to 109 = 15 (eth) + 31 (ip4) + 63 (ip6) for general case. - // TODO: For special cases like many ACEs of similar kind, it could be significant optimization. + // Create table + session per entry final ClassifyAddDelTable ctRequest = - getClassifyAddDelTableRequest(action, (T) ace.getMatches().getAceType(), nextTableIndex); + createClassifyTable(action, (T) ace.getMatches().getAceType(), nextTableIndex); nextTableIndex = createClassifyTable(id, ctRequest); createClassifySession(id, - getClassifyAddDelSessionRequest(action, (T) ace.getMatches().getAceType(), nextTableIndex)); - if (firstTableIndex == -1) { - firstTableIndex = nextTableIndex; - } + createClassifySession(action, (T) ace.getMatches().getAceType(), nextTableIndex)); } - - setClassifyTable(request, firstTableIndex); + setClassifyTable(request, nextTableIndex); } private int createClassifyTable(@Nonnull final InstanceIdentifier<?> id, @@ -104,4 +129,35 @@ abstract class AbstractAceWriter<T extends AceType> implements AceWriter { TranslateUtils.getReplyForWrite(cs.toCompletableFuture(), id); } + + protected ClassifyAddDelTable createClassifyTable(@Nonnull final PacketHandling action, final int nextTableIndex) { + final ClassifyAddDelTable request = new ClassifyAddDelTable(); + request.isAdd = 1; + request.tableIndex = -1; // value not present + + request.nbuckets = 1; // we expect exactly one session per table + + if (action instanceof Permit) { + request.missNextIndex = 0; // for list of permit rules, deny (0) should be default action + } else { // deny is default value + request.missNextIndex = -1; // for list of deny rules, permit (-1) should be default action + } + + request.nextTableIndex = nextTableIndex; + request.memorySize = TABLE_MEM_SIZE; + + return request; + } + + protected ClassifyAddDelSession createClassifySession(@Nonnull final PacketHandling action, final int tableIndex) { + final ClassifyAddDelSession request = new ClassifyAddDelSession(); + request.isAdd = 1; + request.tableIndex = tableIndex; + + if (action instanceof Permit) { + request.hitNextIndex = -1; + } // deny (0) is default value + + return request; + } } |