From c7926cda7ec704bdf701a5717693a4f7d11aaf48 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 3 Feb 2016 08:13:25 -0800 Subject: [PATCH] RDS: Add UUID socket option UUID is opaque user application data to be stored per socket connection. IB transport makes use of it for the ACL based message filtering. Orabug: 23222944 Signed-off-by: Yuval Shaia Signed-off-by: Bang Ngyen Signed-off-by: Santosh Shilimkar --- include/uapi/linux/rds.h | 11 +++++++++++ net/rds/af_rds.c | 34 ++++++++++++++++++++++++++++++++++ net/rds/rds.h | 15 +++++++++++++++ net/rds/recv.c | 15 +++++++++++++++ 4 files changed, 75 insertions(+) diff --git a/include/uapi/linux/rds.h b/include/uapi/linux/rds.h index ce93edb7a1f9..513f05dd3593 100644 --- a/include/uapi/linux/rds.h +++ b/include/uapi/linux/rds.h @@ -67,6 +67,7 @@ #define RDS_GET_MR_FOR_DEST 7 #define RDS_CONN_RESET 8 #define SO_RDS_TRANSPORT 9 +#define RDS_CONFIG_UUID 11 /* supported values for SO_RDS_TRANSPORT */ #define RDS_TRANS_IB 0 @@ -146,6 +147,7 @@ struct rds_cmsg_rx_trace { #define RDS_CMSG_MASKED_ATOMIC_CSWP 9 #define RDS_CMSG_ASYNC_SEND 10 #define RDS_CMSG_RXPATH_LATENCY 11 +#define RDS_CMSG_UUID 12 #define RDS_INFO_FIRST 10000 #define RDS_INFO_COUNTERS 10000 @@ -345,11 +347,20 @@ struct rds_rdma_send_notify { int32_t status; }; +#define RDS_UUID_MAXLEN 64 +struct rds_uuid_args { + u_int8_t uuid[RDS_UUID_MAXLEN]; + unsigned int uuid_en; + unsigned int acl_en; + unsigned int drop_cnt; +}; + #define RDS_RDMA_SEND_SUCCESS 0 #define RDS_RDMA_REMOTE_ERROR 1 #define RDS_RDMA_SEND_CANCELED 2 #define RDS_RDMA_SEND_DROPPED 3 #define RDS_RDMA_SEND_OTHER_ERROR 4 +#define RDS_RDMA_SEND_ACCVIO 5 /* * Common set of flags for all RDMA related structs diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 4b3e728a4c3c..0f5ea17d5152 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -437,6 +437,34 @@ static int rds_recv_track_latency(struct rds_sock *rs, char __user *optval, } +static int rds_set_config_uuid(struct rds_sock *rs, char __user *optval, + int optlen) +{ + return rds_set_bool_option(&rs->rs_uuid_en, optval, optlen); +} + +static int rds_get_config_uuid(struct rds_sock *rs, char __user *optval, + int *optlen) +{ + struct rds_uuid_args args; + + memset(&args, 0, sizeof(args)); + args.uuid_en = rs->rs_uuid_en; + args.drop_cnt = rs->rs_uuid_drop_cnt; + if (rs->rs_conn) { + args.acl_en = rs->rs_conn->c_acl_en; + memcpy(args.uuid, rs->rs_conn->c_uuid, sizeof(args.uuid)); + } + + if (copy_to_user(optval, &args, sizeof(args))) + return -EFAULT; + + if (put_user(sizeof(args), optlen)) + return -EFAULT; + + return 0; +} + static int rds_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { @@ -483,6 +511,9 @@ static int rds_setsockopt(struct socket *sock, int level, int optname, case SO_RDS_MSG_RXPATH_LATENCY: ret = rds_recv_track_latency(rs, optval, optlen); break; + case RDS_CONFIG_UUID: + ret = rds_set_config_uuid(rs, optval, optlen); + break; default: ret = -ENOPROTOOPT; } @@ -534,6 +565,9 @@ static int rds_getsockopt(struct socket *sock, int level, int optname, else ret = 0; break; + case RDS_CONFIG_UUID: + ret = rds_get_config_uuid(rs, optval, optlen); + break; default: break; } diff --git a/net/rds/rds.h b/net/rds/rds.h index 7237bc58fb9d..5499e15aaf3c 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -288,6 +288,10 @@ struct rds_connection { enum rds_conn_drop_src c_drop_source; struct list_head c_laddr_node; + + unsigned char c_acl_init; + unsigned char c_acl_en; + u_int8_t c_uuid[RDS_UUID_MAXLEN]; }; static inline @@ -494,6 +498,7 @@ struct rds_message { u64 m_ack_seq; __be32 m_daddr; unsigned long m_flags; + unsigned int m_status; /* Never access m_rs without holding m_rs_lock. * Lock nesting is @@ -561,6 +566,10 @@ struct rds_message { unsigned int op_dmaoff; struct scatterlist *op_sg; } data; + struct rm_uuid_op { + u_int8_t value[RDS_UUID_MAXLEN]; + u_int8_t enable; + } uuid; }; }; @@ -718,6 +727,12 @@ struct rds_sock { /* Socket receive path trace points*/ u8 rs_rx_traces; u8 rs_rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX]; + + /* UUID specific fields */ + unsigned char rs_uuid_en; + unsigned int rs_uuid_drop_cnt; + unsigned int rs_uuid_sent_cnt; + unsigned int rs_uuid_recv_cnt; }; static inline struct rds_sock *rds_sk_to_rs(const struct sock *sk) diff --git a/net/rds/recv.c b/net/rds/recv.c index 67509dea2735..90b665be6d4a 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -773,6 +773,21 @@ out: return ret; } +static int rds_cmsg_uuid(struct rds_sock *rs, struct rds_incoming *inc, + struct msghdr *msghdr) +{ + struct rds_uuid_args args; + + if (!inc->i_conn->c_acl_en || !rs->rs_uuid_en) + return 0; + + memcpy(args.uuid, inc->i_conn->c_uuid, sizeof(inc->i_conn->c_uuid)); + args.acl_en = inc->i_conn->c_acl_en; + args.uuid_en = rs->rs_uuid_en; + + return put_cmsg(msghdr, SOL_RDS, RDS_CMSG_UUID, sizeof(args), &args); +} + int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int msg_flags) { -- 2.50.1