diff options
author | Pavel Emelyanov <xemul@parallels.com> | 2011-12-14 21:43:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-16 13:48:27 -0500 |
commit | f65c1b534b99aef1809b893387b295963821549f (patch) | |
tree | 0718e1598b4d01c4c1817a3c663a312616f0dddd | |
parent | aec8dc62f66199aef153d86e1f90d9c1d14696e3 (diff) |
sock_diag: Generalize requests cookies managements
The sk address is used as a cookie between dump/get_exact calls.
It will be required for unix socket sdumping, so move it from
inet_diag to sock_diag.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/inet_diag.h | 1 | ||||
-rw-r--r-- | include/linux/sock_diag.h | 3 | ||||
-rw-r--r-- | net/core/sock_diag.c | 19 | ||||
-rw-r--r-- | net/ipv4/inet_diag.c | 23 | ||||
-rw-r--r-- | net/ipv4/udp_diag.c | 2 |
5 files changed, 27 insertions, 21 deletions
diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index a27e62178d43..afa5d5c74169 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h | |||
@@ -168,7 +168,6 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, | |||
168 | struct inet_diag_req *req); | 168 | struct inet_diag_req *req); |
169 | 169 | ||
170 | int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); | 170 | int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); |
171 | int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req); | ||
172 | 171 | ||
173 | extern int inet_diag_register(const struct inet_diag_handler *handler); | 172 | extern int inet_diag_register(const struct inet_diag_handler *handler); |
174 | extern void inet_diag_unregister(const struct inet_diag_handler *handler); | 173 | extern void inet_diag_unregister(const struct inet_diag_handler *handler); |
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index 7999778ad08d..379d5dccf8e1 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h | |||
@@ -22,5 +22,8 @@ void sock_diag_unregister(struct sock_diag_handler *h); | |||
22 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); | 22 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); |
23 | void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); | 23 | void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)); |
24 | 24 | ||
25 | int sock_diag_check_cookie(void *sk, __u32 *cookie); | ||
26 | void sock_diag_save_cookie(void *sk, __u32 *cookie); | ||
27 | |||
25 | extern struct sock *sock_diag_nlsk; | 28 | extern struct sock *sock_diag_nlsk; |
26 | #endif | 29 | #endif |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index cee96f368108..711bdefe7753 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -12,6 +12,25 @@ static struct sock_diag_handler *sock_diag_handlers[AF_MAX]; | |||
12 | static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); | 12 | static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); |
13 | static DEFINE_MUTEX(sock_diag_table_mutex); | 13 | static DEFINE_MUTEX(sock_diag_table_mutex); |
14 | 14 | ||
15 | int sock_diag_check_cookie(void *sk, __u32 *cookie) | ||
16 | { | ||
17 | if ((cookie[0] != INET_DIAG_NOCOOKIE || | ||
18 | cookie[1] != INET_DIAG_NOCOOKIE) && | ||
19 | ((u32)(unsigned long)sk != cookie[0] || | ||
20 | (u32)((((unsigned long)sk) >> 31) >> 1) != cookie[1])) | ||
21 | return -ESTALE; | ||
22 | else | ||
23 | return 0; | ||
24 | } | ||
25 | EXPORT_SYMBOL_GPL(sock_diag_check_cookie); | ||
26 | |||
27 | void sock_diag_save_cookie(void *sk, __u32 *cookie) | ||
28 | { | ||
29 | cookie[0] = (u32)(unsigned long)sk; | ||
30 | cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1); | ||
31 | } | ||
32 | EXPORT_SYMBOL_GPL(sock_diag_save_cookie); | ||
33 | |||
15 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) | 34 | void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) |
16 | { | 35 | { |
17 | mutex_lock(&sock_diag_table_mutex); | 36 | mutex_lock(&sock_diag_table_mutex); |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index fa27313765f3..fb2e47ff59f7 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -102,8 +102,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
102 | r->idiag_retrans = 0; | 102 | r->idiag_retrans = 0; |
103 | 103 | ||
104 | r->id.idiag_if = sk->sk_bound_dev_if; | 104 | r->id.idiag_if = sk->sk_bound_dev_if; |
105 | r->id.idiag_cookie[0] = (u32)(unsigned long)sk; | 105 | sock_diag_save_cookie(sk, r->id.idiag_cookie); |
106 | r->id.idiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1); | ||
107 | 106 | ||
108 | r->id.idiag_sport = inet->inet_sport; | 107 | r->id.idiag_sport = inet->inet_sport; |
109 | r->id.idiag_dport = inet->inet_dport; | 108 | r->id.idiag_dport = inet->inet_dport; |
@@ -221,8 +220,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
221 | r->idiag_family = tw->tw_family; | 220 | r->idiag_family = tw->tw_family; |
222 | r->idiag_retrans = 0; | 221 | r->idiag_retrans = 0; |
223 | r->id.idiag_if = tw->tw_bound_dev_if; | 222 | r->id.idiag_if = tw->tw_bound_dev_if; |
224 | r->id.idiag_cookie[0] = (u32)(unsigned long)tw; | 223 | sock_diag_save_cookie(tw, r->id.idiag_cookie); |
225 | r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1); | ||
226 | r->id.idiag_sport = tw->tw_sport; | 224 | r->id.idiag_sport = tw->tw_sport; |
227 | r->id.idiag_dport = tw->tw_dport; | 225 | r->id.idiag_dport = tw->tw_dport; |
228 | r->id.idiag_src[0] = tw->tw_rcv_saddr; | 226 | r->id.idiag_src[0] = tw->tw_rcv_saddr; |
@@ -261,18 +259,6 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | |||
261 | return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh); | 259 | return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh); |
262 | } | 260 | } |
263 | 261 | ||
264 | int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req) | ||
265 | { | ||
266 | if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE || | ||
267 | req->id.idiag_cookie[1] != INET_DIAG_NOCOOKIE) && | ||
268 | ((u32)(unsigned long)sk != req->id.idiag_cookie[0] || | ||
269 | (u32)((((unsigned long)sk) >> 31) >> 1) != req->id.idiag_cookie[1])) | ||
270 | return -ESTALE; | ||
271 | else | ||
272 | return 0; | ||
273 | } | ||
274 | EXPORT_SYMBOL_GPL(inet_diag_check_cookie); | ||
275 | |||
276 | int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, | 262 | int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, |
277 | const struct nlmsghdr *nlh, struct inet_diag_req *req) | 263 | const struct nlmsghdr *nlh, struct inet_diag_req *req) |
278 | { | 264 | { |
@@ -304,7 +290,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s | |||
304 | if (sk == NULL) | 290 | if (sk == NULL) |
305 | goto out_nosk; | 291 | goto out_nosk; |
306 | 292 | ||
307 | err = inet_diag_check_cookie(sk, req); | 293 | err = sock_diag_check_cookie(sk, req->id.idiag_cookie); |
308 | if (err) | 294 | if (err) |
309 | goto out; | 295 | goto out; |
310 | 296 | ||
@@ -617,8 +603,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
617 | r->idiag_retrans = req->retrans; | 603 | r->idiag_retrans = req->retrans; |
618 | 604 | ||
619 | r->id.idiag_if = sk->sk_bound_dev_if; | 605 | r->id.idiag_if = sk->sk_bound_dev_if; |
620 | r->id.idiag_cookie[0] = (u32)(unsigned long)req; | 606 | sock_diag_save_cookie(req, r->id.idiag_cookie); |
621 | r->id.idiag_cookie[1] = (u32)(((unsigned long)req >> 31) >> 1); | ||
622 | 607 | ||
623 | tmo = req->expires - jiffies; | 608 | tmo = req->expires - jiffies; |
624 | if (tmo < 0) | 609 | if (tmo < 0) |
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index fe9db8675acb..69f8a7ca63dd 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c | |||
@@ -57,7 +57,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, | |||
57 | if (sk == NULL) | 57 | if (sk == NULL) |
58 | goto out_nosk; | 58 | goto out_nosk; |
59 | 59 | ||
60 | err = inet_diag_check_cookie(sk, req); | 60 | err = sock_diag_check_cookie(sk, req->id.idiag_cookie); |
61 | if (err) | 61 | if (err) |
62 | goto out; | 62 | goto out; |
63 | 63 | ||