blob: b12785529388bd3e48e4006998d50d557265e38f [file] [log] [blame]
Carmelo Casconeb045ddc2017-09-01 01:26:35 +02001/*
2 * Copyright 2017-present Open Networking Foundation
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
17package org.onosproject.drivers.p4runtime;
18
19import com.google.common.collect.Maps;
20import com.google.common.collect.Sets;
21import org.onosproject.net.device.DefaultPortStatistics;
22import org.onosproject.net.device.PortStatistics;
23import org.onosproject.net.device.PortStatisticsDiscovery;
24import org.onosproject.net.pi.runtime.PiCounterCellData;
25import org.onosproject.net.pi.runtime.PiCounterCellId;
26import org.onosproject.net.pi.runtime.PiCounterId;
Carmelo Cascone7f75be42017-09-07 14:37:02 +020027import org.onosproject.net.pi.runtime.PiIndirectCounterCellId;
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020028
29import java.util.Collection;
30import java.util.Collections;
31import java.util.Map;
32import java.util.Set;
33import java.util.concurrent.ExecutionException;
34import java.util.stream.Collectors;
35
Carmelo Cascone7f75be42017-09-07 14:37:02 +020036import static org.onosproject.net.pi.runtime.PiCounterType.INDIRECT;
37
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020038/**
39 * Implementation of a PortStatisticsBehaviour that can be used for any P4 program based on default.p4 (i.e. those
40 * under onos/tools/test/p4src).
41 */
42public class DefaultP4PortStatisticsDiscovery extends AbstractP4RuntimeHandlerBehaviour
43 implements PortStatisticsDiscovery {
44
Carmelo Cascone7f75be42017-09-07 14:37:02 +020045 private static final PiCounterId INGRESS_COUNTER_ID = PiCounterId.of("ingress_port_counter", INDIRECT);
46 private static final PiCounterId EGRESS_COUNTER_ID = PiCounterId.of("egress_port_counter", INDIRECT);
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020047
48 @Override
49 public Collection<PortStatistics> discoverPortStatistics() {
50
51 if (!super.setupBehaviour()) {
52 return Collections.emptyList();
53 }
54
55 Map<Long, DefaultPortStatistics.Builder> portStatBuilders = Maps.newHashMap();
56
57 deviceService.getPorts(deviceId)
58 .forEach(p -> portStatBuilders.put(p.number().toLong(),
59 DefaultPortStatistics.builder()
Carmelo Cascone7f75be42017-09-07 14:37:02 +020060 .setPort(p.number())
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020061 .setDeviceId(deviceId)));
62
63 Set<PiCounterCellId> counterCellIds = Sets.newHashSet();
64 portStatBuilders.keySet().forEach(p -> {
65 // Counter cell/index = port number.
Carmelo Cascone7f75be42017-09-07 14:37:02 +020066 counterCellIds.add(PiIndirectCounterCellId.of(INGRESS_COUNTER_ID, p));
67 counterCellIds.add(PiIndirectCounterCellId.of(EGRESS_COUNTER_ID, p));
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020068 });
69
70 Collection<PiCounterCellData> counterEntryResponse;
71 try {
72 counterEntryResponse = client.readCounterCells(counterCellIds, pipeconf).get();
73 } catch (InterruptedException | ExecutionException e) {
74 log.warn("Exception while reading port counters from {}: {}", deviceId, e.toString());
75 log.debug("", e);
76 return Collections.emptyList();
77 }
78
Carmelo Cascone7f75be42017-09-07 14:37:02 +020079 counterEntryResponse.forEach(counterData -> {
80 if (counterData.cellId().type() != INDIRECT) {
81 log.warn("Invalid counter data type {}, skipping", counterData.cellId().type());
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020082 return;
83 }
Carmelo Cascone7f75be42017-09-07 14:37:02 +020084 PiIndirectCounterCellId indCellId = (PiIndirectCounterCellId) counterData.cellId();
85 if (!portStatBuilders.containsKey(indCellId.index())) {
86 log.warn("Unrecognized counter index {}, skipping", counterData);
87 return;
88 }
89 DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(indCellId.index());
90 if (counterData.cellId().counterId().equals(INGRESS_COUNTER_ID)) {
91 statsBuilder.setPacketsReceived(counterData.packets());
92 statsBuilder.setBytesReceived(counterData.bytes());
93 } else if (counterData.cellId().counterId().equals(EGRESS_COUNTER_ID)) {
94 statsBuilder.setPacketsSent(counterData.packets());
95 statsBuilder.setBytesSent(counterData.bytes());
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020096 } else {
Carmelo Cascone7f75be42017-09-07 14:37:02 +020097 log.warn("Unrecognized counter ID {}, skipping", counterData);
Carmelo Casconeb045ddc2017-09-01 01:26:35 +020098 }
99 });
100
101 return portStatBuilders
102 .values()
103 .stream()
104 .map(DefaultPortStatistics.Builder::build)
105 .collect(Collectors.toList());
106 }
107}