diff options
| -rw-r--r-- | include/net/inet_timewait_sock.h | 1 | ||||
| -rw-r--r-- | include/net/net_namespace.h | 2 | ||||
| -rw-r--r-- | include/net/sock.h | 3 | ||||
| -rw-r--r-- | net/core/sock.c | 1 | ||||
| -rw-r--r-- | net/core/sock_diag.c | 12 | ||||
| -rw-r--r-- | net/ipv4/inet_timewait_sock.c | 1 |
6 files changed, 20 insertions, 0 deletions
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index f908dfc06..44975efe4 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -116,6 +116,7 @@ struct inet_timewait_sock { #define tw_dport __tw_common.skc_dport #define tw_num __tw_common.skc_num #define tw_portpair __tw_common.skc_portpair +#define tw_cookie __tw_common.skc_cookie int tw_timeout; volatile unsigned char tw_substate; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 0faaed2e2..b69e8e8d7 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -54,6 +54,8 @@ struct net { #endif spinlock_t rules_mod_lock; + atomic64_t cookie_gen; + struct list_head list; /* list of network namespaces */ struct list_head cleanup_list; /* namespaces on death row */ struct list_head exit_list; /* Use only net_mutex */ diff --git a/include/net/sock.h b/include/net/sock.h index 1fa662430..8d3d22ce2 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -192,6 +192,8 @@ struct sock_common { #ifdef CONFIG_NET_NS struct net *skc_net; #endif + atomic64_t skc_cookie; + /* * fields between dontcopy_begin/dontcopy_end * are not copied in sock_copy() @@ -306,6 +308,7 @@ struct sock { #define sk_bind_node __sk_common.skc_bind_node #define sk_prot __sk_common.skc_prot #define sk_net __sk_common.skc_net +#define sk_cookie __sk_common.skc_cookie socket_lock_t sk_lock; struct sk_buff_head sk_receive_queue; /* diff --git a/net/core/sock.c b/net/core/sock.c index 88900b4d9..ba8394b57 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1521,6 +1521,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) newsk->sk_err = 0; newsk->sk_err_soft = 0; newsk->sk_priority = 0; + atomic64_set(&newsk->sk_cookie, 0); /* * Before updating sk_refcnt, we must commit prior changes to memory * (Documentation/RCU/rculist_nulls.txt for details) diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 3f78978b2..3bd136463 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -13,6 +13,18 @@ static const struct sock_diag_handler *sock_diag_handlers[AF_MAX]; static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); static DEFINE_MUTEX(sock_diag_table_mutex); +static u64 sock_gen_cookie(struct sock *sk) +{ + while (1) { + u64 res = atomic64_read(&sk->sk_cookie); + + if (res) + return res; + res = atomic64_inc_return(&sock_net(sk)->cookie_gen); + atomic64_cmpxchg(&sk->sk_cookie, 0, res); + } +} + int sock_diag_check_cookie(void *sk, __u32 *cookie) { if ((cookie[0] != INET_DIAG_NOCOOKIE || diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 1f27c9f4a..d9e3b5b73 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c @@ -196,6 +196,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat tw->tw_ipv6only = 0; tw->tw_transparent = inet->transparent; tw->tw_prot = sk->sk_prot_creator; + atomic64_set(&tw->tw_cookie, atomic64_read(&sk->sk_cookie)); twsk_net_set(tw, hold_net(sock_net(sk))); /* * Because we use RCU lookups, we should not set tw_refcnt |
