aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/proto.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2006-11-10 14:43:06 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:22:09 -0500
commit6f4e5fff1e4d46714ea554fd83e44eab534e8b11 (patch)
tree4b14344fd825bbcefb6e8514e98e3e796b2dc1bd /net/dccp/proto.c
parenta11d206d0f88e092419877c7f706cafb5e1c2e57 (diff)
[DCCP]: Support for partial checksums (RFC 4340, sec. 9.2)
This patch does the following: a) introduces variable-length checksums as specified in [RFC 4340, sec. 9.2] b) provides necessary socket options and documentation as to how to use them c) basic support and infrastructure for the Minimum Checksum Coverage feature [RFC 4340, sec. 9.2.1]: acceptability tests, user notification and user interface In addition, it (1) fixes two bugs in the DCCPv4 checksum computation: * pseudo-header used checksum_len instead of skb->len * incorrect checksum coverage calculation based on dccph_x (2) removes dccp_v4_verify_checksum() since it reduplicates code of the checksum computation; code calling this function is updated accordingly. (3) now uses skb_checksum(), which is safer than checksum_partial() if the sk_buff has is a non-linear buffer (has pages attached to it). (4) fixes an outstanding TODO item: * If P.CsCov is too large for the packet size, drop packet and return. The code has been tested with applications, the latest version of tcpdump now comes with support for partial DCCP checksums. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r--net/dccp/proto.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 047d170a363a..db54e557eff1 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -472,7 +472,6 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
472 case DCCP_SOCKOPT_PACKET_SIZE: 472 case DCCP_SOCKOPT_PACKET_SIZE:
473 dp->dccps_packet_size = val; 473 dp->dccps_packet_size = val;
474 break; 474 break;
475
476 case DCCP_SOCKOPT_CHANGE_L: 475 case DCCP_SOCKOPT_CHANGE_L:
477 if (optlen != sizeof(struct dccp_so_feat)) 476 if (optlen != sizeof(struct dccp_so_feat))
478 err = -EINVAL; 477 err = -EINVAL;
@@ -481,7 +480,6 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
481 (struct dccp_so_feat __user *) 480 (struct dccp_so_feat __user *)
482 optval); 481 optval);
483 break; 482 break;
484
485 case DCCP_SOCKOPT_CHANGE_R: 483 case DCCP_SOCKOPT_CHANGE_R:
486 if (optlen != sizeof(struct dccp_so_feat)) 484 if (optlen != sizeof(struct dccp_so_feat))
487 err = -EINVAL; 485 err = -EINVAL;
@@ -490,12 +488,26 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
490 (struct dccp_so_feat __user *) 488 (struct dccp_so_feat __user *)
491 optval); 489 optval);
492 break; 490 break;
493 491 case DCCP_SOCKOPT_SEND_CSCOV: /* sender side, RFC 4340, sec. 9.2 */
492 if (val < 0 || val > 15)
493 err = -EINVAL;
494 else
495 dp->dccps_pcslen = val;
496 break;
497 case DCCP_SOCKOPT_RECV_CSCOV: /* receiver side, RFC 4340 sec. 9.2.1 */
498 if (val < 0 || val > 15)
499 err = -EINVAL;
500 else {
501 dp->dccps_pcrlen = val;
502 /* FIXME: add feature negotiation,
503 * ChangeL(MinimumChecksumCoverage, val) */
504 }
505 break;
494 default: 506 default:
495 err = -ENOPROTOOPT; 507 err = -ENOPROTOOPT;
496 break; 508 break;
497 } 509 }
498 510
499 release_sock(sk); 511 release_sock(sk);
500 return err; 512 return err;
501} 513}
@@ -575,6 +587,12 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
575 case DCCP_SOCKOPT_SERVICE: 587 case DCCP_SOCKOPT_SERVICE:
576 return dccp_getsockopt_service(sk, len, 588 return dccp_getsockopt_service(sk, len,
577 (__be32 __user *)optval, optlen); 589 (__be32 __user *)optval, optlen);
590 case DCCP_SOCKOPT_SEND_CSCOV:
591 val = dp->dccps_pcslen;
592 break;
593 case DCCP_SOCKOPT_RECV_CSCOV:
594 val = dp->dccps_pcrlen;
595 break;
578 case 128 ... 191: 596 case 128 ... 191:
579 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, 597 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
580 len, (u32 __user *)optval, optlen); 598 len, (u32 __user *)optval, optlen);