aboutsummaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_hash.c8
-rw-r--r--net/ipv4/fib_trie.c6
-rw-r--r--net/ipv4/inet_hashtables.c6
-rw-r--r--net/ipv4/inet_timewait_sock.c3
-rw-r--r--net/ipv4/inetpeer.c2
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c2
-rw-r--r--net/ipv4/netfilter/arp_tables.c48
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c4
-rw-r--r--net/ipv4/netfilter/ip_tables.c144
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/tcp_input.c4
-rw-r--r--net/ipv4/xfrm4_policy.c2
13 files changed, 120 insertions, 113 deletions
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 107bb6cbb0b3..648f47c1c399 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -45,8 +45,8 @@
#include "fib_lookup.h"
-static kmem_cache_t *fn_hash_kmem __read_mostly;
-static kmem_cache_t *fn_alias_kmem __read_mostly;
+static struct kmem_cache *fn_hash_kmem __read_mostly;
+static struct kmem_cache *fn_alias_kmem __read_mostly;
struct fib_node {
struct hlist_node fn_hash;
@@ -485,13 +485,13 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
goto out;
err = -ENOBUFS;
- new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL);
+ new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
if (new_fa == NULL)
goto out;
new_f = NULL;
if (!f) {
- new_f = kmem_cache_alloc(fn_hash_kmem, SLAB_KERNEL);
+ new_f = kmem_cache_alloc(fn_hash_kmem, GFP_KERNEL);
if (new_f == NULL)
goto out_free_new_fa;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index d17990ec724f..cfb249cc0a58 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -172,7 +172,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn);
static struct tnode *halve(struct trie *t, struct tnode *tn);
static void tnode_free(struct tnode *tn);
-static kmem_cache_t *fn_alias_kmem __read_mostly;
+static struct kmem_cache *fn_alias_kmem __read_mostly;
static struct trie *trie_local = NULL, *trie_main = NULL;
@@ -1187,7 +1187,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
u8 state;
err = -ENOBUFS;
- new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL);
+ new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
if (new_fa == NULL)
goto out;
@@ -1232,7 +1232,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
goto out;
err = -ENOBUFS;
- new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL);
+ new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
if (new_fa == NULL)
goto out;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 244c4f445c7d..8c79c8a4ea5c 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -27,11 +27,11 @@
* Allocate and initialize a new local port bind bucket.
* The bindhash mutex for snum's hash chain must be held here.
*/
-struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep,
+struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
struct inet_bind_hashbucket *head,
const unsigned short snum)
{
- struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, SLAB_ATOMIC);
+ struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
if (tb != NULL) {
tb->port = snum;
@@ -45,7 +45,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep,
/*
* Caller must hold hashbucket lock for this tb with local BH disabled
*/
-void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb)
+void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket *tb)
{
if (hlist_empty(&tb->owners)) {
__hlist_del(&tb->node);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 8c74f9168b7d..9f414e35c488 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -91,7 +91,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
{
struct inet_timewait_sock *tw =
kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab,
- SLAB_ATOMIC);
+ GFP_ATOMIC);
if (tw != NULL) {
const struct inet_sock *inet = inet_sk(sk);
@@ -178,7 +178,6 @@ void inet_twdr_hangman(unsigned long data)
need_timer = 0;
if (inet_twdr_do_twkill_work(twdr, twdr->slot)) {
twdr->thread_slots |= (1 << twdr->slot);
- mb();
schedule_work(&twdr->twkill_work);
need_timer = 1;
} else {
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index f072f3875af8..711eb6d0285a 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -73,7 +73,7 @@
/* Exported for inet_getid inline function. */
DEFINE_SPINLOCK(inet_peer_idlock);
-static kmem_cache_t *peer_cachep __read_mostly;
+static struct kmem_cache *peer_cachep __read_mostly;
#define node_height(x) x->avl_height
static struct inet_peer peer_fake_node = {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index efcf45ecc818..ecb5422ea237 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -105,7 +105,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
In this case data path is free of exclusive locks at all.
*/
-static kmem_cache_t *mrt_cachep __read_mostly;
+static struct kmem_cache *mrt_cachep __read_mostly;
static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local);
static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert);
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 8832eb517d52..8086787a2c51 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -44,7 +44,7 @@
static struct list_head *ip_vs_conn_tab;
/* SLAB cache for IPVS connections */
-static kmem_cache_t *ip_vs_conn_cachep __read_mostly;
+static struct kmem_cache *ip_vs_conn_cachep __read_mostly;
/* counter for current IPVS connections */
static atomic_t ip_vs_conn_count = ATOMIC_INIT(0);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 413c2d0a1f3d..71b76ade00e1 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -375,6 +375,13 @@ static int mark_source_chains(struct xt_table_info *newinfo,
&& unconditional(&e->arp)) {
unsigned int oldpos, size;
+ if (t->verdict < -NF_MAX_VERDICT - 1) {
+ duprintf("mark_source_chains: bad "
+ "negative verdict (%i)\n",
+ t->verdict);
+ return 0;
+ }
+
/* Return: backtrack through the last
* big jump.
*/
@@ -404,6 +411,14 @@ static int mark_source_chains(struct xt_table_info *newinfo,
if (strcmp(t->target.u.user.name,
ARPT_STANDARD_TARGET) == 0
&& newpos >= 0) {
+ if (newpos > newinfo->size -
+ sizeof(struct arpt_entry)) {
+ duprintf("mark_source_chains: "
+ "bad verdict (%i)\n",
+ newpos);
+ return 0;
+ }
+
/* This a jump; chase it. */
duprintf("Jump rule %u -> %u\n",
pos, newpos);
@@ -426,8 +441,6 @@ static int mark_source_chains(struct xt_table_info *newinfo,
static inline int standard_check(const struct arpt_entry_target *t,
unsigned int max_offset)
{
- struct arpt_standard_target *targ = (void *)t;
-
/* Check standard info. */
if (t->u.target_size
!= ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
@@ -437,18 +450,6 @@ static inline int standard_check(const struct arpt_entry_target *t,
return 0;
}
- if (targ->verdict >= 0
- && targ->verdict > max_offset - sizeof(struct arpt_entry)) {
- duprintf("arpt_standard_check: bad verdict (%i)\n",
- targ->verdict);
- return 0;
- }
-
- if (targ->verdict < -NF_MAX_VERDICT - 1) {
- duprintf("arpt_standard_check: bad negative verdict (%i)\n",
- targ->verdict);
- return 0;
- }
return 1;
}
@@ -627,18 +628,20 @@ static int translate_table(const char *name,
}
}
+ if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
+ duprintf("Looping hook\n");
+ return -ELOOP;
+ }
+
/* Finally, each sanity check must pass */
i = 0;
ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
check_entry, name, size, &i);
- if (ret != 0)
- goto cleanup;
-
- ret = -ELOOP;
- if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
- duprintf("Looping hook\n");
- goto cleanup;
+ if (ret != 0) {
+ ARPT_ENTRY_ITERATE(entry0, newinfo->size,
+ cleanup_entry, &i);
+ return ret;
}
/* And one copy for every other CPU */
@@ -647,9 +650,6 @@ static int translate_table(const char *name,
memcpy(newinfo->entries[i], entry0, newinfo->size);
}
- return 0;
-cleanup:
- ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
return ret;
}
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index f4b0e68a16d2..8556a4f4f60a 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -65,8 +65,8 @@ static LIST_HEAD(helpers);
unsigned int ip_conntrack_htable_size __read_mostly = 0;
int ip_conntrack_max __read_mostly;
struct list_head *ip_conntrack_hash __read_mostly;
-static kmem_cache_t *ip_conntrack_cachep __read_mostly;
-static kmem_cache_t *ip_conntrack_expect_cachep __read_mostly;
+static struct kmem_cache *ip_conntrack_cachep __read_mostly;
+static struct kmem_cache *ip_conntrack_expect_cachep __read_mostly;
struct ip_conntrack ip_conntrack_untracked;
unsigned int ip_ct_log_invalid __read_mostly;
static LIST_HEAD(unconfirmed);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 8a455439b128..0ff2956d35e5 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -401,6 +401,13 @@ mark_source_chains(struct xt_table_info *newinfo,
&& unconditional(&e->ip)) {
unsigned int oldpos, size;
+ if (t->verdict < -NF_MAX_VERDICT - 1) {
+ duprintf("mark_source_chains: bad "
+ "negative verdict (%i)\n",
+ t->verdict);
+ return 0;
+ }
+
/* Return: backtrack through the last
big jump. */
do {
@@ -438,6 +445,13 @@ mark_source_chains(struct xt_table_info *newinfo,
if (strcmp(t->target.u.user.name,
IPT_STANDARD_TARGET) == 0
&& newpos >= 0) {
+ if (newpos > newinfo->size -
+ sizeof(struct ipt_entry)) {
+ duprintf("mark_source_chains: "
+ "bad verdict (%i)\n",
+ newpos);
+ return 0;
+ }
/* This a jump; chase it. */
duprintf("Jump rule %u -> %u\n",
pos, newpos);
@@ -470,27 +484,6 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
}
static inline int
-standard_check(const struct ipt_entry_target *t,
- unsigned int max_offset)
-{
- struct ipt_standard_target *targ = (void *)t;
-
- /* Check standard info. */
- if (targ->verdict >= 0
- && targ->verdict > max_offset - sizeof(struct ipt_entry)) {
- duprintf("ipt_standard_check: bad verdict (%i)\n",
- targ->verdict);
- return 0;
- }
- if (targ->verdict < -NF_MAX_VERDICT - 1) {
- duprintf("ipt_standard_check: bad negative verdict (%i)\n",
- targ->verdict);
- return 0;
- }
- return 1;
-}
-
-static inline int
check_match(struct ipt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
@@ -576,12 +569,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
if (ret)
goto err;
- if (t->u.kernel.target == &ipt_standard_target) {
- if (!standard_check(t, size)) {
- ret = -EINVAL;
- goto err;
- }
- } else if (t->u.kernel.target->checkentry
+ if (t->u.kernel.target->checkentry
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
e->comefrom)) {
duprintf("ip_tables: check failed for `%s'.\n",
@@ -718,17 +706,19 @@ translate_table(const char *name,
}
}
+ if (!mark_source_chains(newinfo, valid_hooks, entry0))
+ return -ELOOP;
+
/* Finally, each sanity check must pass */
i = 0;
ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
check_entry, name, size, &i);
- if (ret != 0)
- goto cleanup;
-
- ret = -ELOOP;
- if (!mark_source_chains(newinfo, valid_hooks, entry0))
- goto cleanup;
+ if (ret != 0) {
+ IPT_ENTRY_ITERATE(entry0, newinfo->size,
+ cleanup_entry, &i);
+ return ret;
+ }
/* And one copy for every other CPU */
for_each_possible_cpu(i) {
@@ -736,9 +726,6 @@ translate_table(const char *name,
memcpy(newinfo->entries[i], entry0, newinfo->size);
}
- return 0;
-cleanup:
- IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
return ret;
}
@@ -1529,25 +1516,8 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
void **dstptr, compat_uint_t *size, const char *name,
const struct ipt_ip *ip, unsigned int hookmask)
{
- struct ipt_entry_match *dm;
- struct ipt_match *match;
- int ret;
-
- dm = (struct ipt_entry_match *)*dstptr;
- match = m->u.kernel.match;
xt_compat_match_from_user(m, dstptr, size);
-
- ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
- name, hookmask, ip->proto,
- ip->invflags & IPT_INV_PROTO);
- if (!ret && m->u.kernel.match->checkentry
- && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
- hookmask)) {
- duprintf("ip_tables: check failed for `%s'.\n",
- m->u.kernel.match->name);
- ret = -EINVAL;
- }
- return ret;
+ return 0;
}
static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
@@ -1569,7 +1539,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
name, &de->ip, de->comefrom);
if (ret)
- goto err;
+ return ret;
de->target_offset = e->target_offset - (origsize - *size);
t = ipt_get_target(e);
target = t->u.kernel.target;
@@ -1582,31 +1552,62 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
if ((unsigned char *)de - base < newinfo->underflow[h])
newinfo->underflow[h] -= origsize - *size;
}
+ return ret;
+}
+
+static inline int compat_check_match(struct ipt_entry_match *m, const char *name,
+ const struct ipt_ip *ip, unsigned int hookmask)
+{
+ struct ipt_match *match;
+ int ret;
+
+ match = m->u.kernel.match;
+ ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
+ name, hookmask, ip->proto,
+ ip->invflags & IPT_INV_PROTO);
+ if (!ret && m->u.kernel.match->checkentry
+ && !m->u.kernel.match->checkentry(name, ip, match, m->data,
+ hookmask)) {
+ duprintf("ip_tables: compat: check failed for `%s'.\n",
+ m->u.kernel.match->name);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static inline int compat_check_target(struct ipt_entry *e, const char *name)
+{
+ struct ipt_entry_target *t;
+ struct ipt_target *target;
+ int ret;
- t = ipt_get_target(de);
+ t = ipt_get_target(e);
target = t->u.kernel.target;
ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
name, e->comefrom, e->ip.proto,
e->ip.invflags & IPT_INV_PROTO);
- if (ret)
- goto err;
-
- ret = -EINVAL;
- if (t->u.kernel.target == &ipt_standard_target) {
- if (!standard_check(t, *size))
- goto err;
- } else if (t->u.kernel.target->checkentry
- && !t->u.kernel.target->checkentry(name, de, target,
- t->data, de->comefrom)) {
+ if (!ret && t->u.kernel.target->checkentry
+ && !t->u.kernel.target->checkentry(name, e, target,
+ t->data, e->comefrom)) {
duprintf("ip_tables: compat: check failed for `%s'.\n",
t->u.kernel.target->name);
- goto err;
+ ret = -EINVAL;
}
- ret = 0;
-err:
return ret;
}
+static inline int compat_check_entry(struct ipt_entry *e, const char *name)
+{
+ int ret;
+
+ ret = IPT_MATCH_ITERATE(e, compat_check_match, name, &e->ip,
+ e->comefrom);
+ if (ret)
+ return ret;
+
+ return compat_check_target(e, name);
+}
+
static int
translate_compat_table(const char *name,
unsigned int valid_hooks,
@@ -1695,6 +1696,11 @@ translate_compat_table(const char *name,
if (!mark_source_chains(newinfo, valid_hooks, entry1))
goto free_newinfo;
+ ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
+ name);
+ if (ret)
+ goto free_newinfo;
+
/* And one copy for every other CPU */
for_each_possible_cpu(i)
if (newinfo->entries[i] && newinfo->entries[i] != entry1)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 9f3924c4905e..11c167118e87 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1780,7 +1780,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
#endif
if (in_dev->cnf.no_policy)
rth->u.dst.flags |= DST_NOPOLICY;
- if (in_dev->cnf.no_xfrm)
+ if (out_dev->cnf.no_xfrm)
rth->u.dst.flags |= DST_NOXFRM;
rth->fl.fl4_dst = daddr;
rth->rt_dst = daddr;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9304034c0c47..c701f6abbfc1 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4235,7 +4235,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
* Change state from SYN-SENT only after copied_seq
* is initialized. */
tp->copied_seq = tp->rcv_nxt;
- mb();
+ smp_mb();
tcp_set_state(sk, TCP_ESTABLISHED);
security_inet_conn_established(sk, skb);
@@ -4483,7 +4483,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
case TCP_SYN_RECV:
if (acceptable) {
tp->copied_seq = tp->rcv_nxt;
- mb();
+ smp_mb();
tcp_set_state(sk, TCP_ESTABLISHED);
sk->sk_state_change(sk);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index d4107bb701b5..fb9f69c616f5 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -274,6 +274,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
if (likely(xdst->u.rt.idev))
in_dev_put(xdst->u.rt.idev);
+ if (likely(xdst->u.rt.peer))
+ inet_putpeer(xdst->u.rt.peer);
xfrm_dst_destroy(xdst);
}