mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-11-05 02:31:21 +01:00
[ONOS-7596] Support reading table entries with counter data in P4Runtime
Change-Id: I85bacb1697a6c881dd69ba74a2162c73ec0b8aee
This commit is contained in:
parent
a25251cdf5
commit
7632e150e1
@ -26,7 +26,7 @@ import org.onosproject.net.device.PortStatisticsDiscovery;
|
|||||||
import org.onosproject.net.driver.AbstractHandlerBehaviour;
|
import org.onosproject.net.driver.AbstractHandlerBehaviour;
|
||||||
import org.onosproject.net.pi.model.PiCounterId;
|
import org.onosproject.net.pi.model.PiCounterId;
|
||||||
import org.onosproject.net.pi.model.PiPipeconf;
|
import org.onosproject.net.pi.model.PiPipeconf;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.service.PiPipeconfService;
|
import org.onosproject.net.pi.service.PiPipeconfService;
|
||||||
import org.onosproject.p4runtime.api.P4RuntimeClient;
|
import org.onosproject.p4runtime.api.P4RuntimeClient;
|
||||||
@ -95,7 +95,7 @@ public final class PortStatisticsDiscoveryImpl extends AbstractHandlerBehaviour
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Query the device.
|
// Query the device.
|
||||||
Collection<PiCounterCellData> counterEntryResponse;
|
Collection<PiCounterCell> counterEntryResponse;
|
||||||
try {
|
try {
|
||||||
counterEntryResponse = client.readCounterCells(counterCellIds, pipeconf).get();
|
counterEntryResponse = client.readCounterCells(counterCellIds, pipeconf).get();
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
@ -105,24 +105,24 @@ public final class PortStatisticsDiscoveryImpl extends AbstractHandlerBehaviour
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process response.
|
// Process response.
|
||||||
counterEntryResponse.forEach(counterData -> {
|
counterEntryResponse.forEach(counterCell -> {
|
||||||
if (counterData.cellId().counterType() != INDIRECT) {
|
if (counterCell.cellId().counterType() != INDIRECT) {
|
||||||
log.warn("Invalid counter data type {}, skipping", counterData.cellId().counterType());
|
log.warn("Invalid counter data type {}, skipping", counterCell.cellId().counterType());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!portStatBuilders.containsKey(counterData.cellId().index())) {
|
if (!portStatBuilders.containsKey(counterCell.cellId().index())) {
|
||||||
log.warn("Unrecognized counter index {}, skipping", counterData);
|
log.warn("Unrecognized counter index {}, skipping", counterCell);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(counterData.cellId().index());
|
DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(counterCell.cellId().index());
|
||||||
if (counterData.cellId().counterId().equals(INGRESS_COUNTER_ID)) {
|
if (counterCell.cellId().counterId().equals(INGRESS_COUNTER_ID)) {
|
||||||
statsBuilder.setPacketsReceived(counterData.packets());
|
statsBuilder.setPacketsReceived(counterCell.data().packets());
|
||||||
statsBuilder.setBytesReceived(counterData.bytes());
|
statsBuilder.setBytesReceived(counterCell.data().bytes());
|
||||||
} else if (counterData.cellId().counterId().equals(EGRESS_COUNTER_ID)) {
|
} else if (counterCell.cellId().counterId().equals(EGRESS_COUNTER_ID)) {
|
||||||
statsBuilder.setPacketsSent(counterData.packets());
|
statsBuilder.setPacketsSent(counterCell.data().packets());
|
||||||
statsBuilder.setBytesSent(counterData.bytes());
|
statsBuilder.setBytesSent(counterCell.data().bytes());
|
||||||
} else {
|
} else {
|
||||||
log.warn("Unrecognized counter ID {}, skipping", counterData);
|
log.warn("Unrecognized counter ID {}, skipping", counterCell);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017-present Open Networking Foundation
|
||||||
|
*
|
||||||
|
* 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 org.onosproject.net.pi.runtime;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counter cell of a protocol-independent pipeline.
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public final class PiCounterCell {
|
||||||
|
|
||||||
|
private final PiCounterCellId cellId;
|
||||||
|
private final PiCounterCellData counterData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new counter cell for the given cell identifier and counter cell data.
|
||||||
|
*
|
||||||
|
* @param cellId counter cell identifier
|
||||||
|
* @param piCounterCellData counter cell data
|
||||||
|
*/
|
||||||
|
public PiCounterCell(PiCounterCellId cellId, PiCounterCellData piCounterCellData) {
|
||||||
|
this.cellId = cellId;
|
||||||
|
this.counterData = piCounterCellData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new counter cell for the given cell identifier, number of packets and bytes.
|
||||||
|
*
|
||||||
|
* @param cellId counter cell identifier
|
||||||
|
* @param packets number of packets
|
||||||
|
* @param bytes number of bytes
|
||||||
|
*/
|
||||||
|
public PiCounterCell(PiCounterCellId cellId, long packets, long bytes) {
|
||||||
|
this.cellId = cellId;
|
||||||
|
this.counterData = new PiCounterCellData(packets, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cell identifier.
|
||||||
|
*
|
||||||
|
* @return cell identifier
|
||||||
|
*/
|
||||||
|
public PiCounterCellId cellId() {
|
||||||
|
return cellId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data contained by this cell.
|
||||||
|
*
|
||||||
|
* @return counter cell data
|
||||||
|
*/
|
||||||
|
public PiCounterCellData data() {
|
||||||
|
return counterData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof PiCounterCell)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PiCounterCell that = (PiCounterCell) o;
|
||||||
|
return Objects.equal(cellId, that.cellId) &&
|
||||||
|
Objects.equal(counterData, that.counterData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(cellId, counterData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("cellId", cellId)
|
||||||
|
.add("counterData", counterData)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-present Open Networking Foundation
|
* Copyright 2018-present Open Networking Foundation
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -23,37 +23,26 @@ import com.google.common.base.Objects;
|
|||||||
/**
|
/**
|
||||||
* Data of a counter cell of a protocol-independent pipeline.
|
* Data of a counter cell of a protocol-independent pipeline.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Beta
|
@Beta
|
||||||
public final class PiCounterCellData {
|
public final class PiCounterCellData {
|
||||||
|
|
||||||
private final PiCounterCellId cellId;
|
|
||||||
private final long packets;
|
private final long packets;
|
||||||
private final long bytes;
|
private final long bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new counter cell data for the given cell identifier, number of packets and bytes.
|
* Creates a new counter cell data for the given number of packets and bytes.
|
||||||
*
|
*
|
||||||
* @param cellId counter cell identifier
|
|
||||||
* @param packets number of packets
|
* @param packets number of packets
|
||||||
* @param bytes number of bytes
|
* @param bytes number of bytes
|
||||||
*/
|
*/
|
||||||
public PiCounterCellData(PiCounterCellId cellId, long packets, long bytes) {
|
public PiCounterCellData(long packets, long bytes) {
|
||||||
this.cellId = cellId;
|
|
||||||
this.packets = packets;
|
this.packets = packets;
|
||||||
this.bytes = bytes;
|
this.bytes = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cell identifier.
|
* Returns the packet count value contained by this counter data.
|
||||||
*
|
|
||||||
* @return cell identifier
|
|
||||||
*/
|
|
||||||
public PiCounterCellId cellId() {
|
|
||||||
return cellId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the packet count value contained by this cell.
|
|
||||||
*
|
*
|
||||||
* @return number of packets
|
* @return number of packets
|
||||||
*/
|
*/
|
||||||
@ -62,7 +51,7 @@ public final class PiCounterCellData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the byte count value contained by this cell.
|
* Returns the byte count value contained by this counter data.
|
||||||
*
|
*
|
||||||
* @return number of bytes
|
* @return number of bytes
|
||||||
*/
|
*/
|
||||||
@ -80,19 +69,17 @@ public final class PiCounterCellData {
|
|||||||
}
|
}
|
||||||
PiCounterCellData that = (PiCounterCellData) o;
|
PiCounterCellData that = (PiCounterCellData) o;
|
||||||
return packets == that.packets &&
|
return packets == that.packets &&
|
||||||
bytes == that.bytes &&
|
bytes == that.bytes;
|
||||||
Objects.equal(cellId, that.cellId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(cellId, packets, bytes);
|
return Objects.hashCode(packets, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
.add("cellId", cellId)
|
|
||||||
.add("packets", packets)
|
.add("packets", packets)
|
||||||
.add("bytes", bytes)
|
.add("bytes", bytes)
|
||||||
.toString();
|
.toString();
|
||||||
|
|||||||
@ -42,10 +42,11 @@ public final class PiTableEntry implements PiEntity {
|
|||||||
private final long cookie;
|
private final long cookie;
|
||||||
private final int priority;
|
private final int priority;
|
||||||
private final double timeout;
|
private final double timeout;
|
||||||
|
private final PiCounterCellData counterData;
|
||||||
|
|
||||||
private PiTableEntry(PiTableId tableId, PiMatchKey matchKey,
|
private PiTableEntry(PiTableId tableId, PiMatchKey matchKey,
|
||||||
PiTableAction tableAction, boolean isDefaultAction,
|
PiTableAction tableAction, boolean isDefaultAction,
|
||||||
long cookie, int priority, double timeout) {
|
long cookie, int priority, double timeout, PiCounterCellData data) {
|
||||||
this.tableId = tableId;
|
this.tableId = tableId;
|
||||||
this.matchKey = matchKey;
|
this.matchKey = matchKey;
|
||||||
this.tableAction = tableAction;
|
this.tableAction = tableAction;
|
||||||
@ -53,6 +54,7 @@ public final class PiTableEntry implements PiEntity {
|
|||||||
this.cookie = cookie;
|
this.cookie = cookie;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
|
this.counterData = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,6 +127,18 @@ public final class PiTableEntry implements PiEntity {
|
|||||||
return timeout == NO_TIMEOUT ? Optional.empty() : Optional.of(timeout);
|
return timeout == NO_TIMEOUT ? Optional.empty() : Optional.of(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data of the counter cell associated with this table entry.
|
||||||
|
* This method is meaningful only if the table entry was read from the
|
||||||
|
* infrastructure device and the table has direct counters, otherwise
|
||||||
|
* returns null.
|
||||||
|
*
|
||||||
|
* @return counter cell data
|
||||||
|
*/
|
||||||
|
public PiCounterCellData counter() {
|
||||||
|
return counterData;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
@ -197,6 +211,7 @@ public final class PiTableEntry implements PiEntity {
|
|||||||
private long cookie = 0;
|
private long cookie = 0;
|
||||||
private int priority = NO_PRIORITY;
|
private int priority = NO_PRIORITY;
|
||||||
private double timeout = NO_TIMEOUT;
|
private double timeout = NO_TIMEOUT;
|
||||||
|
private PiCounterCellData counterData;
|
||||||
|
|
||||||
private Builder() {
|
private Builder() {
|
||||||
// Hides constructor.
|
// Hides constructor.
|
||||||
@ -271,6 +286,17 @@ public final class PiTableEntry implements PiEntity {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the counter cell data of this table entry.
|
||||||
|
*
|
||||||
|
* @param data counter cell data
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public Builder withCounterCellData(PiCounterCellData data) {
|
||||||
|
this.counterData = checkNotNull(data, "Counter cell data cannot be null");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the table entry.
|
* Builds the table entry.
|
||||||
*
|
*
|
||||||
@ -281,7 +307,7 @@ public final class PiTableEntry implements PiEntity {
|
|||||||
checkNotNull(matchKey);
|
checkNotNull(matchKey);
|
||||||
final boolean isDefaultAction = matchKey.equals(PiMatchKey.EMPTY);
|
final boolean isDefaultAction = matchKey.equals(PiMatchKey.EMPTY);
|
||||||
return new PiTableEntry(tableId, matchKey, tableAction,
|
return new PiTableEntry(tableId, matchKey, tableAction,
|
||||||
isDefaultAction, cookie, priority, timeout);
|
isDefaultAction, cookie, priority, timeout, counterData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-present Open Networking Foundation
|
* Copyright 2018-present Open Networking Foundation
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -18,48 +18,25 @@ package org.onosproject.net.pi.runtime;
|
|||||||
|
|
||||||
import com.google.common.testing.EqualsTester;
|
import com.google.common.testing.EqualsTester;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.onosproject.net.pi.model.PiActionId;
|
|
||||||
import org.onosproject.net.pi.model.PiTableId;
|
|
||||||
|
|
||||||
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
|
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
|
||||||
import static org.onosproject.net.pi.runtime.PiConstantsTest.DROP;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for PiCounterCellData class.
|
* Unit tests for PiCounterData class.
|
||||||
*/
|
*/
|
||||||
public class PiCounterCellDataTest {
|
public class PiCounterCellDataTest {
|
||||||
|
|
||||||
private static final PiTableEntry PI_TABLE_ENTRY_1 = PiTableEntry.builder()
|
|
||||||
.forTable(PiTableId.of("T10"))
|
|
||||||
.withCookie(0xac)
|
|
||||||
.withPriority(10)
|
|
||||||
.withAction(PiAction.builder().withId(PiActionId.of(DROP)).build())
|
|
||||||
.withTimeout(100)
|
|
||||||
.build();
|
|
||||||
private static final PiTableEntry PI_TABLE_ENTRY_2 = PiTableEntry.builder()
|
|
||||||
.forTable(PiTableId.of("T20"))
|
|
||||||
.withCookie(0xac)
|
|
||||||
.withPriority(10)
|
|
||||||
.withAction(PiAction.builder().withId(PiActionId.of(DROP)).build())
|
|
||||||
.withTimeout(1000)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final PiCounterCellId PI_COUNTER_CELL_ID_1 =
|
|
||||||
PiCounterCellId.ofDirect(PI_TABLE_ENTRY_1);
|
|
||||||
private static final PiCounterCellId PI_COUNTER_CELL_ID_2 =
|
|
||||||
PiCounterCellId.ofDirect(PI_TABLE_ENTRY_2);
|
|
||||||
|
|
||||||
private static final long PACKETS_1 = 10;
|
private static final long PACKETS_1 = 10;
|
||||||
private static final long PACKETS_2 = 20;
|
private static final long PACKETS_2 = 20;
|
||||||
private static final long BYTES_1 = 100;
|
private static final long BYTES_1 = 100;
|
||||||
private static final long BYTES_2 = 200;
|
private static final long BYTES_2 = 200;
|
||||||
|
|
||||||
private static final PiCounterCellData PI_COUNTER_CELL_DATA_1 =
|
private static final PiCounterCellData PI_COUNTER_DATA_1 =
|
||||||
new PiCounterCellData(PI_COUNTER_CELL_ID_1, PACKETS_1, BYTES_1);
|
new PiCounterCellData(PACKETS_1, BYTES_1);
|
||||||
private static final PiCounterCellData SAME_AS_PI_COUNTER_CELL_DATA_1 =
|
private static final PiCounterCellData SAME_AS_PI_COUNTER_DATA_1 =
|
||||||
new PiCounterCellData(PI_COUNTER_CELL_ID_1, PACKETS_1, BYTES_1);
|
new PiCounterCellData(PACKETS_1, BYTES_1);
|
||||||
private static final PiCounterCellData PI_COUNTER_CELL_DATA_2 =
|
private static final PiCounterCellData PI_COUNTER_DATA_2 =
|
||||||
new PiCounterCellData(PI_COUNTER_CELL_ID_2, PACKETS_2, BYTES_2);
|
new PiCounterCellData(PACKETS_2, BYTES_2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that the PiCounterCellData class is immutable.
|
* Checks that the PiCounterCellData class is immutable.
|
||||||
@ -75,8 +52,8 @@ public class PiCounterCellDataTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testEquals() {
|
public void testEquals() {
|
||||||
new EqualsTester()
|
new EqualsTester()
|
||||||
.addEqualityGroup(PI_COUNTER_CELL_DATA_1, SAME_AS_PI_COUNTER_CELL_DATA_1)
|
.addEqualityGroup(PI_COUNTER_DATA_1, SAME_AS_PI_COUNTER_DATA_1)
|
||||||
.addEqualityGroup(PI_COUNTER_CELL_DATA_2)
|
.addEqualityGroup(PI_COUNTER_DATA_2)
|
||||||
.testEquals();
|
.testEquals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017-present Open Networking Foundation
|
||||||
|
*
|
||||||
|
* 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 org.onosproject.net.pi.runtime;
|
||||||
|
|
||||||
|
import com.google.common.testing.EqualsTester;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.onosproject.net.pi.model.PiActionId;
|
||||||
|
import org.onosproject.net.pi.model.PiTableId;
|
||||||
|
|
||||||
|
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
|
||||||
|
import static org.onosproject.net.pi.runtime.PiConstantsTest.DROP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for PiCounterCell class.
|
||||||
|
*/
|
||||||
|
public class PiCounterCellTest {
|
||||||
|
|
||||||
|
private static final PiTableEntry PI_TABLE_ENTRY_1 = PiTableEntry.builder()
|
||||||
|
.forTable(PiTableId.of("T10"))
|
||||||
|
.withCookie(0xac)
|
||||||
|
.withPriority(10)
|
||||||
|
.withAction(PiAction.builder().withId(PiActionId.of(DROP)).build())
|
||||||
|
.withTimeout(100)
|
||||||
|
.build();
|
||||||
|
private static final PiTableEntry PI_TABLE_ENTRY_2 = PiTableEntry.builder()
|
||||||
|
.forTable(PiTableId.of("T20"))
|
||||||
|
.withCookie(0xac)
|
||||||
|
.withPriority(10)
|
||||||
|
.withAction(PiAction.builder().withId(PiActionId.of(DROP)).build())
|
||||||
|
.withTimeout(1000)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private static final PiCounterCellId PI_COUNTER_CELL_ID_1 =
|
||||||
|
PiCounterCellId.ofDirect(PI_TABLE_ENTRY_1);
|
||||||
|
private static final PiCounterCellId PI_COUNTER_CELL_ID_2 =
|
||||||
|
PiCounterCellId.ofDirect(PI_TABLE_ENTRY_2);
|
||||||
|
|
||||||
|
private static final long PACKETS_1 = 10;
|
||||||
|
private static final long PACKETS_2 = 20;
|
||||||
|
private static final long BYTES_1 = 100;
|
||||||
|
private static final long BYTES_2 = 200;
|
||||||
|
|
||||||
|
private static final PiCounterCell PI_COUNTER_CELL_1 =
|
||||||
|
new PiCounterCell(PI_COUNTER_CELL_ID_1, PACKETS_1, BYTES_1);
|
||||||
|
private static final PiCounterCell SAME_AS_PI_COUNTER_CELL_1 =
|
||||||
|
new PiCounterCell(PI_COUNTER_CELL_ID_1, PACKETS_1, BYTES_1);
|
||||||
|
private static final PiCounterCell PI_COUNTER_CELL_2 =
|
||||||
|
new PiCounterCell(PI_COUNTER_CELL_ID_2, PACKETS_2, BYTES_2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the PiCounterCell class is immutable.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testImmutability() {
|
||||||
|
assertThatClassIsImmutable(PiCounterCell.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the operation of equals(), hashCode() and toString() methods.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEquals() {
|
||||||
|
new EqualsTester()
|
||||||
|
.addEqualityGroup(PI_COUNTER_CELL_1, SAME_AS_PI_COUNTER_CELL_1)
|
||||||
|
.addEqualityGroup(PI_COUNTER_CELL_2)
|
||||||
|
.testEquals();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -231,6 +231,7 @@ import org.onosproject.net.pi.runtime.PiActionGroupMemberHandle;
|
|||||||
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
||||||
import org.onosproject.net.pi.runtime.PiActionParam;
|
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||||
import org.onosproject.net.pi.runtime.PiControlMetadata;
|
import org.onosproject.net.pi.runtime.PiControlMetadata;
|
||||||
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.runtime.PiEntity;
|
import org.onosproject.net.pi.runtime.PiEntity;
|
||||||
@ -692,6 +693,7 @@ public final class KryoNamespaces {
|
|||||||
PiActionGroupMemberId.class,
|
PiActionGroupMemberId.class,
|
||||||
PiActionParam.class,
|
PiActionParam.class,
|
||||||
PiControlMetadata.class,
|
PiControlMetadata.class,
|
||||||
|
PiCounterCell.class,
|
||||||
PiCounterCellData.class,
|
PiCounterCellData.class,
|
||||||
PiCounterCellId.class,
|
PiCounterCellId.class,
|
||||||
PiEntity.class,
|
PiEntity.class,
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import org.onosproject.net.pi.model.PiPipelineInterpreter;
|
|||||||
import org.onosproject.net.pi.model.PiPipelineModel;
|
import org.onosproject.net.pi.model.PiPipelineModel;
|
||||||
import org.onosproject.net.pi.model.PiTableId;
|
import org.onosproject.net.pi.model.PiTableId;
|
||||||
import org.onosproject.net.pi.model.PiTableModel;
|
import org.onosproject.net.pi.model.PiTableModel;
|
||||||
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.runtime.PiTableEntry;
|
import org.onosproject.net.pi.runtime.PiTableEntry;
|
||||||
@ -89,11 +90,11 @@ public class P4RuntimeFlowRuleProgrammable
|
|||||||
private static final String SUPPORT_TABLE_COUNTERS = "supportTableCounters";
|
private static final String SUPPORT_TABLE_COUNTERS = "supportTableCounters";
|
||||||
private static final boolean DEFAULT_SUPPORT_TABLE_COUNTERS = true;
|
private static final boolean DEFAULT_SUPPORT_TABLE_COUNTERS = true;
|
||||||
|
|
||||||
// If true, we read all direct counters of a table with one request.
|
// If true, assumes that the device returns table entry message populated
|
||||||
// Otherwise, we send as many requests as the number of table entries.
|
// with direct counter values. If false, we issue a second P4Runtime request
|
||||||
private static final String READ_ALL_DIRECT_COUNTERS = "tableReadAllDirectCounters";
|
// to read the direct counter values.
|
||||||
// FIXME: set to true as soon as the feature is implemented in P4Runtime.
|
private static final String READ_COUNTERS_WITH_TABLE_ENTRIES = "tableReadCountersWithTableEntries";
|
||||||
private static final boolean DEFAULT_READ_ALL_DIRECT_COUNTERS = false;
|
private static final boolean DEFAULT_READ_COUNTERS_WITH_TABLE_ENTRIES = true;
|
||||||
|
|
||||||
// For default entries, P4Runtime mandates that only MODIFY messages are
|
// For default entries, P4Runtime mandates that only MODIFY messages are
|
||||||
// allowed. If true, treats default entries as normal table entries,
|
// allowed. If true, treats default entries as normal table entries,
|
||||||
@ -153,7 +154,6 @@ public class P4RuntimeFlowRuleProgrammable
|
|||||||
|
|
||||||
// Synchronize mirror with the device state.
|
// Synchronize mirror with the device state.
|
||||||
syncMirror(deviceEntries);
|
syncMirror(deviceEntries);
|
||||||
// TODO: ONOS-7596 read counters with table entries
|
|
||||||
final Map<PiTableEntry, PiCounterCellData> counterCellMap =
|
final Map<PiTableEntry, PiCounterCellData> counterCellMap =
|
||||||
readEntryCounters(deviceEntries);
|
readEntryCounters(deviceEntries);
|
||||||
// Forge flow entries with counter values.
|
// Forge flow entries with counter values.
|
||||||
@ -461,25 +461,22 @@ public class P4RuntimeFlowRuleProgrammable
|
|||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<PiCounterCellData> cellDatas;
|
if (driverBoolProperty(READ_COUNTERS_WITH_TABLE_ENTRIES,
|
||||||
|
DEFAULT_READ_COUNTERS_WITH_TABLE_ENTRIES)) {
|
||||||
if (driverBoolProperty(READ_ALL_DIRECT_COUNTERS,
|
return tableEntries.stream().collect(Collectors.toMap(c -> c, PiTableEntry::counter));
|
||||||
DEFAULT_READ_ALL_DIRECT_COUNTERS)) {
|
|
||||||
// FIXME: read counters when dumping table entries ONOS-7596
|
|
||||||
cellDatas = Collections.emptyList();
|
|
||||||
} else {
|
} else {
|
||||||
|
Collection<PiCounterCell> cells;
|
||||||
Set<PiCounterCellId> cellIds = tableEntries.stream()
|
Set<PiCounterCellId> cellIds = tableEntries.stream()
|
||||||
// Ignore counter for default entry.
|
// Ignore counter for default entry.
|
||||||
.filter(e -> !e.isDefaultAction())
|
.filter(e -> !e.isDefaultAction())
|
||||||
.filter(e -> tableHasCounter(e.table()))
|
.filter(e -> tableHasCounter(e.table()))
|
||||||
.map(PiCounterCellId::ofDirect)
|
.map(PiCounterCellId::ofDirect)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
cellDatas = getFutureWithDeadline(client.readCounterCells(cellIds, pipeconf),
|
cells = getFutureWithDeadline(client.readCounterCells(cellIds, pipeconf),
|
||||||
"reading table counters", Collections.emptyList());
|
"reading table counters", Collections.emptyList());
|
||||||
|
return cells.stream()
|
||||||
|
.collect(Collectors.toMap(c -> c.cellId().tableEntry(), PiCounterCell::data));
|
||||||
}
|
}
|
||||||
return cellDatas.stream()
|
|
||||||
.collect(Collectors.toMap(c -> c.cellId().tableEntry(), c -> c));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean tableHasCounter(PiTableId tableId) {
|
private boolean tableHasCounter(PiTableId tableId) {
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import org.onosproject.net.device.PortStatisticsDiscovery;
|
|||||||
import org.onosproject.net.driver.AbstractHandlerBehaviour;
|
import org.onosproject.net.driver.AbstractHandlerBehaviour;
|
||||||
import org.onosproject.net.pi.model.PiCounterId;
|
import org.onosproject.net.pi.model.PiCounterId;
|
||||||
import org.onosproject.net.pi.model.PiPipeconf;
|
import org.onosproject.net.pi.model.PiPipeconf;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.service.PiPipeconfService;
|
import org.onosproject.net.pi.service.PiPipeconfService;
|
||||||
import org.onosproject.p4runtime.api.P4RuntimeClient;
|
import org.onosproject.p4runtime.api.P4RuntimeClient;
|
||||||
@ -112,7 +112,7 @@ public class PortStatisticsDiscoveryImpl extends AbstractHandlerBehaviour implem
|
|||||||
counterCellIds.add(PiCounterCellId.ofIndirect(egressCounterId(), p));
|
counterCellIds.add(PiCounterCellId.ofIndirect(egressCounterId(), p));
|
||||||
});
|
});
|
||||||
|
|
||||||
Collection<PiCounterCellData> counterEntryResponse;
|
Collection<PiCounterCell> counterEntryResponse;
|
||||||
try {
|
try {
|
||||||
counterEntryResponse = client.readCounterCells(counterCellIds, pipeconf).get();
|
counterEntryResponse = client.readCounterCells(counterCellIds, pipeconf).get();
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
@ -121,25 +121,25 @@ public class PortStatisticsDiscoveryImpl extends AbstractHandlerBehaviour implem
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
counterEntryResponse.forEach(counterData -> {
|
counterEntryResponse.forEach(counterCell -> {
|
||||||
if (counterData.cellId().counterType() != INDIRECT) {
|
if (counterCell.cellId().counterType() != INDIRECT) {
|
||||||
log.warn("Invalid counter data type {}, skipping", counterData.cellId().counterType());
|
log.warn("Invalid counter data type {}, skipping", counterCell.cellId().counterType());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PiCounterCellId indCellId = counterData.cellId();
|
PiCounterCellId indCellId = counterCell.cellId();
|
||||||
if (!portStatBuilders.containsKey(indCellId.index())) {
|
if (!portStatBuilders.containsKey(indCellId.index())) {
|
||||||
log.warn("Unrecognized counter index {}, skipping", counterData);
|
log.warn("Unrecognized counter index {}, skipping", counterCell);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(indCellId.index());
|
DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(indCellId.index());
|
||||||
if (counterData.cellId().counterId().equals(ingressCounterId())) {
|
if (counterCell.cellId().counterId().equals(ingressCounterId())) {
|
||||||
statsBuilder.setPacketsReceived(counterData.packets());
|
statsBuilder.setPacketsReceived(counterCell.data().packets());
|
||||||
statsBuilder.setBytesReceived(counterData.bytes());
|
statsBuilder.setBytesReceived(counterCell.data().bytes());
|
||||||
} else if (counterData.cellId().counterId().equals(egressCounterId())) {
|
} else if (counterCell.cellId().counterId().equals(egressCounterId())) {
|
||||||
statsBuilder.setPacketsSent(counterData.packets());
|
statsBuilder.setPacketsSent(counterCell.data().packets());
|
||||||
statsBuilder.setBytesSent(counterData.bytes());
|
statsBuilder.setBytesSent(counterCell.data().bytes());
|
||||||
} else {
|
} else {
|
||||||
log.warn("Unrecognized counter ID {}, skipping", counterData);
|
log.warn("Unrecognized counter ID {}, skipping", counterCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import org.onosproject.net.pi.model.PiTableId;
|
|||||||
import org.onosproject.net.pi.runtime.PiActionGroup;
|
import org.onosproject.net.pi.runtime.PiActionGroup;
|
||||||
import org.onosproject.net.pi.runtime.PiActionGroupMember;
|
import org.onosproject.net.pi.runtime.PiActionGroupMember;
|
||||||
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.runtime.PiMeterCellConfig;
|
import org.onosproject.net.pi.runtime.PiMeterCellConfig;
|
||||||
import org.onosproject.net.pi.runtime.PiMeterCellId;
|
import org.onosproject.net.pi.runtime.PiMeterCellId;
|
||||||
@ -178,7 +178,7 @@ public interface P4RuntimeClient {
|
|||||||
* @param pipeconf pipeconf
|
* @param pipeconf pipeconf
|
||||||
* @return list of counter data
|
* @return list of counter data
|
||||||
*/
|
*/
|
||||||
CompletableFuture<List<PiCounterCellData>> readAllCounterCells(
|
CompletableFuture<List<PiCounterCell>> readAllCounterCells(
|
||||||
Set<PiCounterId> counterIds, PiPipeconf pipeconf);
|
Set<PiCounterId> counterIds, PiPipeconf pipeconf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,7 +189,7 @@ public interface P4RuntimeClient {
|
|||||||
* @param pipeconf pipeconf
|
* @param pipeconf pipeconf
|
||||||
* @return list of counter data
|
* @return list of counter data
|
||||||
*/
|
*/
|
||||||
CompletableFuture<List<PiCounterCellData>> readCounterCells(
|
CompletableFuture<List<PiCounterCell>> readCounterCells(
|
||||||
Set<PiCounterCellId> cellIds, PiPipeconf pipeconf);
|
Set<PiCounterCellId> cellIds, PiPipeconf pipeconf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import org.onosproject.net.pi.model.PiCounterId;
|
|||||||
import org.onosproject.net.pi.model.PiCounterType;
|
import org.onosproject.net.pi.model.PiCounterType;
|
||||||
import org.onosproject.net.pi.model.PiPipeconf;
|
import org.onosproject.net.pi.model.PiPipeconf;
|
||||||
import org.onosproject.net.pi.model.PiTableId;
|
import org.onosproject.net.pi.model.PiTableId;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.runtime.PiTableEntry;
|
import org.onosproject.net.pi.runtime.PiTableEntry;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -135,7 +135,7 @@ final class CounterEntryCodec {
|
|||||||
* @param pipeconf pipeconf
|
* @param pipeconf pipeconf
|
||||||
* @return collection of PI counter cell data
|
* @return collection of PI counter cell data
|
||||||
*/
|
*/
|
||||||
static List<PiCounterCellData> decodeCounterEntities(List<Entity> entities,
|
static List<PiCounterCell> decodeCounterEntities(List<Entity> entities,
|
||||||
PiPipeconf pipeconf) {
|
PiPipeconf pipeconf) {
|
||||||
|
|
||||||
final P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);
|
final P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);
|
||||||
@ -248,7 +248,7 @@ final class CounterEntryCodec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PiCounterCellData decodeCounterEntity(Entity entity,
|
private static PiCounterCell decodeCounterEntity(Entity entity,
|
||||||
PiPipeconf pipeconf,
|
PiPipeconf pipeconf,
|
||||||
P4InfoBrowser browser)
|
P4InfoBrowser browser)
|
||||||
throws EncodeException, P4InfoBrowser.NotFoundException {
|
throws EncodeException, P4InfoBrowser.NotFoundException {
|
||||||
@ -276,7 +276,7 @@ final class CounterEntryCodec {
|
|||||||
entity.getEntityCase().name()));
|
entity.getEntityCase().name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PiCounterCellData(piCellId,
|
return new PiCounterCell(piCellId,
|
||||||
counterData.getPacketCount(),
|
counterData.getPacketCount(),
|
||||||
counterData.getByteCount());
|
counterData.getByteCount());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ import org.onosproject.net.pi.model.PiTableId;
|
|||||||
import org.onosproject.net.pi.runtime.PiActionGroup;
|
import org.onosproject.net.pi.runtime.PiActionGroup;
|
||||||
import org.onosproject.net.pi.runtime.PiActionGroupMember;
|
import org.onosproject.net.pi.runtime.PiActionGroupMember;
|
||||||
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
import org.onosproject.net.pi.runtime.PiCounterCell;
|
||||||
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
import org.onosproject.net.pi.runtime.PiCounterCellId;
|
||||||
import org.onosproject.net.pi.runtime.PiMeterCellConfig;
|
import org.onosproject.net.pi.runtime.PiMeterCellConfig;
|
||||||
import org.onosproject.net.pi.runtime.PiMeterCellId;
|
import org.onosproject.net.pi.runtime.PiMeterCellId;
|
||||||
@ -281,14 +281,14 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<List<PiCounterCellData>> readCounterCells(Set<PiCounterCellId> cellIds,
|
public CompletableFuture<List<PiCounterCell>> readCounterCells(Set<PiCounterCellId> cellIds,
|
||||||
PiPipeconf pipeconf) {
|
PiPipeconf pipeconf) {
|
||||||
return supplyInContext(() -> doReadCounterCells(Lists.newArrayList(cellIds), pipeconf),
|
return supplyInContext(() -> doReadCounterCells(Lists.newArrayList(cellIds), pipeconf),
|
||||||
"readCounterCells-" + cellIds.hashCode());
|
"readCounterCells-" + cellIds.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<List<PiCounterCellData>> readAllCounterCells(Set<PiCounterId> counterIds,
|
public CompletableFuture<List<PiCounterCell>> readAllCounterCells(Set<PiCounterId> counterIds,
|
||||||
PiPipeconf pipeconf) {
|
PiPipeconf pipeconf) {
|
||||||
return supplyInContext(() -> doReadAllCounterCells(Lists.newArrayList(counterIds), pipeconf),
|
return supplyInContext(() -> doReadAllCounterCells(Lists.newArrayList(counterIds), pipeconf),
|
||||||
"readAllCounterCells-" + counterIds.hashCode());
|
"readAllCounterCells-" + counterIds.hashCode());
|
||||||
@ -559,6 +559,7 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
|
|||||||
TableEntry.newBuilder()
|
TableEntry.newBuilder()
|
||||||
.setTableId(tableId)
|
.setTableId(tableId)
|
||||||
.setIsDefaultAction(defaultEntries)
|
.setIsDefaultAction(defaultEntries)
|
||||||
|
.setCounterData(P4RuntimeOuterClass.CounterData.getDefaultInstance())
|
||||||
.build())
|
.build())
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
@ -651,21 +652,21 @@ final class P4RuntimeClientImpl implements P4RuntimeClient {
|
|||||||
isClientMaster.set(isMaster);
|
isClientMaster.set(isMaster);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PiCounterCellData> doReadAllCounterCells(
|
private List<PiCounterCell> doReadAllCounterCells(
|
||||||
List<PiCounterId> counterIds, PiPipeconf pipeconf) {
|
List<PiCounterId> counterIds, PiPipeconf pipeconf) {
|
||||||
return doReadCounterEntities(
|
return doReadCounterEntities(
|
||||||
CounterEntryCodec.readAllCellsEntities(counterIds, pipeconf),
|
CounterEntryCodec.readAllCellsEntities(counterIds, pipeconf),
|
||||||
pipeconf);
|
pipeconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PiCounterCellData> doReadCounterCells(
|
private List<PiCounterCell> doReadCounterCells(
|
||||||
List<PiCounterCellId> cellIds, PiPipeconf pipeconf) {
|
List<PiCounterCellId> cellIds, PiPipeconf pipeconf) {
|
||||||
return doReadCounterEntities(
|
return doReadCounterEntities(
|
||||||
CounterEntryCodec.encodePiCounterCellIds(cellIds, pipeconf),
|
CounterEntryCodec.encodePiCounterCellIds(cellIds, pipeconf),
|
||||||
pipeconf);
|
pipeconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PiCounterCellData> doReadCounterEntities(
|
private List<PiCounterCell> doReadCounterEntities(
|
||||||
List<Entity> counterEntities, PiPipeconf pipeconf) {
|
List<Entity> counterEntities, PiPipeconf pipeconf) {
|
||||||
|
|
||||||
if (counterEntities.size() == 0) {
|
if (counterEntities.size() == 0) {
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import org.onosproject.net.pi.runtime.PiAction;
|
|||||||
import org.onosproject.net.pi.runtime.PiActionGroupId;
|
import org.onosproject.net.pi.runtime.PiActionGroupId;
|
||||||
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
|
||||||
import org.onosproject.net.pi.runtime.PiActionParam;
|
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||||
|
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
||||||
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
|
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
|
||||||
import org.onosproject.net.pi.runtime.PiFieldMatch;
|
import org.onosproject.net.pi.runtime.PiFieldMatch;
|
||||||
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
|
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
|
||||||
@ -40,6 +41,7 @@ import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import p4.config.v1.P4InfoOuterClass;
|
import p4.config.v1.P4InfoOuterClass;
|
||||||
import p4.v1.P4RuntimeOuterClass.Action;
|
import p4.v1.P4RuntimeOuterClass.Action;
|
||||||
|
import p4.v1.P4RuntimeOuterClass.CounterData;
|
||||||
import p4.v1.P4RuntimeOuterClass.FieldMatch;
|
import p4.v1.P4RuntimeOuterClass.FieldMatch;
|
||||||
import p4.v1.P4RuntimeOuterClass.TableAction;
|
import p4.v1.P4RuntimeOuterClass.TableAction;
|
||||||
import p4.v1.P4RuntimeOuterClass.TableEntry;
|
import p4.v1.P4RuntimeOuterClass.TableEntry;
|
||||||
@ -249,6 +251,11 @@ final class TableEntryEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Counter.
|
||||||
|
if (piTableEntry.counter() != null) {
|
||||||
|
tableEntryMsgBuilder.setCounterData(encodeCounter(piTableEntry.counter()));
|
||||||
|
}
|
||||||
|
|
||||||
return tableEntryMsgBuilder.build();
|
return tableEntryMsgBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +288,9 @@ final class TableEntryEncoder {
|
|||||||
// Match key for field matches.
|
// Match key for field matches.
|
||||||
piTableEntryBuilder.withMatchKey(decodeFieldMatchMsgs(tableEntryMsg.getMatchList(), tableInfo, browser));
|
piTableEntryBuilder.withMatchKey(decodeFieldMatchMsgs(tableEntryMsg.getMatchList(), tableInfo, browser));
|
||||||
|
|
||||||
|
// Counter.
|
||||||
|
piTableEntryBuilder.withCounterCellData(decodeCounter(tableEntryMsg.getCounterData()));
|
||||||
|
|
||||||
return piTableEntryBuilder.build();
|
return piTableEntryBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,4 +515,13 @@ final class TableEntryEncoder {
|
|||||||
}
|
}
|
||||||
return PiAction.builder().withId(id).withParameters(params).build();
|
return PiAction.builder().withId(id).withParameters(params).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CounterData encodeCounter(PiCounterCellData piCounterCellData) {
|
||||||
|
return CounterData.newBuilder().setPacketCount(piCounterCellData.packets())
|
||||||
|
.setByteCount(piCounterCellData.bytes()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PiCounterCellData decodeCounter(CounterData counterData) {
|
||||||
|
return new PiCounterCellData(counterData.getPacketCount(), counterData.getByteCount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -32,11 +32,13 @@ import org.onosproject.net.pi.model.PiTableId;
|
|||||||
import org.onosproject.net.pi.runtime.PiAction;
|
import org.onosproject.net.pi.runtime.PiAction;
|
||||||
import org.onosproject.net.pi.runtime.PiActionGroupId;
|
import org.onosproject.net.pi.runtime.PiActionGroupId;
|
||||||
import org.onosproject.net.pi.runtime.PiActionParam;
|
import org.onosproject.net.pi.runtime.PiActionParam;
|
||||||
|
import org.onosproject.net.pi.runtime.PiCounterCellData;
|
||||||
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
|
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
|
||||||
import org.onosproject.net.pi.runtime.PiMatchKey;
|
import org.onosproject.net.pi.runtime.PiMatchKey;
|
||||||
import org.onosproject.net.pi.runtime.PiTableEntry;
|
import org.onosproject.net.pi.runtime.PiTableEntry;
|
||||||
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
|
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
|
||||||
import p4.v1.P4RuntimeOuterClass.Action;
|
import p4.v1.P4RuntimeOuterClass.Action;
|
||||||
|
import p4.v1.P4RuntimeOuterClass.CounterData;
|
||||||
import p4.v1.P4RuntimeOuterClass.TableEntry;
|
import p4.v1.P4RuntimeOuterClass.TableEntry;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -72,6 +74,9 @@ public class TableEntryEncoderTest {
|
|||||||
private static final String ETHER_TYPE = "etherType";
|
private static final String ETHER_TYPE = "etherType";
|
||||||
private static final String ECMP_GROUP_ID = "ecmp_group_id";
|
private static final String ECMP_GROUP_ID = "ecmp_group_id";
|
||||||
|
|
||||||
|
private static final long PACKETS = 10;
|
||||||
|
private static final long BYTES = 100;
|
||||||
|
|
||||||
private final Random rand = new Random();
|
private final Random rand = new Random();
|
||||||
private final URL p4InfoUrl = this.getClass().getResource("/test.p4info");
|
private final URL p4InfoUrl = this.getClass().getResource("/test.p4info");
|
||||||
|
|
||||||
@ -94,6 +99,7 @@ public class TableEntryEncoderTest {
|
|||||||
private final PiActionId outActionId = PiActionId.of(SET_EGRESS_PORT);
|
private final PiActionId outActionId = PiActionId.of(SET_EGRESS_PORT);
|
||||||
private final PiTableId tableId = PiTableId.of(TABLE_0);
|
private final PiTableId tableId = PiTableId.of(TABLE_0);
|
||||||
private final PiTableId ecmpTableId = PiTableId.of(TABLE_ECMP);
|
private final PiTableId ecmpTableId = PiTableId.of(TABLE_ECMP);
|
||||||
|
private final PiCounterCellData counterCellData = new PiCounterCellData(PACKETS, BYTES);
|
||||||
|
|
||||||
private final PiTableEntry piTableEntry = PiTableEntry
|
private final PiTableEntry piTableEntry = PiTableEntry
|
||||||
.builder()
|
.builder()
|
||||||
@ -111,6 +117,7 @@ public class TableEntryEncoderTest {
|
|||||||
.build())
|
.build())
|
||||||
.withPriority(1)
|
.withPriority(1)
|
||||||
.withCookie(2)
|
.withCookie(2)
|
||||||
|
.withCounterCellData(counterCellData)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private final PiTableEntry piTableEntryWithoutAction = PiTableEntry
|
private final PiTableEntry piTableEntryWithoutAction = PiTableEntry
|
||||||
@ -124,6 +131,7 @@ public class TableEntryEncoderTest {
|
|||||||
.build())
|
.build())
|
||||||
.withPriority(1)
|
.withPriority(1)
|
||||||
.withCookie(2)
|
.withCookie(2)
|
||||||
|
.withCounterCellData(counterCellData)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private final PiTableEntry piTableEntryWithGroupAction = PiTableEntry
|
private final PiTableEntry piTableEntryWithGroupAction = PiTableEntry
|
||||||
@ -135,6 +143,7 @@ public class TableEntryEncoderTest {
|
|||||||
.withAction(PiActionGroupId.of(1))
|
.withAction(PiActionGroupId.of(1))
|
||||||
.withPriority(1)
|
.withPriority(1)
|
||||||
.withCookie(2)
|
.withCookie(2)
|
||||||
|
.withCounterCellData(counterCellData)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public TableEntryEncoderTest() throws ImmutableByteSequence.ByteSequenceTrimException {
|
public TableEntryEncoderTest() throws ImmutableByteSequence.ByteSequenceTrimException {
|
||||||
@ -198,6 +207,12 @@ public class TableEntryEncoderTest {
|
|||||||
byte[] encodedActionParam = actionMsg.getParams(0).getValue().toByteArray();
|
byte[] encodedActionParam = actionMsg.getParams(0).getValue().toByteArray();
|
||||||
assertThat(encodedActionParam, is(portValue.asArray()));
|
assertThat(encodedActionParam, is(portValue.asArray()));
|
||||||
|
|
||||||
|
// Counter
|
||||||
|
CounterData counterData = tableEntryMsg.getCounterData();
|
||||||
|
PiCounterCellData encodedCounterData = new PiCounterCellData(counterData.getPacketCount(),
|
||||||
|
counterData.getByteCount());
|
||||||
|
assertThat(encodedCounterData, is(counterCellData));
|
||||||
|
|
||||||
// TODO: improve, assert other field match types (ternary, LPM)
|
// TODO: improve, assert other field match types (ternary, LPM)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,6 +272,12 @@ public class TableEntryEncoderTest {
|
|||||||
// no action
|
// no action
|
||||||
assertThat(tableEntryMsg.hasAction(), is(false));
|
assertThat(tableEntryMsg.hasAction(), is(false));
|
||||||
|
|
||||||
|
// Counter
|
||||||
|
CounterData counterData = tableEntryMsg.getCounterData();
|
||||||
|
PiCounterCellData encodedCounterData = new PiCounterCellData(counterData.getPacketCount(),
|
||||||
|
counterData.getByteCount());
|
||||||
|
assertThat(encodedCounterData, is(counterCellData));
|
||||||
|
|
||||||
// TODO: improve, assert other field match types (ternary, LPM)
|
// TODO: improve, assert other field match types (ternary, LPM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user