Commit 7dc04d712203eecdc1435a4cd135935c4a297be5
Committed by
David S. Miller
1 parent
dd51be0f54
Exists in
master
and in
4 other branches
sctp: Add socket option operation for Auto-ASCONF.
This patch allows the application to operate Auto-ASCONF on/off behavior via setsockopt() and getsockopt(). Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Acked-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 69 additions and 0 deletions Side-by-side Diff
include/net/sctp/user.h
... | ... | @@ -92,6 +92,7 @@ |
92 | 92 | #define SCTP_LOCAL_AUTH_CHUNKS 27 /* Read only */ |
93 | 93 | #define SCTP_GET_ASSOC_NUMBER 28 /* Read only */ |
94 | 94 | #define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */ |
95 | +#define SCTP_AUTO_ASCONF 30 | |
95 | 96 | |
96 | 97 | /* Internal Socket Options. Some of the sctp library functions are |
97 | 98 | * implemented using these socket options. |
net/sctp/socket.c
... | ... | @@ -3356,7 +3356,47 @@ |
3356 | 3356 | |
3357 | 3357 | } |
3358 | 3358 | |
3359 | +/* | |
3360 | + * 8.1.23 SCTP_AUTO_ASCONF | |
3361 | + * | |
3362 | + * This option will enable or disable the use of the automatic generation of | |
3363 | + * ASCONF chunks to add and delete addresses to an existing association. Note | |
3364 | + * that this option has two caveats namely: a) it only affects sockets that | |
3365 | + * are bound to all addresses available to the SCTP stack, and b) the system | |
3366 | + * administrator may have an overriding control that turns the ASCONF feature | |
3367 | + * off no matter what setting the socket option may have. | |
3368 | + * This option expects an integer boolean flag, where a non-zero value turns on | |
3369 | + * the option, and a zero value turns off the option. | |
3370 | + * Note. In this implementation, socket operation overrides default parameter | |
3371 | + * being set by sysctl as well as FreeBSD implementation | |
3372 | + */ | |
3373 | +static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, | |
3374 | + unsigned int optlen) | |
3375 | +{ | |
3376 | + int val; | |
3377 | + struct sctp_sock *sp = sctp_sk(sk); | |
3359 | 3378 | |
3379 | + if (optlen < sizeof(int)) | |
3380 | + return -EINVAL; | |
3381 | + if (get_user(val, (int __user *)optval)) | |
3382 | + return -EFAULT; | |
3383 | + if (!sctp_is_ep_boundall(sk) && val) | |
3384 | + return -EINVAL; | |
3385 | + if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf)) | |
3386 | + return 0; | |
3387 | + | |
3388 | + if (val == 0 && sp->do_auto_asconf) { | |
3389 | + list_del(&sp->auto_asconf_list); | |
3390 | + sp->do_auto_asconf = 0; | |
3391 | + } else if (val && !sp->do_auto_asconf) { | |
3392 | + list_add_tail(&sp->auto_asconf_list, | |
3393 | + &sctp_auto_asconf_splist); | |
3394 | + sp->do_auto_asconf = 1; | |
3395 | + } | |
3396 | + return 0; | |
3397 | +} | |
3398 | + | |
3399 | + | |
3360 | 3400 | /* API 6.2 setsockopt(), getsockopt() |
3361 | 3401 | * |
3362 | 3402 | * Applications use setsockopt() and getsockopt() to set or retrieve |
... | ... | @@ -3503,6 +3543,9 @@ |
3503 | 3543 | case SCTP_AUTH_DELETE_KEY: |
3504 | 3544 | retval = sctp_setsockopt_del_key(sk, optval, optlen); |
3505 | 3545 | break; |
3546 | + case SCTP_AUTO_ASCONF: | |
3547 | + retval = sctp_setsockopt_auto_asconf(sk, optval, optlen); | |
3548 | + break; | |
3506 | 3549 | default: |
3507 | 3550 | retval = -ENOPROTOOPT; |
3508 | 3551 | break; |
... | ... | @@ -5309,6 +5352,28 @@ |
5309 | 5352 | } |
5310 | 5353 | |
5311 | 5354 | /* |
5355 | + * 8.1.23 SCTP_AUTO_ASCONF | |
5356 | + * See the corresponding setsockopt entry as description | |
5357 | + */ | |
5358 | +static int sctp_getsockopt_auto_asconf(struct sock *sk, int len, | |
5359 | + char __user *optval, int __user *optlen) | |
5360 | +{ | |
5361 | + int val = 0; | |
5362 | + | |
5363 | + if (len < sizeof(int)) | |
5364 | + return -EINVAL; | |
5365 | + | |
5366 | + len = sizeof(int); | |
5367 | + if (sctp_sk(sk)->do_auto_asconf && sctp_is_ep_boundall(sk)) | |
5368 | + val = 1; | |
5369 | + if (put_user(len, optlen)) | |
5370 | + return -EFAULT; | |
5371 | + if (copy_to_user(optval, &val, len)) | |
5372 | + return -EFAULT; | |
5373 | + return 0; | |
5374 | +} | |
5375 | + | |
5376 | +/* | |
5312 | 5377 | * 8.2.6. Get the Current Identifiers of Associations |
5313 | 5378 | * (SCTP_GET_ASSOC_ID_LIST) |
5314 | 5379 | * |
... | ... | @@ -5491,6 +5556,9 @@ |
5491 | 5556 | break; |
5492 | 5557 | case SCTP_GET_ASSOC_ID_LIST: |
5493 | 5558 | retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen); |
5559 | + break; | |
5560 | + case SCTP_AUTO_ASCONF: | |
5561 | + retval = sctp_getsockopt_auto_asconf(sk, len, optval, optlen); | |
5494 | 5562 | break; |
5495 | 5563 | default: |
5496 | 5564 | retval = -ENOPROTOOPT; |