aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-10 13:23:03 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-17 19:02:12 +0100
commit9df1a36a98aaf167993501c32ff7a10a38913f50 (patch)
tree3147f56e0462b9ac2b6c2b1bfeda4332f9c097c5 /executor
parent1f693e021993b9ce686952f9f28475684767c458 (diff)
sys/linux: add bridge netfilter support
Diffstat (limited to 'executor')
-rw-r--r--executor/common_linux.h97
-rw-r--r--executor/syscalls_linux.h25
2 files changed, 112 insertions, 10 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 5128009dd..37cc9c5ea 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -1232,8 +1232,104 @@ static void reset_arptables()
close(fd);
}
+#include <linux/netfilter_bridge/ebtables.h>
+
+struct ebt_table_desc {
+ const char* name;
+ struct ebt_replace replace;
+ char entrytable[XT_TABLE_SIZE];
+};
+
+static struct ebt_table_desc ebt_tables[] = {
+ {.name = "filter"},
+ {.name = "nat"},
+ {.name = "broute"},
+};
+
+static void checkpoint_ebtables(void)
+{
+ socklen_t optlen;
+ unsigned i;
+ int fd;
+
+ fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (fd == -1)
+ fail("socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)");
+ for (i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
+ struct ebt_table_desc* table = &ebt_tables[i];
+ strcpy(table->replace.name, table->name);
+ optlen = sizeof(table->replace);
+ if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_INFO, &table->replace, &optlen)) {
+ switch (errno) {
+ case EPERM:
+ case ENOENT:
+ case ENOPROTOOPT:
+ continue;
+ }
+ fail("getsockopt(EBT_SO_GET_INIT_INFO)");
+ }
+ debug("checkpoint ebtable %s: entries=%d hooks=%x size=%d\n", table->name, table->replace.nentries, table->replace.valid_hooks, table->replace.entries_size);
+ if (table->replace.entries_size > sizeof(table->entrytable))
+ fail("table size is too large: %u", table->replace.entries_size);
+ table->replace.num_counters = 0;
+ table->replace.entries = table->entrytable;
+ optlen = sizeof(table->replace) + table->replace.entries_size;
+ if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_ENTRIES, &table->replace, &optlen))
+ fail("getsockopt(EBT_SO_GET_INIT_ENTRIES)");
+ }
+ close(fd);
+}
+
+static void reset_ebtables()
+{
+ struct ebt_replace replace;
+ char entrytable[XT_TABLE_SIZE];
+ socklen_t optlen;
+ unsigned i, j, h;
+ int fd;
+
+ fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (fd == -1)
+ fail("socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)");
+ for (i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
+ struct ebt_table_desc* table = &ebt_tables[i];
+ if (table->replace.valid_hooks == 0)
+ continue;
+ memset(&replace, 0, sizeof(replace));
+ strcpy(replace.name, table->name);
+ optlen = sizeof(replace);
+ if (getsockopt(fd, SOL_IP, EBT_SO_GET_INFO, &replace, &optlen))
+ fail("getsockopt(EBT_SO_GET_INFO)");
+ replace.num_counters = 0;
+ for (h = 0; h < NF_BR_NUMHOOKS; h++)
+ table->replace.hook_entry[h] = 0;
+ if (memcmp(&table->replace, &replace, sizeof(table->replace)) == 0) {
+ memset(&entrytable, 0, sizeof(entrytable));
+ replace.entries = entrytable;
+ optlen = sizeof(replace) + replace.entries_size;
+ if (getsockopt(fd, SOL_IP, EBT_SO_GET_ENTRIES, &replace, &optlen))
+ fail("getsockopt(EBT_SO_GET_ENTRIES)");
+ if (memcmp(table->entrytable, entrytable, replace.entries_size) == 0)
+ continue;
+ }
+ debug("resetting ebtable %s\n", table->name);
+ // Kernel does not seem to return actual entry points (wat?).
+ for (j = 0, h = 0; h < NF_BR_NUMHOOKS; h++) {
+ if (table->replace.valid_hooks & (1 << h)) {
+ table->replace.hook_entry[h] = (struct ebt_entries*)table->entrytable + j;
+ j++;
+ }
+ }
+ optlen = sizeof(table->replace) + table->replace.entries_size;
+ if (setsockopt(fd, SOL_IP, EBT_SO_SET_ENTRIES, &table->replace, optlen))
+ fail("setsockopt(EBT_SO_SET_ENTRIES)");
+ }
+ close(fd);
+}
+
static void checkpoint_net_namespace(void)
{
+ checkpoint_ebtables();
checkpoint_arptables();
checkpoint_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]), AF_INET, SOL_IP);
checkpoint_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]), AF_INET6, SOL_IPV6);
@@ -1241,6 +1337,7 @@ static void checkpoint_net_namespace(void)
static void reset_net_namespace(void)
{
+ reset_ebtables();
reset_arptables();
reset_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]), AF_INET, SOL_IP);
reset_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]), AF_INET6, SOL_IPV6);
diff --git a/executor/syscalls_linux.h b/executor/syscalls_linux.h
index edbf9a79c..0bbab652a 100644
--- a/executor/syscalls_linux.h
+++ b/executor/syscalls_linux.h
@@ -2,8 +2,8 @@
#if defined(__i386__) || 0
#define GOARCH "386"
-#define SYZ_REVISION "d82c642c1409d036404216acd5d0886572f581f6"
-unsigned syscall_count = 1582;
+#define SYZ_REVISION "1d92abf94e3a94a587c23e34ff517226557eb39b"
+unsigned syscall_count = 1583;
call_t syscalls[] = {
{"accept4", 364},
{"accept4$alg", 364},
@@ -1200,6 +1200,7 @@ call_t syscalls[] = {
{"setsockopt$ALG_SET_AEAD_AUTHSIZE", 366},
{"setsockopt$ALG_SET_KEY", 366},
{"setsockopt$ARPT_SO_SET_REPLACE", 366},
+ {"setsockopt$EBT_SO_SET_ENTRIES", 366},
{"setsockopt$IP6T_SO_SET_REPLACE", 366},
{"setsockopt$IPT_SO_SET_REPLACE", 366},
{"setsockopt$RDS_CANCEL_SENT_TO", 366},
@@ -1593,8 +1594,8 @@ call_t syscalls[] = {
#if defined(__x86_64__) || 0
#define GOARCH "amd64"
-#define SYZ_REVISION "54bb54ead4b62281da500ec1751ca2932e1441f4"
-unsigned syscall_count = 1635;
+#define SYZ_REVISION "c063297cc1f7a742899148ea3e480a503975e1a3"
+unsigned syscall_count = 1636;
call_t syscalls[] = {
{"accept", 43},
{"accept$alg", 43},
@@ -2832,6 +2833,7 @@ call_t syscalls[] = {
{"setsockopt$ALG_SET_AEAD_AUTHSIZE", 54},
{"setsockopt$ALG_SET_KEY", 54},
{"setsockopt$ARPT_SO_SET_REPLACE", 54},
+ {"setsockopt$EBT_SO_SET_ENTRIES", 54},
{"setsockopt$IP6T_SO_SET_REPLACE", 54},
{"setsockopt$IPT_SO_SET_REPLACE", 54},
{"setsockopt$RDS_CANCEL_SENT_TO", 54},
@@ -3237,8 +3239,8 @@ call_t syscalls[] = {
#if defined(__arm__) || 0
#define GOARCH "arm"
-#define SYZ_REVISION "fe2bd7c6f616382bfcaf3834e90cbba612c30578"
-unsigned syscall_count = 1592;
+#define SYZ_REVISION "2a035864a56374d1ef4eafcffb968f43fd5b075c"
+unsigned syscall_count = 1593;
call_t syscalls[] = {
{"accept", 285},
{"accept$alg", 285},
@@ -4436,6 +4438,7 @@ call_t syscalls[] = {
{"setsockopt$ALG_SET_AEAD_AUTHSIZE", 294},
{"setsockopt$ALG_SET_KEY", 294},
{"setsockopt$ARPT_SO_SET_REPLACE", 294},
+ {"setsockopt$EBT_SO_SET_ENTRIES", 294},
{"setsockopt$IP6T_SO_SET_REPLACE", 294},
{"setsockopt$IPT_SO_SET_REPLACE", 294},
{"setsockopt$RDS_CANCEL_SENT_TO", 294},
@@ -4838,8 +4841,8 @@ call_t syscalls[] = {
#if defined(__aarch64__) || 0
#define GOARCH "arm64"
-#define SYZ_REVISION "a647e74461d106215be994c7e4a030e46be581f4"
-unsigned syscall_count = 1564;
+#define SYZ_REVISION "033a3d40f0ba2f8c5ebeb2a344a44e89db17e105"
+unsigned syscall_count = 1565;
call_t syscalls[] = {
{"accept", 202},
{"accept$alg", 202},
@@ -6018,6 +6021,7 @@ call_t syscalls[] = {
{"setsockopt$ALG_SET_AEAD_AUTHSIZE", 208},
{"setsockopt$ALG_SET_KEY", 208},
{"setsockopt$ARPT_SO_SET_REPLACE", 208},
+ {"setsockopt$EBT_SO_SET_ENTRIES", 208},
{"setsockopt$IP6T_SO_SET_REPLACE", 208},
{"setsockopt$IPT_SO_SET_REPLACE", 208},
{"setsockopt$RDS_CANCEL_SENT_TO", 208},
@@ -6411,8 +6415,8 @@ call_t syscalls[] = {
#if defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || 0
#define GOARCH "ppc64le"
-#define SYZ_REVISION "76a3156b1ae121f74fe5b00f7d0a88b139d13cd6"
-unsigned syscall_count = 1554;
+#define SYZ_REVISION "c996439d4a7c1dc76b269b6869f8bb2b505550b3"
+unsigned syscall_count = 1555;
call_t syscalls[] = {
{"accept", 330},
{"accept$alg", 330},
@@ -7582,6 +7586,7 @@ call_t syscalls[] = {
{"setsockopt$ALG_SET_AEAD_AUTHSIZE", 339},
{"setsockopt$ALG_SET_KEY", 339},
{"setsockopt$ARPT_SO_SET_REPLACE", 339},
+ {"setsockopt$EBT_SO_SET_ENTRIES", 339},
{"setsockopt$IP6T_SO_SET_REPLACE", 339},
{"setsockopt$IPT_SO_SET_REPLACE", 339},
{"setsockopt$RDS_CANCEL_SENT_TO", 339},