Use xt_bpf module to record the iface stats
To make interface packet accounting more accurately and persistent, the
xt_bpf module is implemented to record the total packets and bytes
tx/rx through each interface. The netd will load the bpf program and
set up iptable rules for the xt_bpf module at boot time and the
framework service will use them to get per interface networks stats on
supported devices. Add logcat support to bpfloader program.
Test: iface stats show up in maps. Iptable rules show up after boot.
Bug: 72111305
Change-Id: Ib33d2b165b64e130999931302dd67891c35a12e9
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index 4a5fad8..e79a595 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -52,9 +52,11 @@
#include <netdutils/Syscalls.h>
#include "BandwidthController.h"
+#include "Controllers.h"
#include "FirewallController.h" /* For makeCriticalCommands */
#include "Fwmark.h"
#include "NetdConstants.h"
+#include "bpf/BpfUtils.h"
/* Alphabetical */
#define ALERT_IPT_TEMPLATE "%s %s -m quota2 ! --quota %" PRId64" --name %s\n"
@@ -69,6 +71,8 @@
using android::base::Join;
using android::base::StringAppendF;
using android::base::StringPrintf;
+using android::bpf::XT_BPF_EGRESS_PROG_PATH;
+using android::bpf::XT_BPF_INGRESS_PROG_PATH;
using android::netdutils::StatusOr;
using android::netdutils::UniqueFile;
@@ -201,46 +205,59 @@
*
* See go/ipsec-data-accounting for more information.
*/
-static const std::vector<std::string> IPT_BASIC_ACCOUNTING_COMMANDS = {
- "*filter",
- // Prevents IPSec double counting (ESP and UDP-encap-ESP respectively)
- "-A bw_INPUT -p esp -j RETURN",
- StringPrintf("-A bw_INPUT -m mark --mark 0x%x/0x%x -j RETURN",
- uidBillingMask, uidBillingMask),
- "-A bw_INPUT -m owner --socket-exists", /* This is a tracking rule. */
- StringPrintf("-A bw_INPUT -j MARK --or-mark 0x%x", uidBillingMask),
- // Prevents IPSec double counting (Tunnel mode and Transport mode,
- // respectively)
- "-A bw_OUTPUT -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
- "-A bw_OUTPUT -m policy --pol ipsec --dir out -j RETURN",
- "-A bw_OUTPUT -m owner --socket-exists", /* This is a tracking rule. */
+const std::vector<std::string> getBasicAccountingCommands() {
+ bool useBpf = android::net::gCtls->trafficCtrl.checkBpfStatsEnable();
+ //TODO: remove this when xt_bpf kernel support is ready
+ useBpf = false;
- "-A bw_costly_shared --jump bw_penalty_box",
- "-A bw_penalty_box --jump bw_happy_box",
- "-A bw_happy_box --jump bw_data_saver",
- "-A bw_data_saver -j RETURN",
- HAPPY_BOX_WHITELIST_COMMAND,
- "COMMIT",
+ const std::vector<std::string> ipt_basic_accounting_commands = {
+ "*filter",
+ // Prevents IPSec double counting (ESP and UDP-encap-ESP respectively)
+ "-A bw_INPUT -p esp -j RETURN",
+ StringPrintf("-A bw_INPUT -m mark --mark 0x%x/0x%x -j RETURN",
+ uidBillingMask, uidBillingMask),
+ "-A bw_INPUT -m owner --socket-exists", /* This is a tracking rule. */
+ StringPrintf("-A bw_INPUT -j MARK --or-mark 0x%x", uidBillingMask),
- "*raw",
- // Prevents IPSec double counting (Tunnel mode and Transport mode,
- // respectively)
- "-A bw_raw_PREROUTING -i " IPSEC_IFACE_PREFIX "+ -j RETURN",
- "-A bw_raw_PREROUTING -m policy --pol ipsec --dir in -j RETURN",
- "-A bw_raw_PREROUTING -m owner --socket-exists", /* This is a tracking rule. */
- "COMMIT",
+ // Prevents IPSec double counting (Tunnel mode and Transport mode,
+ // respectively)
+ "-A bw_OUTPUT -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
+ "-A bw_OUTPUT -m policy --pol ipsec --dir out -j RETURN",
+ "-A bw_OUTPUT -m owner --socket-exists", /* This is a tracking rule. */
- "*mangle",
- // Prevents IPSec double counting (Tunnel mode and Transport mode,
- // respectively)
- "-A bw_mangle_POSTROUTING -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
- "-A bw_mangle_POSTROUTING -m policy --pol ipsec --dir out -j RETURN",
- "-A bw_mangle_POSTROUTING -m owner --socket-exists", /* This is a tracking rule. */
- StringPrintf("-A bw_mangle_POSTROUTING -j MARK --set-mark 0x0/0x%x",
- uidBillingMask), // Clear the mark before sending this packet
- COMMIT_AND_CLOSE
-};
+ "-A bw_costly_shared --jump bw_penalty_box",
+ "-A bw_penalty_box --jump bw_happy_box",
+ "-A bw_happy_box --jump bw_data_saver",
+ "-A bw_data_saver -j RETURN",
+ HAPPY_BOX_WHITELIST_COMMAND,
+ "COMMIT",
+
+ "*raw",
+ // Prevents IPSec double counting (Tunnel mode and Transport mode,
+ // respectively)
+ "-A bw_raw_PREROUTING -i " IPSEC_IFACE_PREFIX "+ -j RETURN",
+ "-A bw_raw_PREROUTING -m policy --pol ipsec --dir in -j RETURN",
+ "-A bw_raw_PREROUTING -m owner --socket-exists", /* This is a tracking rule. */
+ useBpf ? StringPrintf("-A bw_raw_PREROUTING -m bpf --object-pinned %s",
+ XT_BPF_INGRESS_PROG_PATH):"",
+ "COMMIT",
+
+ "*mangle",
+ // Prevents IPSec double counting (Tunnel mode and Transport mode,
+ // respectively)
+ "-A bw_mangle_POSTROUTING -o " IPSEC_IFACE_PREFIX "+ -j RETURN",
+ "-A bw_mangle_POSTROUTING -m policy --pol ipsec --dir out -j RETURN",
+ "-A bw_mangle_POSTROUTING -m owner --socket-exists", /* This is a tracking rule. */
+ StringPrintf("-A bw_mangle_POSTROUTING -j MARK --set-mark 0x0/0x%x",
+ uidBillingMask), // Clear the mark before sending this packet
+ useBpf ? StringPrintf("-A bw_mangle_POSTROUTING -m bpf --object-pinned %s",
+ XT_BPF_EGRESS_PROG_PATH):"",
+ COMMIT_AND_CLOSE
+ };
+ return ipt_basic_accounting_commands;
+}
+
std::vector<std::string> toStrVec(int num, char* strs[]) {
std::vector<std::string> tmp;
@@ -286,7 +303,8 @@
mSharedQuotaBytes = mSharedAlertBytes = 0;
flushCleanTables(false);
- std::string commands = Join(IPT_BASIC_ACCOUNTING_COMMANDS, '\n');
+
+ std::string commands = Join(getBasicAccountingCommands(), '\n');
return iptablesRestoreFunction(V4V6, commands, nullptr);
}