patchpanel: Query iptables counters in CountersService
This patch adds the code for querying iptables and parsing its output to
get traffic counters. Also adds some corresponding unit tests.
BUG=b:160113164
TEST=cros_workon_make --board=$BOARD --test patchpanel
Change-Id: Ifd73c077c8796dc8f84dfe1301bf57140d30f58a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2291854
Tested-by: Jie Jiang <jiejiang@chromium.org>
Commit-Queue: Jie Jiang <jiejiang@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/counters_service.h b/patchpanel/counters_service.h
index 2876c2e..b2e8cde 100644
--- a/patchpanel/counters_service.h
+++ b/patchpanel/counters_service.h
@@ -5,10 +5,14 @@
#ifndef PATCHPANEL_COUNTERS_SERVICE_H_
#define PATCHPANEL_COUNTERS_SERVICE_H_
+#include <map>
#include <set>
#include <string>
+#include <utility>
#include <vector>
+#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
+
#include "patchpanel/minijailed_process_runner.h"
#include "patchpanel/shill_client.h"
@@ -43,17 +47,39 @@
// The above rules and chains will never be removed once created, so we will
// check if one rule exists before creating it.
//
-// TODO(jiejiang): Query will be implemented in future patches.
-//
// Query: Two commands (iptables and ip6tables) will be executed in the mangle
// table to get all the chains and rules. And then we perform a text parsing on
// the output to get the counters. Counters for the same entry will be merged
// before return.
class CountersService {
public:
+ using SourceDevice = std::pair<TrafficCounter::Source, std::string>;
+ struct Counter {
+ Counter() = default;
+ Counter(uint64_t rx_bytes,
+ uint64_t rx_packets,
+ uint64_t tx_bytes,
+ uint64_t tx_packets);
+
+ uint64_t rx_bytes = 0;
+ uint64_t rx_packets = 0;
+ uint64_t tx_bytes = 0;
+ uint64_t tx_packets = 0;
+ };
+
CountersService(ShillClient* shill_client, MinijailedProcessRunner* runner);
~CountersService() = default;
+ // Collects and returns counters from all the existing iptables rules.
+ // |devices| is the set of interfaces for which counters should be returned,
+ // any unknown interfaces will be ignored. If |devices| is empty, counters for
+ // all known interfaces will be returned. An empty map will be returned on
+ // any failure. Note that currently all traffic to/from an interface will be
+ // counted by (UNKNOWN, ifname), i.e., no other sources except for UNKNOWN are
+ // used.
+ std::map<SourceDevice, Counter> GetCounters(
+ const std::set<std::string>& devices);
+
private:
// TODO(b/161060333): Move the following two functions elsewhere.
// Creates a new chain using both iptables and ip6tables in the mangle table.