#include <linux/crypto.h>
#include <linux/scatterlist.h>
-/* Socket used for sending RSTs and ACKs */
-static struct socket *tcp6_socket;
-
static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
static void tcp_v6_send_check(struct sock *sk, int len,
hp = tcp_get_md5sig_pool();
if (!hp) {
- printk(KERN_WARNING "%s(): hash pool not found...\n", __FUNCTION__);
+ printk(KERN_WARNING "%s(): hash pool not found...\n", __func__);
goto clear_hash_noput;
}
bp = &hp->md5_blk.ip6;
/* Now store the hash into the packet */
err = crypto_hash_init(desc);
if (err) {
- printk(KERN_WARNING "%s(): hash_init failed\n", __FUNCTION__);
+ printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
goto clear_hash;
}
err = crypto_hash_update(desc, sg, nbytes);
if (err) {
- printk(KERN_WARNING "%s(): hash_update failed\n", __FUNCTION__);
+ printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
goto clear_hash;
}
err = crypto_hash_final(desc, md5_hash);
if (err) {
- printk(KERN_WARNING "%s(): hash_final failed\n", __FUNCTION__);
+ printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
goto clear_hash;
}
struct tcphdr *th = tcp_hdr(skb), *t1;
struct sk_buff *buff;
struct flowi fl;
+ struct net *net = skb->dst->dev->nd_net;
+ struct sock *ctl_sk = net->ipv6.tcp_sk;
unsigned int tot_len = sizeof(*th);
#ifdef CONFIG_TCP_MD5SIG
struct tcp_md5sig_key *key;
* Underlying function will use this to retrieve the network
* namespace
*/
- if (!ip6_dst_lookup(tcp6_socket->sk, &buff->dst, &fl)) {
+ if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
- ip6_xmit(tcp6_socket->sk, buff, &fl, NULL, 0);
+ ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
return;
struct tcphdr *th = tcp_hdr(skb), *t1;
struct sk_buff *buff;
struct flowi fl;
+ struct net *net = skb->dev->nd_net;
+ struct sock *ctl_sk = net->ipv6.tcp_sk;
unsigned int tot_len = sizeof(struct tcphdr);
__be32 *topt;
#ifdef CONFIG_TCP_MD5SIG
fl.fl_ip_sport = t1->source;
security_skb_classify_flow(skb, &fl);
- if (!ip6_dst_lookup(tcp6_socket->sk, &buff->dst, &fl)) {
+ if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
- ip6_xmit(tcp6_socket->sk, buff, &fl, NULL, 0);
+ ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
return;
}
.seq_fops = &tcp6_seq_fops,
};
-int __init tcp6_proc_init(void)
+int tcp6_proc_init(struct net *net)
{
- return tcp_proc_register(&tcp6_seq_afinfo);
+ return tcp_proc_register(net, &tcp6_seq_afinfo);
}
-void tcp6_proc_exit(void)
+void tcp6_proc_exit(struct net *net)
{
- tcp_proc_unregister(&tcp6_seq_afinfo);
+ tcp_proc_unregister(net, &tcp6_seq_afinfo);
}
#endif
INET_PROTOSW_ICSK,
};
+static int tcpv6_net_init(struct net *net)
+{
+ int err;
+ struct socket *sock;
+ struct sock *sk;
+
+ err = inet_csk_ctl_sock_create(&sock, PF_INET6, SOCK_RAW, IPPROTO_TCP);
+ if (err)
+ return err;
+
+ net->ipv6.tcp_sk = sk = sock->sk;
+ sk_change_net(sk, net);
+ return err;
+}
+
+static void tcpv6_net_exit(struct net *net)
+{
+ sk_release_kernel(net->ipv6.tcp_sk);
+}
+
+static struct pernet_operations tcpv6_net_ops = {
+ .init = tcpv6_net_init,
+ .exit = tcpv6_net_exit,
+};
+
int __init tcpv6_init(void)
{
int ret;
if (ret)
goto out_tcpv6_protocol;
- ret = inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6,
- SOCK_RAW, IPPROTO_TCP);
+ ret = register_pernet_subsys(&tcpv6_net_ops);
if (ret)
goto out_tcpv6_protosw;
out:
void tcpv6_exit(void)
{
- sock_release(tcp6_socket);
+ unregister_pernet_subsys(&tcpv6_net_ops);
inet6_unregister_protosw(&tcpv6_protosw);
inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
}