diff options
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r-- | net/dccp/proto.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 8b63394ec24c..445884cf1c29 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -501,6 +501,36 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx) | |||
501 | return rc; | 501 | return rc; |
502 | } | 502 | } |
503 | 503 | ||
504 | static int dccp_setsockopt_ccid(struct sock *sk, int type, | ||
505 | char __user *optval, int optlen) | ||
506 | { | ||
507 | u8 *val; | ||
508 | int rc = 0; | ||
509 | |||
510 | if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS) | ||
511 | return -EINVAL; | ||
512 | |||
513 | val = kmalloc(optlen, GFP_KERNEL); | ||
514 | if (val == NULL) | ||
515 | return -ENOMEM; | ||
516 | |||
517 | if (copy_from_user(val, optval, optlen)) { | ||
518 | kfree(val); | ||
519 | return -EFAULT; | ||
520 | } | ||
521 | |||
522 | lock_sock(sk); | ||
523 | if (type == DCCP_SOCKOPT_TX_CCID || type == DCCP_SOCKOPT_CCID) | ||
524 | rc = dccp_feat_register_sp(sk, DCCPF_CCID, 1, val, optlen); | ||
525 | |||
526 | if (!rc && (type == DCCP_SOCKOPT_RX_CCID || type == DCCP_SOCKOPT_CCID)) | ||
527 | rc = dccp_feat_register_sp(sk, DCCPF_CCID, 0, val, optlen); | ||
528 | release_sock(sk); | ||
529 | |||
530 | kfree(val); | ||
531 | return rc; | ||
532 | } | ||
533 | |||
504 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | 534 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, |
505 | char __user *optval, int optlen) | 535 | char __user *optval, int optlen) |
506 | { | 536 | { |
@@ -515,6 +545,10 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
515 | case DCCP_SOCKOPT_CHANGE_R: | 545 | case DCCP_SOCKOPT_CHANGE_R: |
516 | DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n"); | 546 | DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n"); |
517 | return 0; | 547 | return 0; |
548 | case DCCP_SOCKOPT_CCID: | ||
549 | case DCCP_SOCKOPT_RX_CCID: | ||
550 | case DCCP_SOCKOPT_TX_CCID: | ||
551 | return dccp_setsockopt_ccid(sk, optname, optval, optlen); | ||
518 | } | 552 | } |
519 | 553 | ||
520 | if (optlen < (int)sizeof(int)) | 554 | if (optlen < (int)sizeof(int)) |