summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-09-01 16:53:35 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-09-02 13:00:05 +0900
commitc8683d7eb9bb95de2090431e8daaa45d92b45e38 (patch)
treef4e928ba8e5f5caa2f01b3910a9b69567b0ebd41
parentf2fed7647ede2ae39a76d50cf4abc9e57b49d40d (diff)
downloadnetd-marshmallow-mr1-release.tar.gz
Working IPv6 connectivity relies on the kernel being able to receive certain ICMPv6 packets (router advertisements, neighbour solicitations, neighbour advertisements) at all times. Allow these packets when in doze mode. This is not necessary for IPv4 because in IPv4 these functions use ARP, which is invisible to iptables. Bug: 23158230 Change-Id: I29ed77561db9688486cf58cd14ac3bce7fce4b40
-rw-r--r--server/FirewallController.cpp19
-rw-r--r--server/FirewallController.h3
2 files changed, 22 insertions, 0 deletions
diff --git a/server/FirewallController.cpp b/server/FirewallController.cpp
index bcf7524c..cf5a7de2 100644
--- a/server/FirewallController.cpp
+++ b/server/FirewallController.cpp
@@ -37,6 +37,18 @@ const char* FirewallController::LOCAL_FORWARD = "fw_FORWARD";
const char* FirewallController::LOCAL_DOZABLE = "fw_dozable";
const char* FirewallController::LOCAL_STANDBY = "fw_standby";
+// ICMPv6 types that are required for any form of IPv6 connectivity to work. Note that because the
+// fw_dozable chain is called from both INPUT and OUTPUT, this includes both packets that we need
+// to be able to send (e.g., RS, NS), and packets that we need to receive (e.g., RA, NA).
+const char* FirewallController::ICMPV6_TYPES[] = {
+ "packet-too-big",
+ "router-solicitation",
+ "router-advertisement",
+ "neighbour-solicitation",
+ "neighbour-advertisement",
+ "redirect",
+};
+
FirewallController::FirewallController(void) {
// If no rules are set, it's in BLACKLIST mode
mFirewallType = BLACKLIST;
@@ -264,11 +276,18 @@ int FirewallController::createChain(const char* childChain,
int res = 0;
res |= execIptables(V4V6, "-t", TABLE, "-N", childChain, NULL);
if (type == WHITELIST) {
+ // Allow ICMPv6 packets necessary to make IPv6 connectivity work. http://b/23158230 .
+ for (size_t i = 0; i < ARRAY_SIZE(ICMPV6_TYPES); i++) {
+ res |= execIptables(V6, "-A", childChain, "-p", "icmpv6", "--icmpv6-type",
+ ICMPV6_TYPES[i], "-j", "RETURN", NULL);
+ }
+
// create default white list for system uid range
char uidStr[16];
sprintf(uidStr, "0-%d", AID_APP - 1);
res |= execIptables(V4V6, "-A", childChain, "-m", "owner", "--uid-owner",
uidStr, "-j", "RETURN", NULL);
+
// create default rule to drop all traffic
res |= execIptables(V4V6, "-A", childChain, "-j", "DROP", NULL);
}
diff --git a/server/FirewallController.h b/server/FirewallController.h
index b32072e7..34a8b9ce 100644
--- a/server/FirewallController.h
+++ b/server/FirewallController.h
@@ -64,6 +64,9 @@ public:
static const char* LOCAL_DOZABLE;
static const char* LOCAL_STANDBY;
+
+ static const char* ICMPV6_TYPES[];
+
private:
FirewallType mFirewallType;
int attachChain(const char*, const char*);