Committed by
Jonathan Hart
Added dump of table entry ids in bmv2 protocol
Change-Id: I54534cfb2c6188c922b36a2f8eb8e5c0851bc681
Showing
4 changed files
with
197 additions
and
0 deletions
| ... | @@ -19,6 +19,7 @@ package org.onosproject.bmv2.api.runtime; | ... | @@ -19,6 +19,7 @@ package org.onosproject.bmv2.api.runtime; |
| 19 | import org.onlab.util.ImmutableByteSequence; | 19 | import org.onlab.util.ImmutableByteSequence; |
| 20 | 20 | ||
| 21 | import java.util.Collection; | 21 | import java.util.Collection; |
| 22 | +import java.util.List; | ||
| 22 | 23 | ||
| 23 | /** | 24 | /** |
| 24 | * RPC client to control a BMv2 device. | 25 | * RPC client to control a BMv2 device. |
| ... | @@ -83,6 +84,24 @@ public interface Bmv2Client { | ... | @@ -83,6 +84,24 @@ public interface Bmv2Client { |
| 83 | String dumpTable(String tableName) throws Bmv2RuntimeException; | 84 | String dumpTable(String tableName) throws Bmv2RuntimeException; |
| 84 | 85 | ||
| 85 | /** | 86 | /** |
| 87 | + * Returns a list of ids for the entries installed in the given table. | ||
| 88 | + * | ||
| 89 | + * @param tableName string value of table name | ||
| 90 | + * @return a list of entry ids | ||
| 91 | + * @throws Bmv2RuntimeException if any error occurs | ||
| 92 | + */ | ||
| 93 | + List<Long> getInstalledEntryIds(String tableName) throws Bmv2RuntimeException; | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Removes all entries installed in the given table. | ||
| 97 | + * | ||
| 98 | + * @param tableName string value of table name | ||
| 99 | + * @return the number of entries removed | ||
| 100 | + * @throws Bmv2RuntimeException if any error occurs | ||
| 101 | + */ | ||
| 102 | + int cleanupTable(String tableName) throws Bmv2RuntimeException; | ||
| 103 | + | ||
| 104 | + /** | ||
| 86 | * Requests the device to transmit a given byte sequence over the given port. | 105 | * Requests the device to transmit a given byte sequence over the given port. |
| 87 | * | 106 | * |
| 88 | * @param portNumber a port number | 107 | * @param portNumber a port number | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.bmv2.ctl; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | +import org.apache.commons.lang3.tuple.Pair; | ||
| 21 | + | ||
| 22 | +import java.util.List; | ||
| 23 | +import java.util.regex.Matcher; | ||
| 24 | +import java.util.regex.Pattern; | ||
| 25 | +import java.util.stream.Collectors; | ||
| 26 | + | ||
| 27 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * String parser for the BMv2 table dump. | ||
| 31 | + */ | ||
| 32 | +public class Bmv2TableDumpParser { | ||
| 33 | + | ||
| 34 | + /* | ||
| 35 | + Example of BMv2 table dump: | ||
| 36 | + 0: 0000 000000000000 000000000000 0806 &&& 0000000000000000000000000000ffff => send_to_cpu - | ||
| 37 | + | ||
| 38 | + For each entry, we want to match the id and all the rest. | ||
| 39 | + */ | ||
| 40 | + private static final String ENTRY_PATTERN_STRING = "(\\d+):(.+)"; | ||
| 41 | + private static final Pattern ENTRY_PATTERN = Pattern.compile(ENTRY_PATTERN_STRING); | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * Returns a list of entry Ids for the given table dump. | ||
| 45 | + * | ||
| 46 | + * @param tableDump a string value | ||
| 47 | + * @return a list of long values | ||
| 48 | + * @throws Bmv2TableDumpParserException if dump can't be parsed | ||
| 49 | + */ | ||
| 50 | + public List<Long> getEntryIds(String tableDump) throws Bmv2TableDumpParserException { | ||
| 51 | + return parse(tableDump).stream().map(Pair::getKey).collect(Collectors.toList()); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + private List<Pair<Long, String>> parse(String tableDump) throws Bmv2TableDumpParserException { | ||
| 55 | + checkNotNull(tableDump, "tableDump cannot be null"); | ||
| 56 | + | ||
| 57 | + List<Pair<Long, String>> results = Lists.newArrayList(); | ||
| 58 | + | ||
| 59 | + // TODO: consider caching parser results for speed. | ||
| 60 | + | ||
| 61 | + Matcher matcher = ENTRY_PATTERN.matcher(tableDump); | ||
| 62 | + | ||
| 63 | + while (matcher.find()) { | ||
| 64 | + String entryString = matcher.group(1); | ||
| 65 | + if (entryString == null) { | ||
| 66 | + throw new Bmv2TableDumpParserException("Unable to parse entry for string: " + matcher.group()); | ||
| 67 | + } | ||
| 68 | + Long entryId = -1L; | ||
| 69 | + try { | ||
| 70 | + entryId = Long.valueOf(entryString.trim()); | ||
| 71 | + } catch (NumberFormatException e) { | ||
| 72 | + throw new Bmv2TableDumpParserException("Unable to parse entry id for string: " + matcher.group()); | ||
| 73 | + } | ||
| 74 | + String allTheRest = matcher.group(2); | ||
| 75 | + if (allTheRest == null) { | ||
| 76 | + throw new Bmv2TableDumpParserException("Unable to parse entry for string: " + matcher.group()); | ||
| 77 | + } | ||
| 78 | + results.add(Pair.of(entryId, allTheRest)); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + return results; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + public class Bmv2TableDumpParserException extends Throwable { | ||
| 85 | + public Bmv2TableDumpParserException(String msg) { | ||
| 86 | + super(msg); | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | +} |
| ... | @@ -90,6 +90,9 @@ public final class Bmv2ThriftClient implements Bmv2Client { | ... | @@ -90,6 +90,9 @@ public final class Bmv2ThriftClient implements Bmv2Client { |
| 90 | .expireAfterAccess(CLIENT_CACHE_TIMEOUT, TimeUnit.SECONDS) | 90 | .expireAfterAccess(CLIENT_CACHE_TIMEOUT, TimeUnit.SECONDS) |
| 91 | .removalListener(new ClientRemovalListener()) | 91 | .removalListener(new ClientRemovalListener()) |
| 92 | .build(new ClientLoader()); | 92 | .build(new ClientLoader()); |
| 93 | + | ||
| 94 | + private static final Bmv2TableDumpParser TABLE_DUMP_PARSER = new Bmv2TableDumpParser(); | ||
| 95 | + | ||
| 93 | private final Standard.Iface standardClient; | 96 | private final Standard.Iface standardClient; |
| 94 | private final SimpleSwitch.Iface simpleSwitchClient; | 97 | private final SimpleSwitch.Iface simpleSwitchClient; |
| 95 | private final TTransport transport; | 98 | private final TTransport transport; |
| ... | @@ -391,6 +394,44 @@ public final class Bmv2ThriftClient implements Bmv2Client { | ... | @@ -391,6 +394,44 @@ public final class Bmv2ThriftClient implements Bmv2Client { |
| 391 | } | 394 | } |
| 392 | 395 | ||
| 393 | @Override | 396 | @Override |
| 397 | + public List<Long> getInstalledEntryIds(String tableName) throws Bmv2RuntimeException { | ||
| 398 | + | ||
| 399 | + LOG.debug("Getting entry ids... > deviceId={}, tableName={}", deviceId, tableName); | ||
| 400 | + | ||
| 401 | + try { | ||
| 402 | + List<Long> entryIds = TABLE_DUMP_PARSER.getEntryIds(dumpTable(tableName)); | ||
| 403 | + LOG.debug("Entry ids retrieved! > deviceId={}, tableName={}, entryIdsCount={}", | ||
| 404 | + deviceId, tableName, entryIds.size()); | ||
| 405 | + return entryIds; | ||
| 406 | + } catch (Bmv2TableDumpParser.Bmv2TableDumpParserException e) { | ||
| 407 | + LOG.debug("Exception while retrieving entry ids: {} > deviceId={}, tableName={}", | ||
| 408 | + e, deviceId, tableName); | ||
| 409 | + throw new Bmv2RuntimeException(e.getMessage(), e); | ||
| 410 | + } | ||
| 411 | + } | ||
| 412 | + | ||
| 413 | + @Override | ||
| 414 | + public int cleanupTable(String tableName) throws Bmv2RuntimeException { | ||
| 415 | + | ||
| 416 | + LOG.debug("Starting table cleanup... > deviceId={}, tableName={}", deviceId, tableName); | ||
| 417 | + | ||
| 418 | + List<Long> entryIds = getInstalledEntryIds(tableName); | ||
| 419 | + | ||
| 420 | + int count = 0; | ||
| 421 | + for (Long entryId : entryIds) { | ||
| 422 | + try { | ||
| 423 | + standardClient.bm_mt_delete_entry(CONTEXT_ID, tableName, entryId); | ||
| 424 | + count++; | ||
| 425 | + } catch (TException e) { | ||
| 426 | + LOG.warn("Exception while deleting entry: {} > deviceId={}, tableName={}, entryId={}", | ||
| 427 | + e.toString(), deviceId, tableName, entryId); | ||
| 428 | + } | ||
| 429 | + } | ||
| 430 | + | ||
| 431 | + return count; | ||
| 432 | + } | ||
| 433 | + | ||
| 434 | + @Override | ||
| 394 | public void transmitPacket(int portNumber, ImmutableByteSequence packet) throws Bmv2RuntimeException { | 435 | public void transmitPacket(int portNumber, ImmutableByteSequence packet) throws Bmv2RuntimeException { |
| 395 | 436 | ||
| 396 | LOG.debug("Requesting packet transmission... > portNumber={}, packet={}", portNumber, packet); | 437 | LOG.debug("Requesting packet transmission... > portNumber={}, packet={}", portNumber, packet); | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.bmv2.api.model; | ||
| 18 | + | ||
| 19 | +import org.junit.Test; | ||
| 20 | +import org.onosproject.bmv2.ctl.Bmv2TableDumpParser; | ||
| 21 | + | ||
| 22 | +import java.util.List; | ||
| 23 | + | ||
| 24 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
| 25 | +import static org.hamcrest.core.Is.is; | ||
| 26 | +import static org.hamcrest.core.IsEqual.equalTo; | ||
| 27 | + | ||
| 28 | +public class Bmv2TableDumpParserTest { | ||
| 29 | + | ||
| 30 | + @Test | ||
| 31 | + public void testParse() throws Exception, Bmv2TableDumpParser.Bmv2TableDumpParserException { | ||
| 32 | + | ||
| 33 | + String text = | ||
| 34 | + "0: 0000 000000000000 000000000000 &&& 0000000000000000000000000000 => send_to_cpu -\n" + | ||
| 35 | + "1: 0000 000000000000 000000000000 &&& 0000000000000000000000000000 => send_to_cpu -\n" + | ||
| 36 | + "2: 0000 000000000000 000000000000 &&& 0000000000000000000000000000 => send_to_cpu -\n" + | ||
| 37 | + "3: 0000 000000000000 000000000000 &&& 0000000000000000000000000000 => send_to_cpu -"; | ||
| 38 | + | ||
| 39 | + Bmv2TableDumpParser parser = new Bmv2TableDumpParser(); | ||
| 40 | + | ||
| 41 | + List<Long> result = parser.getEntryIds(text); | ||
| 42 | + | ||
| 43 | + assertThat("invalid parsed values", result.get(0), is(equalTo(0L))); | ||
| 44 | + assertThat("invalid parsed values", result.get(1), is(equalTo(1L))); | ||
| 45 | + assertThat("invalid parsed values", result.get(2), is(equalTo(2L))); | ||
| 46 | + assertThat("invalid parsed values", result.get(3), is(equalTo(3L))); | ||
| 47 | + } | ||
| 48 | +} |
-
Please register or login to post a comment