69
69
#include <linux/crypto.h>
70
70
#include <linux/scatterlist.h>
71
71
72
- /* Socket used for sending RSTs and ACKs */
73
- static struct socket * tcp6_socket ;
74
-
75
72
static void tcp_v6_send_reset (struct sock * sk , struct sk_buff * skb );
76
73
static void tcp_v6_reqsk_send_ack (struct sk_buff * skb , struct request_sock * req );
77
74
static 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
1072
* Underlying function will use this to retrieve the network
1076
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
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
1080
TCP_INC_STATS_BH (TCP_MIB_OUTSEGS );
1083
1081
TCP_INC_STATS_BH (TCP_MIB_OUTRSTS );
1084
1082
return ;
@@ -1175,9 +1173,10 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1175
1173
fl .fl_ip_sport = t1 -> source ;
1176
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
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
1180
TCP_INC_STATS_BH (TCP_MIB_OUTSEGS );
1182
1181
return ;
1183
1182
}
@@ -2198,6 +2197,31 @@ static struct inet_protosw tcpv6_protosw = {
2198
2197
INET_PROTOSW_ICSK ,
2199
2198
};
2200
2199
2200
+ static 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
+
2215
+ static void tcpv6_net_exit (struct net * net )
2216
+ {
2217
+ sk_release_kernel (net -> ipv6 .tcp_sk );
2218
+ }
2219
+
2220
+ static struct pernet_operations tcpv6_net_ops = {
2221
+ .init = tcpv6_net_init ,
2222
+ .exit = tcpv6_net_exit ,
2223
+ };
2224
+
2201
2225
int __init tcpv6_init (void )
2202
2226
{
2203
2227
int ret ;
@@ -2211,8 +2235,7 @@ int __init tcpv6_init(void)
2211
2235
if (ret )
2212
2236
goto out_tcpv6_protocol ;
2213
2237
2214
- ret = inet_csk_ctl_sock_create (& tcp6_socket , PF_INET6 ,
2215
- SOCK_RAW , IPPROTO_TCP );
2238
+ ret = register_pernet_subsys (& tcpv6_net_ops );
2216
2239
if (ret )
2217
2240
goto out_tcpv6_protosw ;
2218
2241
out :
@@ -2227,7 +2250,7 @@ int __init tcpv6_init(void)
2227
2250
2228
2251
void tcpv6_exit (void )
2229
2252
{
2230
- sock_release ( tcp6_socket );
2253
+ unregister_pernet_subsys ( & tcpv6_net_ops );
2231
2254
inet6_unregister_protosw (& tcpv6_protosw );
2232
2255
inet6_del_protocol (& tcpv6_protocol , IPPROTO_TCP );
2233
2256
}
0 commit comments