summaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-17 22:26:41 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-17 22:26:41 -0800
commitccb19d263fd1c9e34948e2158c53eacbff369344 (patch)
tree6683e55f183920dcbf3e1a5b749e7f9780c465b3 /net/netfilter
parent6a488979f574cb4287880db2dbc8b13cee30c5be (diff)
parentc3b5003b628d8e373262bee42c7260d6a799c73e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (47 commits) tg3: Fix single-vector MSI-X code openvswitch: Fix multipart datapath dumps. ipv6: fix per device IP snmp counters inetpeer: initialize ->redirect_genid in inet_getpeer() net: fix NULL-deref in WARN() in skb_gso_segment() net: WARN if skb_checksum_help() is called on skb requiring segmentation caif: Remove bad WARN_ON in caif_dev caif: Fix typo in Vendor/Product-ID for CAIF modems bnx2x: Disable AN KR work-around for BCM57810 bnx2x: Remove AutoGrEEEn for BCM84833 bnx2x: Remove 100Mb force speed for BCM84833 bnx2x: Fix PFC setting on BCM57840 bnx2x: Fix Super-Isolate mode for BCM84833 net: fix some sparse errors net: kill duplicate included header net: sh-eth: Fix build error by the value which is not defined net: Use device model to get driver name in skb_gso_segment() bridge: BH already disabled in br_fdb_cleanup() net: move sock_update_memcg outside of CONFIG_INET mwl8k: Fixing Sparse ENDIAN CHECK warning ...
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipset/ip_set_core.c37
-rw-r--r--net/netfilter/nf_conntrack_helper.c12
-rw-r--r--net/netfilter/nf_conntrack_netlink.c4
-rw-r--r--net/netfilter/xt_CT.c8
-rw-r--r--net/netfilter/xt_hashlimit.c5
5 files changed, 34 insertions, 32 deletions
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 86137b558f4..32dbf0fa89d 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -77,35 +77,42 @@ find_set_type(const char *name, u8 family, u8 revision)
}
/* Unlock, try to load a set type module and lock again */
-static int
-try_to_load_type(const char *name)
+static bool
+load_settype(const char *name)
{
nfnl_unlock();
pr_debug("try to load ip_set_%s\n", name);
if (request_module("ip_set_%s", name) < 0) {
pr_warning("Can't find ip_set type %s\n", name);
nfnl_lock();
- return -IPSET_ERR_FIND_TYPE;
+ return false;
}
nfnl_lock();
- return -EAGAIN;
+ return true;
}
/* Find a set type and reference it */
+#define find_set_type_get(name, family, revision, found) \
+ __find_set_type_get(name, family, revision, found, false)
+
static int
-find_set_type_get(const char *name, u8 family, u8 revision,
- struct ip_set_type **found)
+__find_set_type_get(const char *name, u8 family, u8 revision,
+ struct ip_set_type **found, bool retry)
{
struct ip_set_type *type;
int err;
+ if (retry && !load_settype(name))
+ return -IPSET_ERR_FIND_TYPE;
+
rcu_read_lock();
*found = find_set_type(name, family, revision);
if (*found) {
err = !try_module_get((*found)->me) ? -EFAULT : 0;
goto unlock;
}
- /* Make sure the type is loaded but we don't support the revision */
+ /* Make sure the type is already loaded
+ * but we don't support the revision */
list_for_each_entry_rcu(type, &ip_set_type_list, list)
if (STREQ(type->name, name)) {
err = -IPSET_ERR_FIND_TYPE;
@@ -113,7 +120,8 @@ find_set_type_get(const char *name, u8 family, u8 revision,
}
rcu_read_unlock();
- return try_to_load_type(name);
+ return retry ? -IPSET_ERR_FIND_TYPE :
+ __find_set_type_get(name, family, revision, found, true);
unlock:
rcu_read_unlock();
@@ -124,12 +132,19 @@ unlock:
* If we succeeded, the supported minimal and maximum revisions are
* filled out.
*/
+#define find_set_type_minmax(name, family, min, max) \
+ __find_set_type_minmax(name, family, min, max, false)
+
static int
-find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
+__find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max,
+ bool retry)
{
struct ip_set_type *type;
bool found = false;
+ if (retry && !load_settype(name))
+ return -IPSET_ERR_FIND_TYPE;
+
*min = 255; *max = 0;
rcu_read_lock();
list_for_each_entry_rcu(type, &ip_set_type_list, list)
@@ -145,7 +160,8 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
if (found)
return 0;
- return try_to_load_type(name);
+ return retry ? -IPSET_ERR_FIND_TYPE :
+ __find_set_type_minmax(name, family, min, max, true);
}
#define family_name(f) ((f) == AF_INET ? "inet" : \
@@ -1126,6 +1142,7 @@ release_refcount:
if (ret || !cb->args[2]) {
pr_debug("release set %s\n", ip_set_list[index]->name);
ip_set_put_byindex(index);
+ cb->args[2] = 0;
}
out:
if (nlh) {
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 299fec91f74..bbe23baa19b 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -121,18 +121,6 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
int ret = 0;
if (tmpl != NULL) {
- /* we've got a userspace helper. */
- if (tmpl->status & IPS_USERSPACE_HELPER) {
- help = nf_ct_helper_ext_add(ct, flags);
- if (help == NULL) {
- ret = -ENOMEM;
- goto out;
- }
- rcu_assign_pointer(help->helper, NULL);
- __set_bit(IPS_USERSPACE_HELPER_BIT, &ct->status);
- ret = 0;
- goto out;
- }
help = nfct_help(tmpl);
if (help != NULL)
helper = help->helper;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 2a4834b8333..9307b033c0c 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2042,10 +2042,6 @@ ctnetlink_create_expect(struct net *net, u16 zone,
}
help = nfct_help(ct);
if (!help) {
- err = -EOPNOTSUPP;
- goto out;
- }
- if (test_bit(IPS_USERSPACE_HELPER_BIT, &ct->status)) {
if (!cda[CTA_EXPECT_TIMEOUT]) {
err = -EINVAL;
goto out;
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 8e87123f137..0221d10de75 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -62,8 +62,8 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par)
int ret = 0;
u8 proto;
- if (info->flags & ~(XT_CT_NOTRACK | XT_CT_USERSPACE_HELPER))
- return -EOPNOTSUPP;
+ if (info->flags & ~XT_CT_NOTRACK)
+ return -EINVAL;
if (info->flags & XT_CT_NOTRACK) {
ct = nf_ct_untracked_get();
@@ -92,9 +92,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par)
GFP_KERNEL))
goto err3;
- if (info->flags & XT_CT_USERSPACE_HELPER) {
- __set_bit(IPS_USERSPACE_HELPER_BIT, &ct->status);
- } else if (info->helper[0]) {
+ if (info->helper[0]) {
ret = -ENOENT;
proto = xt_ct_find_proto(par);
if (!proto) {
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 8e499210187..d95f9c963cd 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -445,7 +445,6 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
{
__be16 _ports[2], *ports;
u8 nexthdr;
- __be16 frag_off;
int poff;
memset(dst, 0, sizeof(*dst));
@@ -466,6 +465,9 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
break;
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
case NFPROTO_IPV6:
+ {
+ __be16 frag_off;
+
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr,
sizeof(dst->ip6.dst));
@@ -485,6 +487,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
if ((int)protoff < 0)
return -1;
break;
+ }
#endif
default:
BUG();