diff options
author | Denis V. Lunev <den@openvz.org> | 2008-02-29 20:19:58 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-29 20:19:58 +0100 |
commit | 4a6ad7a141cbee2cf074e6cf8dc527b231b69ece (patch) | |
tree | f4edbb78969f6109874ea38d92464aa79cc74d3d /net | |
parent | [NETNS]: icmp(v6)_sk should not pin a namespace. (diff) | |
download | linux-4a6ad7a141cbee2cf074e6cf8dc527b231b69ece.tar.xz linux-4a6ad7a141cbee2cf074e6cf8dc527b231b69ece.zip |
[NETNS]: Make icmp_sk per namespace.
All preparations are done. Now just add a hook to perform an
initialization on namespace startup and replace icmp_sk macro with
proper inline call.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Acked-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/icmp.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 97d97ada4ce6..b51f4b0a3264 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -229,8 +229,10 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; * * On SMP we have one ICMP socket per-cpu. */ -static struct sock **__icmp_sk = NULL; -#define icmp_sk (__icmp_sk[smp_processor_id()]) +static struct sock *icmp_sk(struct net *net) +{ + return net->ipv4.icmp_sk[smp_processor_id()]; +} static inline int icmp_xmit_lock(struct sock *sk) { @@ -349,7 +351,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, struct sock *sk; struct sk_buff *skb; - sk = icmp_sk; + sk = icmp_sk(rt->u.dst.dev->nd_net); if (ip_append_data(sk, icmp_glue_bits, icmp_param, icmp_param->data_len+icmp_param->head_len, icmp_param->head_len, @@ -378,10 +380,11 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) { - struct sock *sk = icmp_sk; - struct inet_sock *inet = inet_sk(sk); struct ipcm_cookie ipc; struct rtable *rt = (struct rtable *)skb->dst; + struct net *net = rt->u.dst.dev->nd_net; + struct sock *sk = icmp_sk(net); + struct inet_sock *inet = inet_sk(sk); __be32 daddr; if (ip_options_echo(&icmp_param->replyopts, skb)) @@ -407,7 +410,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) .tos = RT_TOS(ip_hdr(skb)->tos) } }, .proto = IPPROTO_ICMP }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_key(rt->u.dst.dev->nd_net, &rt, &fl)) + if (ip_route_output_key(net, &rt, &fl)) goto out_unlock; } if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, @@ -440,11 +443,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) __be32 saddr; u8 tos; struct net *net; - struct sock *sk = icmp_sk; + struct sock *sk; if (!rt) goto out; net = rt->u.dst.dev->nd_net; + sk = icmp_sk(net); /* * Find the original header. It is expected to be valid, of course. @@ -1142,22 +1146,23 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { }, }; -static void __exit icmp_exit(void) +static void __net_exit icmp_sk_exit(struct net *net) { int i; for_each_possible_cpu(i) - sk_release_kernel(__icmp_sk[i]); - kfree(__icmp_sk); - __icmp_sk = NULL; + sk_release_kernel(net->ipv4.icmp_sk[i]); + kfree(net->ipv4.icmp_sk); + net->ipv4.icmp_sk = NULL; } -int __init icmp_init(void) +int __net_init icmp_sk_init(struct net *net) { int i, err; - __icmp_sk = kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL); - if (__icmp_sk == NULL) + net->ipv4.icmp_sk = + kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL); + if (net->ipv4.icmp_sk == NULL) return -ENOMEM; for_each_possible_cpu(i) { @@ -1169,8 +1174,8 @@ int __init icmp_init(void) if (err < 0) goto fail; - __icmp_sk[i] = sk = sock->sk; - sk_change_net(sk, &init_net); + net->ipv4.icmp_sk[i] = sk = sock->sk; + sk_change_net(sk, net); sk->sk_allocation = GFP_ATOMIC; @@ -1193,10 +1198,20 @@ int __init icmp_init(void) return 0; fail: - icmp_exit(); + icmp_sk_exit(net); return err; } +static struct pernet_operations __net_initdata icmp_sk_ops = { + .init = icmp_sk_init, + .exit = icmp_sk_exit, +}; + +int __init icmp_init(void) +{ + return register_pernet_device(&icmp_sk_ops); +} + EXPORT_SYMBOL(icmp_err_convert); EXPORT_SYMBOL(icmp_send); EXPORT_SYMBOL(icmp_statistics); |