patchpanel: add traffic accounting chains for VPNs
This patch adds traffic accounting chains and rules for traffic routed
through a VPN connection. All traffic routed to a VPN is counted with
the same chain, regardless of the type of VPN client.
BUG=b:160112868
TEST=Unit tests. Checked GetTrafficCounters still work with:
$ dbus-send --system --dest=org.chromium.PatchPanel --print-reply \
/org/chromium/PatchPanel org.chromium.PatchPanel.GetTrafficCounters
Change-Id: I3f0e7feabea5a18f164b1fc78ef9628da4b353eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2562983
Commit-Queue: Hugo Benichi <hugobenichi@google.com>
Tested-by: Hugo Benichi <hugobenichi@google.com>
Reviewed-by: Taoyu Li <taoyl@chromium.org>
diff --git a/patchpanel/counters_service.h b/patchpanel/counters_service.h
index fb284ab..3e3460d 100644
--- a/patchpanel/counters_service.h
+++ b/patchpanel/counters_service.h
@@ -16,7 +16,6 @@
#include "patchpanel/datapath.h"
#include "patchpanel/minijailed_process_runner.h"
#include "patchpanel/routing_service.h"
-#include "patchpanel/shill_client.h"
namespace patchpanel {
@@ -69,11 +68,21 @@
uint64_t tx_packets = 0;
};
- CountersService(ShillClient* shill_client,
- Datapath* datapath,
- MinijailedProcessRunner* runner);
+ CountersService(Datapath* datapath, MinijailedProcessRunner* runner);
~CountersService() = default;
+ // Installs the initial iptables setup for vpn accounting and for the given
+ // set of devices.
+ void Init(const std::set<std::string>& devices);
+ // Adds accounting rules and jump rules for a new physical device if this is
+ // the first time this device is seen.
+ void OnPhysicalDeviceAdded(const std::string& ifname);
+ // Removes jump rules for a physical device.
+ void OnPhysicalDeviceRemoved(const std::string& ifname);
+ // Adds accounting rules and jump rules for a new VPN device.
+ void OnVpnDeviceAdded(const std::string& ifname);
+ // Removes jump rules for a VPN device.
+ void OnVpnDeviceRemoved(const std::string& ifname);
// 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
@@ -85,20 +94,21 @@
const std::set<std::string>& devices);
private:
+ // Creates an iptables chain in the mangle table. Returns true if the chain
+ // was created, or false if the chain already existed.
bool MakeAccountingChain(const std::string& chain_name);
bool AddAccountingRule(const std::string& chain_name, TrafficSource source);
+ // Installs the required accounting chains and rules for the target
+ // |chain_tag|. Returns false if these chains and rules already existed.
+ bool SetupAccountingRules(const std::string& chain_tag);
+ // Installs jump rules in POSTROUTING to count traffic ingressing and
+ // egressing |ifname| with the accounting target |chain_tag|.
+ void SetupJumpRules(const std::string& op,
+ const std::string& ifname,
+ const std::string& chain_tag);
- // Installs the required chains and rules for the given shill device.
- void SetupChainsAndRules(const std::string& ifname);
-
- void OnDeviceChanged(const std::set<std::string>& added,
- const std::set<std::string>& removed);
-
- ShillClient* shill_client_;
Datapath* datapath_;
MinijailedProcessRunner* runner_;
-
- base::WeakPtrFactory<CountersService> weak_factory_{this};
};
TrafficCounter::Source TrafficSourceToProto(TrafficSource source);