aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2006-03-20 22:25:24 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 22:25:24 -0500
commit017487d7d1e905a5bb529f6a2bc8cf8ea14e2307 (patch)
tree6a68904ea48ccae0c4c17f7dc248831fd46bd3e6 /net/dccp
parente55d912f5b75723159348a7fc7692f869a86636a (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.h6
-rw-r--r--net/dccp/input.c2
-rw-r--r--net/dccp/ipv4.c26
-rw-r--r--net/dccp/output.c30
-rw-r--r--net/dccp/timer.c2
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);
235extern struct sk_buff *dccp_make_response(struct sock *sk, 235extern 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);
238extern struct sk_buff *dccp_make_reset(struct sock *sk,
239 struct dst_entry *dst,
240 enum dccp_reset_codes code);
241 238
242extern int dccp_connect(struct sock *sk); 239extern int dccp_connect(struct sock *sk);
243extern int dccp_disconnect(struct sock *sk, int flags); 240extern int dccp_disconnect(struct sock *sk, int flags);
@@ -264,8 +261,7 @@ extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
264extern int dccp_v4_checksum(const struct sk_buff *skb, 261extern 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
267extern int dccp_v4_send_reset(struct sock *sk, 264extern int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code);
268 enum dccp_reset_codes code);
269extern void dccp_send_close(struct sock *sk, const int active); 265extern void dccp_send_close(struct sock *sk, const int active);
270extern int dccp_invalid_packet(struct sk_buff *skb); 266extern 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
33static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb) 33static 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
458EXPORT_SYMBOL_GPL(dccp_v4_send_check); 458EXPORT_SYMBOL_GPL(dccp_v4_send_check);
459 459
460int 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
486static inline u64 dccp_v4_init_sequence(const struct sock *sk, 460static 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
324EXPORT_SYMBOL_GPL(dccp_make_response); 324EXPORT_SYMBOL_GPL(dccp_make_response);
325 325
326struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, 326static 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
375int 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}