aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-07 14:16:02 -0500
committerDavid S. Miller <davem@davemloft.net>2008-03-07 14:16:02 -0500
commit93ec926b075d14bb7edcbc054e92199e9ad4ad1d (patch)
tree7899be4a1f6e45199e80a324a9e9af8b582b5fb3 /net
parent1762f7e88eb34f653b4a915be99a102e347dd45e (diff)
[NETNS][IPV6] tcp6 - make socket control per namespace
Instead of having a tcp6_socket global to all the namespace, there is tcp6 socket control per namespace. That is consistent with which namespace sent a RST and allows to pass the socket to the underlying function to retrieve the network namespace. Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: Benjamin Thery <benjamin.thery@bull.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/tcp_ipv6.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index b47cce8fea44..7954b4e99c4f 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -69,9 +69,6 @@
69#include <linux/crypto.h> 69#include <linux/crypto.h>
70#include <linux/scatterlist.h> 70#include <linux/scatterlist.h>
71 71
72/* Socket used for sending RSTs and ACKs */
73static struct socket *tcp6_socket;
74
75static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); 72static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
76static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); 73static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
77static void tcp_v6_send_check(struct sock *sk, int len, 74static void tcp_v6_send_check(struct sock *sk, int len,
@@ -1075,10 +1072,11 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1075 * Underlying function will use this to retrieve the network 1072 * Underlying function will use this to retrieve the network
1076 * namespace 1073 * namespace
1077 */ 1074 */
1078 if (!ip6_dst_lookup(tcp6_socket->sk, &buff->dst, &fl)) { 1075 if (!ip6_dst_lookup(init_net.ipv6.tcp_sk, &buff->dst, &fl)) {
1079 1076
1080 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 1077 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1081 ip6_xmit(tcp6_socket->sk, buff, &fl, NULL, 0); 1078 ip6_xmit(init_net.ipv6.tcp_sk,
1079 buff, &fl, NULL, 0);
1082 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1080 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
1083 TCP_INC_STATS_BH(TCP_MIB_OUTRSTS); 1081 TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
1084 return; 1082 return;
@@ -1175,9 +1173,10 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1175 fl.fl_ip_sport = t1->source; 1173 fl.fl_ip_sport = t1->source;
1176 security_skb_classify_flow(skb, &fl); 1174 security_skb_classify_flow(skb, &fl);
1177 1175
1178 if (!ip6_dst_lookup(tcp6_socket->sk, &buff->dst, &fl)) { 1176 if (!ip6_dst_lookup(init_net.ipv6.tcp_sk, &buff->dst, &fl)) {
1179 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 1177 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1180 ip6_xmit(tcp6_socket->sk, buff, &fl, NULL, 0); 1178 ip6_xmit(init_net.ipv6.tcp_sk,
1179 buff, &fl, NULL, 0);
1181 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 1180 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
1182 return; 1181 return;
1183 } 1182 }
@@ -2198,6 +2197,31 @@ static struct inet_protosw tcpv6_protosw = {
2198 INET_PROTOSW_ICSK, 2197 INET_PROTOSW_ICSK,
2199}; 2198};
2200 2199
2200static int tcpv6_net_init(struct net *net)
2201{
2202 int err;
2203 struct socket *sock;
2204 struct sock *sk;
2205
2206 err = inet_csk_ctl_sock_create(&sock, PF_INET6, SOCK_RAW, IPPROTO_TCP);
2207 if (err)
2208 return err;
2209
2210 net->ipv6.tcp_sk = sk = sock->sk;
2211 sk_change_net(sk, net);
2212 return err;
2213}
2214
2215static void tcpv6_net_exit(struct net *net)
2216{
2217 sk_release_kernel(net->ipv6.tcp_sk);
2218}
2219
2220static struct pernet_operations tcpv6_net_ops = {
2221 .init = tcpv6_net_init,
2222 .exit = tcpv6_net_exit,
2223};
2224
2201int __init tcpv6_init(void) 2225int __init tcpv6_init(void)
2202{ 2226{
2203 int ret; 2227 int ret;
@@ -2211,8 +2235,7 @@ int __init tcpv6_init(void)
2211 if (ret) 2235 if (ret)
2212 goto out_tcpv6_protocol; 2236 goto out_tcpv6_protocol;
2213 2237
2214 ret = inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, 2238 ret = register_pernet_subsys(&tcpv6_net_ops);
2215 SOCK_RAW, IPPROTO_TCP);
2216 if (ret) 2239 if (ret)
2217 goto out_tcpv6_protosw; 2240 goto out_tcpv6_protosw;
2218out: 2241out:
@@ -2227,7 +2250,7 @@ out_tcpv6_protosw:
2227 2250
2228void tcpv6_exit(void) 2251void tcpv6_exit(void)
2229{ 2252{
2230 sock_release(tcp6_socket); 2253 unregister_pernet_subsys(&tcpv6_net_ops);
2231 inet6_unregister_protosw(&tcpv6_protosw); 2254 inet6_unregister_protosw(&tcpv6_protosw);
2232 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); 2255 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2233} 2256}