]> Pileus Git - ~andy/linux/blobdiff - net/ipv6/ipv6_sockglue.c
[Syncookies]: Add support for TCP options via timestamps.
[~andy/linux] / net / ipv6 / ipv6_sockglue.c
index dc6695cc5767a140722e2ee46f4ed5df52d4f0b9..99624109c01026dd8e9f826582d36319df492caa 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/sockios.h>
 #include <linux/net.h>
 #include <linux/in6.h>
+#include <linux/mroute6.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/init.h>
@@ -107,7 +108,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                    char __user *optval, int optlen)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct net *net = sk->sk_net;
+       struct net *net = sock_net(sk);
        int val, valbool;
        int retv = -ENOPROTOOPT;
 
@@ -118,6 +119,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 
        valbool = (val!=0);
 
+       if (ip6_mroute_opt(optname))
+               return ip6_mroute_setsockopt(sk, optname, optval, optlen);
+
        lock_sock(sk);
 
        switch (optname) {
@@ -155,10 +159,11 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 
                        if (sk->sk_protocol == IPPROTO_TCP) {
                                struct inet_connection_sock *icsk = inet_csk(sk);
+                               struct net *net = sock_net(sk);
 
                                local_bh_disable();
-                               sock_prot_inuse_add(sk->sk_prot, -1);
-                               sock_prot_inuse_add(&tcp_prot, 1);
+                               sock_prot_inuse_add(net, sk->sk_prot, -1);
+                               sock_prot_inuse_add(net, &tcp_prot, 1);
                                local_bh_enable();
                                sk->sk_prot = &tcp_prot;
                                icsk->icsk_af_ops = &ipv4_specific;
@@ -167,12 +172,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                                tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
                        } else {
                                struct proto *prot = &udp_prot;
+                               struct net *net = sock_net(sk);
 
                                if (sk->sk_protocol == IPPROTO_UDPLITE)
                                        prot = &udplite_prot;
                                local_bh_disable();
-                               sock_prot_inuse_add(sk->sk_prot, -1);
-                               sock_prot_inuse_add(prot, 1);
+                               sock_prot_inuse_add(net, sk->sk_prot, -1);
+                               sock_prot_inuse_add(net, prot, 1);
                                local_bh_enable();
                                sk->sk_prot = prot;
                                sk->sk_socket->ops = &inet_dgram_ops;
@@ -788,6 +794,9 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
        int len;
        int val;
 
+       if (ip6_mroute_opt(optname))
+               return ip6_mroute_getsockopt(sk, optname, optval, optlen);
+
        if (get_user(len, optlen))
                return -EFAULT;
        switch (optname) {