diff options
author | David Howells <dhowells@redhat.com> | 2017-06-07 16:27:15 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2017-06-07 17:15:46 +0100 |
commit | 515559ca21713218595f3a4dad44a4e7eea2fcfb (patch) | |
tree | 120f6e8449b032b1d29d6ea123460c0fe8b8c82d | |
parent | 216fe8f021e33c36e3b27c49c9f1951f6b037d7f (diff) | |
download | op-kernel-dev-515559ca21713218595f3a4dad44a4e7eea2fcfb.zip op-kernel-dev-515559ca21713218595f3a4dad44a4e7eea2fcfb.tar.gz |
rxrpc: Provide a getsockopt call to query what cmsgs types are supported
Provide a getsockopt() call that can query what cmsg types are supported by
AF_RXRPC.
-rw-r--r-- | Documentation/networking/rxrpc.txt | 9 | ||||
-rw-r--r-- | include/linux/rxrpc.h | 24 | ||||
-rw-r--r-- | net/rxrpc/af_rxrpc.c | 30 |
3 files changed, 52 insertions, 11 deletions
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt index 18078e6..bce8e10 100644 --- a/Documentation/networking/rxrpc.txt +++ b/Documentation/networking/rxrpc.txt @@ -406,6 +406,10 @@ calls, to invoke certain actions and to report certain conditions. These are: future communication to that server and RXRPC_UPGRADE_SERVICE should no longer be set. +The symbol RXRPC__SUPPORTED is defined as one more than the highest control +message type supported. At run time this can be queried by means of the +RXRPC_SUPPORTED_CMSG socket option (see below). + ============== SOCKET OPTIONS @@ -459,6 +463,11 @@ AF_RXRPC sockets support a few socket options at the SOL_RXRPC level: must point to an array of two unsigned short ints. The first is the service ID to upgrade from and the second the service ID to upgrade to. + (*) RXRPC_SUPPORTED_CMSG + + This is a read-only option that writes an int into the buffer indicating + the highest control message type supported. + ======== SECURITY diff --git a/include/linux/rxrpc.h b/include/linux/rxrpc.h index 707910c..bdd3175 100644 --- a/include/linux/rxrpc.h +++ b/include/linux/rxrpc.h @@ -38,6 +38,7 @@ struct sockaddr_rxrpc { #define RXRPC_EXCLUSIVE_CONNECTION 3 /* Deprecated; use RXRPC_EXCLUSIVE_CALL instead */ #define RXRPC_MIN_SECURITY_LEVEL 4 /* minimum security level */ #define RXRPC_UPGRADEABLE_SERVICE 5 /* Upgrade service[0] -> service[1] */ +#define RXRPC_SUPPORTED_CMSG 6 /* Get highest supported control message type */ /* * RxRPC control messages @@ -45,16 +46,19 @@ struct sockaddr_rxrpc { * - terminal messages mean that a user call ID tag can be recycled * - s/r/- indicate whether these are applicable to sendmsg() and/or recvmsg() */ -#define RXRPC_USER_CALL_ID 1 /* sr: user call ID specifier */ -#define RXRPC_ABORT 2 /* sr: abort request / notification [terminal] */ -#define RXRPC_ACK 3 /* -r: [Service] RPC op final ACK received [terminal] */ -#define RXRPC_NET_ERROR 5 /* -r: network error received [terminal] */ -#define RXRPC_BUSY 6 /* -r: server busy received [terminal] */ -#define RXRPC_LOCAL_ERROR 7 /* -r: local error generated [terminal] */ -#define RXRPC_NEW_CALL 8 /* -r: [Service] new incoming call notification */ -#define RXRPC_ACCEPT 9 /* s-: [Service] accept request */ -#define RXRPC_EXCLUSIVE_CALL 10 /* s-: Call should be on exclusive connection */ -#define RXRPC_UPGRADE_SERVICE 11 /* s-: Request service upgrade for client call */ +enum rxrpc_cmsg_type { + RXRPC_USER_CALL_ID = 1, /* sr: user call ID specifier */ + RXRPC_ABORT = 2, /* sr: abort request / notification [terminal] */ + RXRPC_ACK = 3, /* -r: [Service] RPC op final ACK received [terminal] */ + RXRPC_NET_ERROR = 5, /* -r: network error received [terminal] */ + RXRPC_BUSY = 6, /* -r: server busy received [terminal] */ + RXRPC_LOCAL_ERROR = 7, /* -r: local error generated [terminal] */ + RXRPC_NEW_CALL = 8, /* -r: [Service] new incoming call notification */ + RXRPC_ACCEPT = 9, /* s-: [Service] accept request */ + RXRPC_EXCLUSIVE_CALL = 10, /* s-: Call should be on exclusive connection */ + RXRPC_UPGRADE_SERVICE = 11, /* s-: Request service upgrade for client call */ + RXRPC__SUPPORTED +}; /* * RxRPC security levels diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 0c4dc4a..44a52b8 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -582,6 +582,34 @@ error: } /* + * Get socket options. + */ +static int rxrpc_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *_optlen) +{ + int optlen; + + if (level != SOL_RXRPC) + return -EOPNOTSUPP; + + if (get_user(optlen, _optlen)) + return -EFAULT; + + switch (optname) { + case RXRPC_SUPPORTED_CMSG: + if (optlen < sizeof(int)) + return -ETOOSMALL; + if (put_user(RXRPC__SUPPORTED - 1, (int __user *)optval) || + put_user(sizeof(int), _optlen)) + return -EFAULT; + return 0; + + default: + return -EOPNOTSUPP; + } +} + +/* * permit an RxRPC socket to be polled */ static unsigned int rxrpc_poll(struct file *file, struct socket *sock, @@ -784,7 +812,7 @@ static const struct proto_ops rxrpc_rpc_ops = { .listen = rxrpc_listen, .shutdown = rxrpc_shutdown, .setsockopt = rxrpc_setsockopt, - .getsockopt = sock_no_getsockopt, + .getsockopt = rxrpc_getsockopt, .sendmsg = rxrpc_sendmsg, .recvmsg = rxrpc_recvmsg, .mmap = sock_no_mmap, |