diff options
author | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2006-03-20 22:25:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-20 22:25:24 -0500 |
commit | 017487d7d1e905a5bb529f6a2bc8cf8ea14e2307 (patch) | |
tree | 6a68904ea48ccae0c4c17f7dc248831fd46bd3e6 /net/dccp | |
parent | e55d912f5b75723159348a7fc7692f869a86636a (diff) |
[DCCP]: Generalize dccp_v4_send_reset
Renaming it to dccp_send_reset and moving it from the ipv4 specific
code to the core dccp code.
This fixes some bugs in IPV6 where timers would send v4 resets, etc.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/dccp.h | 6 | ||||
-rw-r--r-- | net/dccp/input.c | 2 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 26 | ||||
-rw-r--r-- | net/dccp/output.c | 30 | ||||
-rw-r--r-- | net/dccp/timer.c | 2 |
5 files changed, 28 insertions, 38 deletions
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index f059541f5a1d..cd7c5d069ae4 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -235,9 +235,6 @@ extern void dccp_close(struct sock *sk, long timeout); | |||
235 | extern struct sk_buff *dccp_make_response(struct sock *sk, | 235 | extern struct sk_buff *dccp_make_response(struct sock *sk, |
236 | struct dst_entry *dst, | 236 | struct dst_entry *dst, |
237 | struct request_sock *req); | 237 | struct request_sock *req); |
238 | extern struct sk_buff *dccp_make_reset(struct sock *sk, | ||
239 | struct dst_entry *dst, | ||
240 | enum dccp_reset_codes code); | ||
241 | 238 | ||
242 | extern int dccp_connect(struct sock *sk); | 239 | extern int dccp_connect(struct sock *sk); |
243 | extern int dccp_disconnect(struct sock *sk, int flags); | 240 | extern int dccp_disconnect(struct sock *sk, int flags); |
@@ -264,8 +261,7 @@ extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, | |||
264 | extern int dccp_v4_checksum(const struct sk_buff *skb, | 261 | extern int dccp_v4_checksum(const struct sk_buff *skb, |
265 | const __be32 saddr, const __be32 daddr); | 262 | const __be32 saddr, const __be32 daddr); |
266 | 263 | ||
267 | extern int dccp_v4_send_reset(struct sock *sk, | 264 | extern int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code); |
268 | enum dccp_reset_codes code); | ||
269 | extern void dccp_send_close(struct sock *sk, const int active); | 265 | extern void dccp_send_close(struct sock *sk, const int active); |
270 | extern int dccp_invalid_packet(struct sk_buff *skb); | 266 | extern int dccp_invalid_packet(struct sk_buff *skb); |
271 | 267 | ||
diff --git a/net/dccp/input.c b/net/dccp/input.c index 67691a0592af..eac5178ce515 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -32,7 +32,7 @@ static void dccp_fin(struct sock *sk, struct sk_buff *skb) | |||
32 | 32 | ||
33 | static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb) | 33 | static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb) |
34 | { | 34 | { |
35 | dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED); | 35 | dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED); |
36 | dccp_fin(sk, skb); | 36 | dccp_fin(sk, skb); |
37 | dccp_set_state(sk, DCCP_CLOSED); | 37 | dccp_set_state(sk, DCCP_CLOSED); |
38 | sk_wake_async(sk, 1, POLL_HUP); | 38 | sk_wake_async(sk, 1, POLL_HUP); |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index f94286e46c42..3baf4c76a89d 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -457,32 +457,6 @@ void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) | |||
457 | 457 | ||
458 | EXPORT_SYMBOL_GPL(dccp_v4_send_check); | 458 | EXPORT_SYMBOL_GPL(dccp_v4_send_check); |
459 | 459 | ||
460 | int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code) | ||
461 | { | ||
462 | struct sk_buff *skb; | ||
463 | /* | ||
464 | * FIXME: what if rebuild_header fails? | ||
465 | * Should we be doing a rebuild_header here? | ||
466 | */ | ||
467 | int err = inet_sk_rebuild_header(sk); | ||
468 | |||
469 | if (err != 0) | ||
470 | return err; | ||
471 | |||
472 | skb = dccp_make_reset(sk, sk->sk_dst_cache, code); | ||
473 | if (skb != NULL) { | ||
474 | const struct inet_sock *inet = inet_sk(sk); | ||
475 | |||
476 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | ||
477 | err = ip_build_and_send_pkt(skb, sk, | ||
478 | inet->saddr, inet->daddr, NULL); | ||
479 | if (err == NET_XMIT_CN) | ||
480 | err = 0; | ||
481 | } | ||
482 | |||
483 | return err; | ||
484 | } | ||
485 | |||
486 | static inline u64 dccp_v4_init_sequence(const struct sock *sk, | 460 | static inline u64 dccp_v4_init_sequence(const struct sock *sk, |
487 | const struct sk_buff *skb) | 461 | const struct sk_buff *skb) |
488 | { | 462 | { |
diff --git a/net/dccp/output.c b/net/dccp/output.c index 0cc2bcf56522..9922d2696b9c 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -323,8 +323,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, | |||
323 | 323 | ||
324 | EXPORT_SYMBOL_GPL(dccp_make_response); | 324 | EXPORT_SYMBOL_GPL(dccp_make_response); |
325 | 325 | ||
326 | struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | 326 | static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, |
327 | const enum dccp_reset_codes code) | 327 | const enum dccp_reset_codes code) |
328 | 328 | ||
329 | { | 329 | { |
330 | struct dccp_hdr *dh; | 330 | struct dccp_hdr *dh; |
@@ -366,14 +366,34 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | |||
366 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dp->dccps_gsr); | 366 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dp->dccps_gsr); |
367 | 367 | ||
368 | dccp_hdr_reset(skb)->dccph_reset_code = code; | 368 | dccp_hdr_reset(skb)->dccph_reset_code = code; |
369 | 369 | inet_csk(sk)->icsk_af_ops->send_check(sk, skb->len, skb); | |
370 | dh->dccph_checksum = dccp_v4_checksum(skb, inet_sk(sk)->saddr, | ||
371 | inet_sk(sk)->daddr); | ||
372 | 370 | ||
373 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); | 371 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); |
374 | return skb; | 372 | return skb; |
375 | } | 373 | } |
376 | 374 | ||
375 | int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code) | ||
376 | { | ||
377 | /* | ||
378 | * FIXME: what if rebuild_header fails? | ||
379 | * Should we be doing a rebuild_header here? | ||
380 | */ | ||
381 | int err = inet_sk_rebuild_header(sk); | ||
382 | |||
383 | if (err == 0) { | ||
384 | struct sk_buff *skb = dccp_make_reset(sk, sk->sk_dst_cache, | ||
385 | code); | ||
386 | if (skb != NULL) { | ||
387 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | ||
388 | err = inet_csk(sk)->icsk_af_ops->queue_xmit(skb, 0); | ||
389 | if (err == NET_XMIT_CN) | ||
390 | err = 0; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | return err; | ||
395 | } | ||
396 | |||
377 | /* | 397 | /* |
378 | * Do all connect socket setups that can be done AF independent. | 398 | * Do all connect socket setups that can be done AF independent. |
379 | */ | 399 | */ |
diff --git a/net/dccp/timer.c b/net/dccp/timer.c index d7c786608ec6..5244415e5f18 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c | |||
@@ -31,7 +31,7 @@ static void dccp_write_err(struct sock *sk) | |||
31 | sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; | 31 | sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; |
32 | sk->sk_error_report(sk); | 32 | sk->sk_error_report(sk); |
33 | 33 | ||
34 | dccp_v4_send_reset(sk, DCCP_RESET_CODE_ABORTED); | 34 | dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED); |
35 | dccp_done(sk); | 35 | dccp_done(sk); |
36 | DCCP_INC_STATS_BH(DCCP_MIB_ABORTONTIMEOUT); | 36 | DCCP_INC_STATS_BH(DCCP_MIB_ABORTONTIMEOUT); |
37 | } | 37 | } |