diff options
author | David S. Miller <davem@davemloft.net> | 2019-05-05 21:35:08 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-05 21:35:08 -0700 |
commit | 1ffad6d1af7a9e69f99d5df4335015271e27d564 (patch) | |
tree | 7609d0440bd185cee82a9b2bd676562cee23c1d3 /net | |
parent | 19ab5f40235538fc04d77e0fdb708436b0471f01 (diff) | |
parent | 522e4077e8dcdfc5b8e96469d3bc2324bc5d6466 (diff) | |
download | linux-1ffad6d1af7a9e69f99d5df4335015271e27d564.tar.gz linux-1ffad6d1af7a9e69f99d5df4335015271e27d564.tar.bz2 linux-1ffad6d1af7a9e69f99d5df4335015271e27d564.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says:
===================
Netfilter updates for net-next
The following batch contains Netfilter updates for net-next, they are:
1) Move nft_expr_clone() to nft_dynset, from Paul Gortmaker.
2) Do not include module.h from net/netfilter/nf_tables.h,
also from Paul.
3) Restrict conntrack sysctl entries to boolean, from Tonghao Zhang.
4) Several patches to add infrastructure to autoload NAT helper
modules from their respective conntrack helper, this also includes
the first client of this code in OVS, patches from Flavio Leitner.
5) Add support to match for conntrack ID, from Brett Mastbergen.
6) Spelling fix in connlabel, from Colin Ian King.
7) Use struct_size() from hashlimit, from Gustavo A. R. Silva.
8) Add optimized version of nf_inet_addr_mask(), from Li RongQing.
===================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/nf_nat_h323.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_pptp.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_amanda.c | 8 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_ftp.c | 18 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 86 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_irc.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sane.c | 12 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 28 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_standalone.c | 48 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_tftp.c | 18 | ||||
-rw-r--r-- | net/netfilter/nf_nat_amanda.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_nat_ftp.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_nat_irc.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_nat_sip.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_nat_tftp.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_tables_set_core.c | 1 | ||||
-rw-r--r-- | net/netfilter/nft_ct.c | 8 | ||||
-rw-r--r-- | net/netfilter/nft_dynset.c | 17 | ||||
-rw-r--r-- | net/netfilter/xt_connlabel.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_hashlimit.c | 3 | ||||
-rw-r--r-- | net/openvswitch/conntrack.c | 26 |
21 files changed, 262 insertions, 68 deletions
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 4e6b53ab6c33..7875c98072eb 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -631,4 +631,4 @@ module_exit(fini); MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); MODULE_DESCRIPTION("H.323 NAT helper"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ip_nat_h323"); +MODULE_ALIAS_NF_NAT_HELPER("h323"); diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c index 68b4d450391b..e17b4ee7604c 100644 --- a/net/ipv4/netfilter/nf_nat_pptp.c +++ b/net/ipv4/netfilter/nf_nat_pptp.c @@ -37,7 +37,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP"); -MODULE_ALIAS("ip_nat_pptp"); +MODULE_ALIAS_NF_NAT_HELPER("pptp"); static void pptp_nat_expected(struct nf_conn *ct, struct nf_conntrack_expect *exp) diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index f2681ec5b5f6..dbec6fca0d9e 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c @@ -28,11 +28,13 @@ static unsigned int master_timeout __read_mostly = 300; static char *ts_algo = "kmp"; +#define HELPER_NAME "amanda" + MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); MODULE_DESCRIPTION("Amanda connection tracking module"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_amanda"); -MODULE_ALIAS_NFCT_HELPER("amanda"); +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); module_param(master_timeout, uint, 0600); MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); @@ -179,13 +181,14 @@ static const struct nf_conntrack_expect_policy amanda_exp_policy = { static struct nf_conntrack_helper amanda_helper[2] __read_mostly = { { - .name = "amanda", + .name = HELPER_NAME, .me = THIS_MODULE, .help = amanda_help, .tuple.src.l3num = AF_INET, .tuple.src.u.udp.port = cpu_to_be16(10080), .tuple.dst.protonum = IPPROTO_UDP, .expect_policy = &amanda_exp_policy, + .nat_mod_name = NF_NAT_HELPER_NAME(HELPER_NAME), }, { .name = "amanda", @@ -195,6 +198,7 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = { .tuple.src.u.udp.port = cpu_to_be16(10080), .tuple.dst.protonum = IPPROTO_UDP, .expect_policy = &amanda_exp_policy, + .nat_mod_name = NF_NAT_HELPER_NAME(HELPER_NAME), }, }; diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index a11c304fb771..32aeac1c4760 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -29,11 +29,13 @@ #include <net/netfilter/nf_conntrack_helper.h> #include <linux/netfilter/nf_conntrack_ftp.h> +#define HELPER_NAME "ftp" + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); MODULE_DESCRIPTION("ftp connection tracking helper"); MODULE_ALIAS("ip_conntrack_ftp"); -MODULE_ALIAS_NFCT_HELPER("ftp"); +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); /* This is slow, but it's simple. --RR */ static char *ftp_buffer; @@ -588,12 +590,14 @@ static int __init nf_conntrack_ftp_init(void) /* FIXME should be configurable whether IPv4 and IPv6 FTP connections are tracked or not - YK */ for (i = 0; i < ports_c; i++) { - nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP, "ftp", - FTP_PORT, ports[i], ports[i], &ftp_exp_policy, - 0, help, nf_ct_ftp_from_nlattr, THIS_MODULE); - nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP, "ftp", - FTP_PORT, ports[i], ports[i], &ftp_exp_policy, - 0, help, nf_ct_ftp_from_nlattr, THIS_MODULE); + nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP, + HELPER_NAME, FTP_PORT, ports[i], ports[i], + &ftp_exp_policy, 0, help, + nf_ct_ftp_from_nlattr, THIS_MODULE); + nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP, + HELPER_NAME, FTP_PORT, ports[i], ports[i], + &ftp_exp_policy, 0, help, + nf_ct_ftp_from_nlattr, THIS_MODULE); } ret = nf_conntrack_helpers_register(ftp, ports_c * 2); diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 274baf1dab87..918df7f71c8f 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -42,6 +42,9 @@ module_param_named(nf_conntrack_helper, nf_ct_auto_assign_helper, bool, 0644); MODULE_PARM_DESC(nf_conntrack_helper, "Enable automatic conntrack helper assignment (default 0)"); +static DEFINE_MUTEX(nf_ct_nat_helpers_mutex); +static struct list_head nf_ct_nat_helpers __read_mostly; + /* Stupid hash, but collision free for the default registrations of the * helpers currently in the kernel. */ static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple) @@ -130,6 +133,70 @@ void nf_conntrack_helper_put(struct nf_conntrack_helper *helper) } EXPORT_SYMBOL_GPL(nf_conntrack_helper_put); +static struct nf_conntrack_nat_helper * +nf_conntrack_nat_helper_find(const char *mod_name) +{ + struct nf_conntrack_nat_helper *cur; + bool found = false; + + list_for_each_entry_rcu(cur, &nf_ct_nat_helpers, list) { + if (!strcmp(cur->mod_name, mod_name)) { + found = true; + break; + } + } + return found ? cur : NULL; +} + +int +nf_nat_helper_try_module_get(const char *name, u16 l3num, u8 protonum) +{ + struct nf_conntrack_helper *h; + struct nf_conntrack_nat_helper *nat; + char mod_name[NF_CT_HELPER_NAME_LEN]; + int ret = 0; + + rcu_read_lock(); + h = __nf_conntrack_helper_find(name, l3num, protonum); + if (!h) { + rcu_read_unlock(); + return -ENOENT; + } + + nat = nf_conntrack_nat_helper_find(h->nat_mod_name); + if (!nat) { + snprintf(mod_name, sizeof(mod_name), "%s", h->nat_mod_name); + rcu_read_unlock(); + request_module(mod_name); + + rcu_read_lock(); + nat = nf_conntrack_nat_helper_find(mod_name); + if (!nat) { + rcu_read_unlock(); + return -ENOENT; + } + } + + if (!try_module_get(nat->module)) + ret = -ENOENT; + + rcu_read_unlock(); + return ret; +} +EXPORT_SYMBOL_GPL(nf_nat_helper_try_module_get); + +void nf_nat_helper_put(struct nf_conntrack_helper *helper) +{ + struct nf_conntrack_nat_helper *nat; + + nat = nf_conntrack_nat_helper_find(helper->nat_mod_name); + if (WARN_ON_ONCE(!nat)) + return; + + module_put(nat->module); +} +EXPORT_SYMBOL_GPL(nf_nat_helper_put); + struct nf_conn_help * nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) { @@ -430,6 +497,8 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper, helper->help = help; helper->from_nlattr = from_nlattr; helper->me = module; + snprintf(helper->nat_mod_name, sizeof(helper->nat_mod_name), + NF_NAT_HELPER_PREFIX "%s", name); if (spec_port == default_port) snprintf(helper->name, sizeof(helper->name), "%s", name); @@ -466,6 +535,22 @@ void nf_conntrack_helpers_unregister(struct nf_conntrack_helper *helper, } EXPORT_SYMBOL_GPL(nf_conntrack_helpers_unregister); +void nf_nat_helper_register(struct nf_conntrack_nat_helper *nat) +{ + mutex_lock(&nf_ct_nat_helpers_mutex); + list_add_rcu(&nat->list, &nf_ct_nat_helpers); + mutex_unlock(&nf_ct_nat_helpers_mutex); +} +EXPORT_SYMBOL_GPL(nf_nat_helper_register); + +void nf_nat_helper_unregister(struct nf_conntrack_nat_helper *nat) +{ + mutex_lock(&nf_ct_nat_helpers_mutex); + list_del_rcu(&nat->list); + mutex_unlock(&nf_ct_nat_helpers_mutex); +} +EXPORT_SYMBOL_GPL(nf_nat_helper_unregister); + static const struct nf_ct_ext_type helper_extend = { .len = sizeof(struct nf_conn_help), .align = __alignof__(struct nf_conn_help), @@ -493,6 +578,7 @@ int nf_conntrack_helper_init(void) goto out_extend; } + INIT_LIST_HEAD(&nf_ct_nat_helpers); return 0; out_extend: kvfree(nf_ct_helper_hash); diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 4099f4d79bae..79e5014b3b0d 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c @@ -42,11 +42,13 @@ unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb, struct nf_conntrack_expect *exp) __read_mostly; EXPORT_SYMBOL_GPL(nf_nat_irc_hook); +#define HELPER_NAME "irc" + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_irc"); -MODULE_ALIAS_NFCT_HELPER("irc"); +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); module_param_array(ports, ushort, &ports_c, 0400); MODULE_PARM_DESC(ports, "port numbers of IRC servers"); @@ -259,7 +261,7 @@ static int __init nf_conntrack_irc_init(void) ports[ports_c++] = IRC_PORT; for (i = 0; i < ports_c; i++) { - nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, "irc", + nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, HELPER_NAME, IRC_PORT, ports[i], i, &irc_exp_policy, 0, help, NULL, THIS_MODULE); } diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c index 5072ff96ab33..83306648dd0f 100644 --- a/net/netfilter/nf_conntrack_sane.c +++ b/net/netfilter/nf_conntrack_sane.c @@ -30,10 +30,12 @@ #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_sane.h> +#define HELPER_NAME "sane" + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>"); MODULE_DESCRIPTION("SANE connection tracking helper"); -MODULE_ALIAS_NFCT_HELPER("sane"); +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); static char *sane_buffer; @@ -195,12 +197,12 @@ static int __init nf_conntrack_sane_init(void) /* FIXME should be configurable whether IPv4 and IPv6 connections are tracked or not - YK */ for (i = 0; i < ports_c; i++) { - nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP, "sane", - SANE_PORT, ports[i], ports[i], + nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP, + HELPER_NAME, SANE_PORT, ports[i], ports[i], &sane_exp_policy, 0, help, NULL, THIS_MODULE); - nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP, "sane", - SANE_PORT, ports[i], ports[i], + nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP, + HELPER_NAME, SANE_PORT, ports[i], ports[i], &sane_exp_policy, 0, help, NULL, THIS_MODULE); } diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index d5454d1031a3..c30c883c370b 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -30,11 +30,13 @@ #include <net/netfilter/nf_conntrack_zones.h> #include <linux/netfilter/nf_conntrack_sip.h> +#define HELPER_NAME "sip" + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>"); MODULE_DESCRIPTION("SIP connection tracking helper"); MODULE_ALIAS("ip_conntrack_sip"); -MODULE_ALIAS_NFCT_HELPER("sip"); +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); #define MAX_PORTS 8 static unsigned short ports[MAX_PORTS]; @@ -1669,21 +1671,21 @@ static int __init nf_conntrack_sip_init(void) ports[ports_c++] = SIP_PORT; for (i = 0; i < ports_c; i++) { - nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP, "sip", - SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, sip_help_udp, + nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP, + HELPER_NAME, SIP_PORT, ports[i], i, + sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp, NULL, THIS_MODULE); - nf_ct_helper_init(&sip[4 * i + 1], AF_INET, IPPROTO_TCP, "sip", - SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, sip_help_tcp, + nf_ct_helper_init(&sip[4 * i + 1], AF_INET, IPPROTO_TCP, + HELPER_NAME, SIP_PORT, ports[i], i, + sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp, NULL, THIS_MODULE); - nf_ct_helper_init(&sip[4 * i + 2], AF_INET6, IPPROTO_UDP, "sip", - SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, sip_help_udp, + nf_ct_helper_init(&sip[4 * i + 2], AF_INET6, IPPROTO_UDP, + HELPER_NAME, SIP_PORT, ports[i], i, + sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp, NULL, THIS_MODULE); - nf_ct_helper_init(&sip[4 * i + 3], AF_INET6, IPPROTO_TCP, "sip", - SIP_PORT, ports[i], i, sip_exp_policy, - SIP_EXPECT_MAX, sip_help_tcp, + nf_ct_helper_init(&sip[4 * i + 3], AF_INET6, IPPROTO_TCP, + HELPER_NAME, SIP_PORT, ports[i], i, + sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp, NULL, THIS_MODULE); } diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index c2ae14c720b4..e0d392cb3075 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -511,6 +511,8 @@ static void nf_conntrack_standalone_fini_proc(struct net *net) /* Log invalid packets of a given protocol */ static int log_invalid_proto_min __read_mostly; static int log_invalid_proto_max __read_mostly = 255; +static int zero; +static int one = 1; /* size the user *wants to set */ static unsigned int nf_conntrack_htable_size_user __read_mostly; @@ -624,9 +626,11 @@ static struct ctl_table nf_ct_sysctl_table[] = { [NF_SYSCTL_CT_CHECKSUM] = { .procname = "nf_conntrack_checksum", .data = &init_net.ct.sysctl_checksum, - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, [NF_SYSCTL_CT_LOG_INVALID] = { .procname = "nf_conntrack_log_invalid", @@ -647,33 +651,41 @@ static struct ctl_table nf_ct_sysctl_table[] = { [NF_SYSCTL_CT_ACCT] = { .procname = "nf_conntrack_acct", .data = &init_net.ct.sysctl_acct, - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, [NF_SYSCTL_CT_HELPER] = { .procname = "nf_conntrack_helper", .data = &init_net.ct.sysctl_auto_assign_helper, - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, #ifdef CONFIG_NF_CONNTRACK_EVENTS [NF_SYSCTL_CT_EVENTS] = { .procname = "nf_conntrack_events", .data = &init_net.ct.sysctl_events, - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, #endif #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP [NF_SYSCTL_CT_TIMESTAMP] = { .procname = "nf_conntrack_timestamp", .data = &init_net.ct.sysctl_tstamp, - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, #endif [NF_SYSCTL_CT_PROTO_TIMEOUT_GENERIC] = { @@ -744,15 +756,19 @@ static struct ctl_table nf_ct_sysctl_table[] = { }, [NF_SYSCTL_CT_PROTO_TCP_LOOSE] = { .procname = "nf_conntrack_tcp_loose", - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, [NF_SYSCTL_CT_PROTO_TCP_LIBERAL] = { .procname = "nf_conntrack_tcp_be_liberal", - .maxlen = sizeof(unsigned int), + .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, [NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS] = { .procname = "nf_conntrack_tcp_max_retrans", @@ -887,7 +903,9 @@ static struct ctl_table nf_ct_sysctl_table[] = { .procname = "nf_conntrack_dccp_loose", .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, }, #endif #ifdef CONFIG_NF_CT_PROTO_GRE diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c index 548b673b3625..6977cb91ae9a 100644 --- a/net/netfilter/nf_conntrack_tftp.c +++ b/net/netfilter/nf_conntrack_tftp.c @@ -20,11 +20,13 @@ #include <net/netfilter/nf_conntrack_helper.h> #include <linux/netfilter/nf_conntrack_tftp.h> +#define HELPER_NAME "tftp" + MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>"); MODULE_DESCRIPTION("TFTP connection tracking helper"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ip_conntrack_tftp"); -MODULE_ALIAS_NFCT_HELPER("tftp"); +MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); #define MAX_PORTS 8 static unsigned short ports[MAX_PORTS]; @@ -119,12 +121,14 @@ static int __init nf_conntrack_tftp_init(void) ports[ports_c++] = TFTP_PORT; for (i = 0; i < ports_c; i++) { - nf_ct_helper_init(&tftp[2 * i], AF_INET, IPPROTO_UDP, "tftp", - TFTP_PORT, ports[i], i, &tftp_exp_policy, - 0, tftp_help, NULL, THIS_MODULE); - nf_ct_helper_init(&tftp[2 * i + 1], AF_INET6, IPPROTO_UDP, "tftp", - TFTP_PORT, ports[i], i, &tftp_exp_policy, - 0, tftp_help, NULL, THIS_MODULE); + nf_ct_helper_init(&tftp[2 * i], AF_INET, IPPROTO_UDP, + HELPER_NAME, TFTP_PORT, ports[i], i, + &tftp_exp_policy, 0, tftp_help, NULL, + THIS_MODULE); + nf_ct_helper_init(&tftp[2 * i + 1], AF_INET6, IPPROTO_UDP, + HELPER_NAME, TFTP_PORT, ports[i], i, + &tftp_exp_policy, 0, tftp_help, NULL, + THIS_MODULE); } ret = nf_conntrack_helpers_register(tftp, ports_c * 2); diff --git a/net/netfilter/nf_nat_amanda.c b/net/netfilter/nf_nat_amanda.c index e4d61a7a5258..4e59416ea709 100644 --- a/net/netfilter/nf_nat_amanda.c +++ b/net/netfilter/nf_nat_amanda.c @@ -19,10 +19,15 @@ #include <net/netfilter/nf_nat_helper.h> #include <linux/netfilter/nf_conntrack_amanda.h> +#define NAT_HELPER_NAME "amanda" + MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>"); MODULE_DESCRIPTION("Amanda NAT helper"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ip_nat_amanda"); +MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME); + +static struct nf_conntrack_nat_helper nat_helper_amanda = + NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME); static unsigned int help(struct sk_buff *skb, enum ip_conntrack_info ctinfo, @@ -74,6 +79,7 @@ static unsigned int help(struct sk_buff *skb, static void __exit nf_nat_amanda_fini(void) { + nf_nat_helper_unregister(&nat_helper_amanda); RCU_INIT_POINTER(nf_nat_amanda_hook, NULL); synchronize_rcu(); } @@ -81,6 +87,7 @@ static void __exit nf_nat_amanda_fini(void) static int __init nf_nat_amanda_init(void) { BUG_ON(nf_nat_amanda_hook != NULL); + nf_nat_helper_register(&nat_helper_amanda); RCU_INIT_POINTER(nf_nat_amanda_hook, help); return 0; } diff --git a/net/netfilter/nf_nat_ftp.c b/net/netfilter/nf_nat_ftp.c index 5063cbf1689c..0ea6b1bc52de 100644 --- a/net/netfilter/nf_nat_ftp.c +++ b/net/netfilter/nf_nat_ftp.c @@ -21,13 +21,18 @@ #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_ftp.h> +#define NAT_HELPER_NAME "ftp" + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); MODULE_DESCRIPTION("ftp NAT helper"); -MODULE_ALIAS("ip_nat_ftp"); +MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME); /* FIXME: Time out? --RR */ +static struct nf_conntrack_nat_helper nat_helper_ftp = + NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME); + static int nf_nat_ftp_fmt_cmd(struct nf_conn *ct, enum nf_ct_ftp_type type, char *buffer, size_t buflen, union nf_inet_addr *addr, u16 port) @@ -124,6 +129,7 @@ out: static void __exit nf_nat_ftp_fini(void) { + nf_nat_helper_unregister(&nat_helper_ftp); RCU_INIT_POINTER(nf_nat_ftp_hook, NULL); synchronize_rcu(); } @@ -131,6 +137,7 @@ static void __exit nf_nat_ftp_fini(void) static int __init nf_nat_ftp_init(void) { BUG_ON(nf_nat_ftp_hook != NULL); + nf_nat_helper_register(&nat_helper_ftp); RCU_INIT_POINTER(nf_nat_ftp_hook, nf_nat_ftp); return 0; } diff --git a/net/netfilter/nf_nat_irc.c b/net/netfilter/nf_nat_irc.c index 3aa35a43100d..d87cbe5e03ec 100644 --- a/net/netfilter/nf_nat_irc.c +++ b/net/netfilter/nf_nat_irc.c @@ -23,10 +23,15 @@ #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_irc.h> +#define NAT_HELPER_NAME "irc" + MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); MODULE_DESCRIPTION("IRC (DCC) NAT helper"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ip_nat_irc"); +MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME); + +static struct nf_conntrack_nat_helper nat_helper_irc = + NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME); static unsigned int help(struct sk_buff *skb, enum ip_conntrack_info ctinfo, @@ -96,6 +101,7 @@ static unsigned int help(struct sk_buff *skb, static void __exit nf_nat_irc_fini(void) { + nf_nat_helper_unregister(&nat_helper_irc); RCU_INIT_POINTER(nf_nat_irc_hook, NULL); synchronize_rcu(); } @@ -103,6 +109,7 @@ static void __exit nf_nat_irc_fini(void) static int __init nf_nat_irc_init(void) { BUG_ON(nf_nat_irc_hook != NULL); + nf_nat_helper_register(&nat_helper_irc); RCU_INIT_POINTER(nf_nat_irc_hook, help); return 0; } diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index aa1be643d7a0..464387b3600f 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c @@ -24,11 +24,15 @@ #include <net/netfilter/nf_conntrack_seqadj.h> #include <linux/netfilter/nf_conntrack_sip.h> +#define NAT_HELPER_NAME "sip" + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>"); MODULE_DESCRIPTION("SIP NAT helper"); -MODULE_ALIAS("ip_nat_sip"); +MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME); +static struct nf_conntrack_nat_helper nat_helper_sip = + NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME); static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff, unsigned int dataoff, @@ -656,8 +660,8 @@ static struct nf_ct_helper_expectfn sip_nat = { static void __exit nf_nat_sip_fini(void) { + nf_nat_helper_unregister(&nat_helper_sip); RCU_INIT_POINTER(nf_nat_sip_hooks, NULL); - nf_ct_helper_expectfn_unregister(&sip_nat); synchronize_rcu(); } @@ -675,6 +679,7 @@ static const struct nf_nat_sip_hooks sip_hooks = { static int __init nf_nat_sip_init(void) { BUG_ON(nf_nat_sip_hooks != NULL); + nf_nat_helper_register(&nat_helper_sip); RCU_INIT_POINTER(nf_nat_sip_hooks, &sip_hooks); nf_ct_helper_expectfn_register(&sip_nat); return 0; diff --git a/net/netfilter/nf_nat_tftp.c b/net/netfilter/nf_nat_tftp.c index 7f67e1d5310d..e633b3863e33 100644 --- a/net/netfilter/nf_nat_tftp.c +++ b/net/netfilter/nf_nat_tftp.c @@ -13,10 +13,15 @@ #include <net/netfilter/nf_nat_helper.h> #include <linux/netfilter/nf_conntrack_tftp.h> +#define NAT_HELPER_NAME "tftp" + MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>"); MODULE_DESCRIPTION("TFTP NAT helper"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ip_nat_tftp"); +MODULE_ALIAS_NF_NAT_HELPER(NAT_HELPER_NAME); + +static struct nf_conntrack_nat_helper nat_helper_tftp = + NF_CT_NAT_HELPER_INIT(NAT_HELPER_NAME); static unsigned int help(struct sk_buff *skb, enum ip_conntrack_info ctinfo, @@ -37,6 +42,7 @@ static unsigned int help(struct sk_buff *skb, static void __exit nf_nat_tftp_fini(void) { + nf_nat_helper_unregister(&nat_helper_tftp); RCU_INIT_POINTER(nf_nat_tftp_hook, NULL); synchronize_rcu(); } @@ -44,6 +50,7 @@ static void __exit nf_nat_tftp_fini(void) static int __init nf_nat_tftp_init(void) { BUG_ON(nf_nat_tftp_hook != NULL); + nf_nat_helper_register(&nat_helper_tftp); RCU_INIT_POINTER(nf_nat_tftp_hook, help); return 0; } diff --git a/net/netfilter/nf_tables_set_core.c b/net/netfilter/nf_tables_set_core.c index 814789644bd3..a9fce8d10051 100644 --- a/net/netfilter/nf_tables_set_core.c +++ b/net/netfilter/nf_tables_set_core.c @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#include <linux/module.h> #include <net/netfilter/nf_tables_core.h> static int __init nf_tables_set_module_init(void) diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index b422b74bfe08..f043936763f3 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -178,6 +178,11 @@ static void nft_ct_get_eval(const struct nft_expr *expr, return; } #endif + case NFT_CT_ID: + if (!nf_ct_is_confirmed(ct)) + goto err; + *dest = nf_ct_get_id(ct); + return; default: break; } @@ -479,6 +484,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, len = sizeof(u16); break; #endif + case NFT_CT_ID: + len = sizeof(u32); + break; default: return -EOPNOTSUPP; } diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index e461007558e8..8394560aa695 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -28,6 +28,23 @@ struct nft_dynset { struct nft_set_binding binding; }; +static int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src) +{ + int err; + + if (src->ops->clone) { + dst->ops = src->ops; + err = src->ops->clone(dst, src); + if (err < 0) + return err; + } else { + memcpy(dst, src, src->ops->size); + } + + __module_get(src->ops->type->owner); + return 0; +} + static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr, struct nft_regs *regs) { diff --git a/net/netfilter/xt_connlabel.c b/net/netfilter/xt_connlabel.c index 4fa4efd24353..893374ac3758 100644 --- a/net/netfilter/xt_connlabel.c +++ b/net/netfilter/xt_connlabel.c @@ -15,7 +15,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Florian Westphal <fw@strlen.de>"); -MODULE_DESCRIPTION("Xtables: add/match connection trackling labels"); +MODULE_DESCRIPTION("Xtables: add/match connection tracking labels"); MODULE_ALIAS("ipt_connlabel"); MODULE_ALIAS("ip6t_connlabel"); diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 8d86e39d6280..a30536b17ee1 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -288,8 +288,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, size = 16; } /* FIXME: don't use vmalloc() here or anywhere else -HW */ - hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + - sizeof(struct hlist_head) * size); + hinfo = vmalloc(struct_size(hinfo, hash, size)); if (hinfo == NULL) return -ENOMEM; *out_hinfo = hinfo; diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index caeabf5215e8..333ec5f298fe 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -1307,6 +1307,7 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name, { struct nf_conntrack_helper *helper; struct nf_conn_help *help; + int ret = 0; helper = nf_conntrack_helper_try_module_get(name, info->family, key->ip.proto); @@ -1321,13 +1322,21 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name, return -ENOMEM; } +#ifdef CONFIG_NF_NAT_NEEDED + if (info->nat) { + ret = nf_nat_helper_try_module_get(name, info->family, + key->ip.proto); + if (ret) { + nf_conntrack_helper_put(helper); + OVS_NLERR(log, "Failed to load \"%s\" NAT helper, error: %d", + name, ret); + return ret; + } + } +#endif rcu_assign_pointer(help->helper, helper); info->helper = helper; - - if (info->nat) - request_module("ip_nat_%s", name); - - return 0; + return ret; } #if IS_ENABLED(CONFIG_NF_NAT) @@ -1801,8 +1810,13 @@ void ovs_ct_free_action(const struct nlattr *a) static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info) { - if (ct_info->helper) + if (ct_info->helper) { +#ifdef CONFIG_NF_NAT_NEEDED + if (ct_info->nat) + nf_nat_helper_put(ct_info->helper); +#endif nf_conntrack_helper_put(ct_info->helper); + } if (ct_info->ct) { if (ct_info->timeout[0]) nf_ct_destroy_timeout(ct_info->ct); |