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 e29bbf914057..2cd56df44d8e 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -506,6 +506,36 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx) | |||
506 | return rc; | 506 | return rc; |
507 | } | 507 | } |
508 | 508 | ||
509 | static int dccp_setsockopt_ccid(struct sock *sk, int type, | ||
510 | char __user *optval, int optlen) | ||
511 | { | ||
512 | u8 *val; | ||
513 | int rc = 0; | ||
514 | |||
515 | if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS) | ||
516 | return -EINVAL; | ||
517 | |||
518 | val = kmalloc(optlen, GFP_KERNEL); | ||
519 | if (val == NULL) | ||
520 | return -ENOMEM; | ||
521 | |||
522 | if (copy_from_user(val, optval, optlen)) { | ||
523 | kfree(val); | ||
524 | return -EFAULT; | ||
525 | } | ||
526 | |||
527 | lock_sock(sk); | ||
528 | if (type == DCCP_SOCKOPT_TX_CCID || type == DCCP_SOCKOPT_CCID) | ||
529 | rc = dccp_feat_register_sp(sk, DCCPF_CCID, 1, val, optlen); | ||
530 | |||
531 | if (!rc && (type == DCCP_SOCKOPT_RX_CCID || type == DCCP_SOCKOPT_CCID)) | ||
532 | rc = dccp_feat_register_sp(sk, DCCPF_CCID, 0, val, optlen); | ||
533 | release_sock(sk); | ||
534 | |||
535 | kfree(val); | ||
536 | return rc; | ||
537 | } | ||
538 | |||
509 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | 539 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, |
510 | char __user *optval, int optlen) | 540 | char __user *optval, int optlen) |
511 | { | 541 | { |
@@ -520,6 +550,10 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
520 | case DCCP_SOCKOPT_CHANGE_R: | 550 | case DCCP_SOCKOPT_CHANGE_R: |
521 | DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n"); | 551 | DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n"); |
522 | return 0; | 552 | return 0; |
553 | case DCCP_SOCKOPT_CCID: | ||
554 | case DCCP_SOCKOPT_RX_CCID: | ||
555 | case DCCP_SOCKOPT_TX_CCID: | ||
556 | return dccp_setsockopt_ccid(sk, optname, optval, optlen); | ||
523 | } | 557 | } |
524 | 558 | ||
525 | if (optlen < (int)sizeof(int)) | 559 | if (optlen < (int)sizeof(int)) |