From 4eee8fa4da610eced563f12f9ee935130fdb09c7 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Mon, 13 Aug 2018 17:18:23 +0200 Subject: HC2VPP-375: align classify session's match with skip-n-vectors zeros If bigger values of skip-n-vectors are used (e.g. policer usecase), also key is very long, making the API hard to use. To make it easier, match value will be now aligned with zeros if needed. Read part does not need to be updated, beacause classify_session_dump returns match without skip-n-vectors part. Change-Id: Iab54480e7a3851690aed30c8f5b8b0e6769c054f Signed-off-by: Marek Gradzki --- .../classifier/write/ClassifySessionWriter.java | 23 ++++++++-------- .../write/ClassifySessionWriterTest.java | 31 +++++++++------------- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java index 7a62e4a74..5674547d7 100644 --- a/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java +++ b/vpp-classifier/impl/src/main/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriter.java @@ -16,7 +16,6 @@ package io.fd.hc2vpp.vpp.classifier.write; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Optional; @@ -115,7 +114,8 @@ public class ClassifySessionWriter extends VppNodeWriter final int tableIndex = classifyTableContext.getTableIndex(tableName, writeContext.getMappingContext()); final ClassifyTable classifyTable = getClassifyTable(writeContext, id, isAdd); - final ClassifyAddDelSession request = getClassifyAddDelSessionRequest(isAdd, classifySession, tableIndex); + final ClassifyAddDelSession request = + getClassifyAddDelSessionRequest(isAdd, classifySession, classifyTable, tableIndex); // TODO(HC2VPP-9): registry of next_node translators would allow to weaken dependency between policer // and vpp-classifier models @@ -127,14 +127,6 @@ public class ClassifySessionWriter extends VppNodeWriter } final CompletionStage createClassifyTableReplyCompletionStage = getFutureJVpp() .classifyAddDelSession(request); - - // VPP requires to prepend classify session with skip_n_vectors*16 bytes: - final long expectedMatchLen = - 16 * classifyTable.getSkipNVectors() + getBinaryVector(classifyTable.getMask()).length; - final long actualMatchLen = Integer.toUnsignedLong(request.matchLen); - checkArgument(actualMatchLen == expectedMatchLen, - "Match length should be equal to table.skipNVectors*16 + table.mask length (" - + expectedMatchLen + ") but was: " + actualMatchLen); getReplyForWrite(createClassifyTableReplyCompletionStage.toCompletableFuture(), id); } @@ -168,6 +160,7 @@ public class ClassifySessionWriter extends VppNodeWriter private ClassifyAddDelSession getClassifyAddDelSessionRequest(final boolean isAdd, @Nonnull final ClassifySession classifySession, + final ClassifyTable classifyTable, final int tableIndex) { ClassifyAddDelSession request = new ClassifyAddDelSession(); request.isAdd = booleanToByte(isAdd); @@ -176,8 +169,14 @@ public class ClassifySessionWriter extends VppNodeWriter // default 0: request.advance = classifySession.getAdvance(); - request.match = getBinaryVector(classifySession.getMatch()); - request.matchLen = request.match.length; + // VPP requires match vector of size mask + skip_n_vectors*16 bytes, + // so align it with zeros: + final int matchLength = + (int) (16 * classifyTable.getSkipNVectors() + getBinaryVector(classifyTable.getMask()).length); + request.match = new byte[matchLength]; + final byte[] actualMatch = getBinaryVector(classifySession.getMatch()); + System.arraycopy(actualMatch, 0, request.match, 0, actualMatch.length); + request.matchLen = matchLength; return request; } diff --git a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java index 68d20a728..c33a21ece 100644 --- a/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java +++ b/vpp-classifier/impl/src/test/java/io/fd/hc2vpp/vpp/classifier/write/ClassifySessionWriterTest.java @@ -78,15 +78,20 @@ public class ClassifySessionWriterTest extends WriterCustomizerTest { private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex, final int sessionIndex) { + return generateClassifyAddDelSession(isAdd, tableIndex, sessionIndex, + new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, + (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}); + } + + private static ClassifyAddDelSession generateClassifyAddDelSession(final byte isAdd, final int tableIndex, + final int sessionIndex, final byte[] match) { final ClassifyAddDelSession request = new ClassifyAddDelSession(); request.isAdd = isAdd; request.tableIndex = tableIndex; request.opaqueIndex = sessionIndex; request.hitNextIndex = 0; request.advance = 123; - request.match = - new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, - (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00}; + request.match = match; request.matchLen = request.match.length; return request; } @@ -193,19 +198,6 @@ public class ClassifySessionWriterTest extends WriterCustomizerTest { customizer.writeCurrentAttributes(id, classifySession, writeContext); } - @Test(expected = IllegalArgumentException.class) - public void testCreateInvalidMatchLength() throws WriteFailedException { - final ClassifyTable table = mock(ClassifyTable.class); - when(table.getMask()).thenReturn(new HexString("00:00:00:00:00:00:ff:FF:ff:ff:ff:FF:00:00:00:00")); - when(table.getSkipNVectors()).thenReturn(1L); - when(writeContext.readAfter(ArgumentMatchers.any())).thenReturn(Optional.of(table)); - - final String match = "00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; - final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); - final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); - customizer.writeCurrentAttributes(id, classifySession, writeContext); - } - @Test public void testCreateSkipOneVector() throws WriteFailedException { final ClassifyTable table = mock(ClassifyTable.class); @@ -214,10 +206,13 @@ public class ClassifySessionWriterTest extends WriterCustomizerTest { when(writeContext.readAfter(ArgumentMatchers.any())).thenReturn(Optional.of(table)); whenClassifyAddDelSessionThenSuccess(); - final String match = - "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01:02:03:04:05:06:00:00:00:00"; + final String match = "01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10"; final ClassifySession classifySession = generateClassifySession(SESSION_INDEX, match); final InstanceIdentifier id = getClassifySessionId(TABLE_NAME, match); customizer.writeCurrentAttributes(id, classifySession, writeContext); + verify(api).classifyAddDelSession(generateClassifyAddDelSession((byte) 1, TABLE_INDEX, SESSION_INDEX, + new byte[] { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); } } \ No newline at end of file -- cgit 1.2.3-korg