diff --git a/Makefile b/Makefile index a1617a3fa..dcc9492af 100644 --- a/Makefile +++ b/Makefile @@ -141,12 +141,12 @@ ifneq ($(PIEGEN),no) endif endif -cflags-y += -iquote include -iquote pie -iquote . +cflags-y += -iquote include -iquote pie -iquote . -I/usr/include/libnl3 cflags-y += -iquote $(ARCH_DIR) -iquote $(ARCH_DIR)/include cflags-y += -fno-strict-aliasing export cflags-y -LIBS := -lrt -lpthread -lprotobuf-c -ldl +LIBS := -lrt -lpthread -lprotobuf-c -ldl -lnl-3 DEFINES += -D_FILE_OFFSET_BITS=64 DEFINES += -D_GNU_SOURCE @@ -161,7 +161,7 @@ ifeq ($(DEBUG),1) DEFINES += -DCR_DEBUG CFLAGS += -O0 -ggdb3 else - CFLAGS += -O2 + CFLAGS += -O2 -g endif ifeq ($(GMON),1) diff --git a/net.c b/net.c index 9c009525e..9f62cd0c6 100644 --- a/net.c +++ b/net.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "imgset.h" #include "namespaces.h" @@ -359,6 +360,54 @@ static int dump_one_nf(struct nlmsghdr *hdr, void *arg) return 0; } +static int ct_restore_callback(struct nlmsghdr *nlh) +{ + struct nfgenmsg *msg; + struct nlattr *tb[CTA_MAX+1], *tbp[CTA_PROTOINFO_MAX + 1], *tb_tcp[CTA_PROTOINFO_TCP_MAX+1]; + int err; + + msg = NLMSG_DATA(nlh); + + if (msg->nfgen_family != AF_INET && msg->nfgen_family != AF_INET6) + return 0; + + err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX, NULL); + if (err < 0) + return -1; + + if (!tb[CTA_PROTOINFO]) + return 0; + + err = nla_parse_nested(tbp, CTA_PROTOINFO_MAX, tb[CTA_PROTOINFO], NULL); + if (err < 0) + return -1; + + if (!tbp[CTA_PROTOINFO_TCP]) + return 0; + + err = nla_parse_nested(tb_tcp, CTA_PROTOINFO_TCP_MAX, tbp[CTA_PROTOINFO_TCP], NULL); + if (err < 0) + return -1; + + if (tb_tcp[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) { + struct nf_ct_tcp_flags *flags; + + flags = nla_data(tb_tcp[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]); + flags->flags |= IP_CT_TCP_FLAG_BE_LIBERAL; + flags->mask |= IP_CT_TCP_FLAG_BE_LIBERAL; + } + + if (tb_tcp[CTA_PROTOINFO_TCP_FLAGS_REPLY]) { + struct nf_ct_tcp_flags *flags; + + flags = nla_data(tb_tcp[CTA_PROTOINFO_TCP_FLAGS_REPLY]); + flags->flags |= IP_CT_TCP_FLAG_BE_LIBERAL; + flags->mask |= IP_CT_TCP_FLAG_BE_LIBERAL; + } + + return 0; +} + static int restore_nf_ct(int pid, int type) { struct nlmsghdr *nlh = NULL; @@ -404,6 +453,10 @@ static int restore_nf_ct(int pid, int type) goto out; } + if (type == CR_FD_NETNF_CT) + if (ct_restore_callback(nlh)) + goto out; + nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_CREATE; ret = do_rtnl_req(sk, nlh, nlh->nlmsg_len, NULL, NULL, NULL); if (ret)