Skip to content

Commit de45f97

Browse files
sowminivMukesh Kacker
authored andcommitted
Add setsockopt support for SO_RDS_TRANSPORT
An application may deterministically attach the underlying transport for a PF_RDS socket by invoking setsockopt(2) with the SO_RDS_TRANSPORT option at the SOL_RDS level. The integer argument to setsockopt must be one of the RDS_TRANS_* transport types, e.g., RDS_TRANS_TCP. The option must be specified before invoking bind(2) on the socket, and may only be used once on the socket. An attempt to set the option on a bound socket, or to invoke the option after a successful SO_RDS_TRANSPORT attachment, will return EOPNOTSUPP. Orabug: 21061146 Signed-off-by: Sowmini Varadhan <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Mukesh Kacker <[email protected]>
1 parent ac7ca8d commit de45f97

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

net/rds/af_rds.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,28 @@ static int rds_user_reset(struct rds_sock *rs, char __user *optval, int optlen)
330330
return 0;
331331
}
332332

333+
static int rds_set_transport(struct rds_sock *rs, char __user *optval,
334+
int optlen)
335+
{
336+
int t_type;
337+
338+
if (rs->rs_transport)
339+
return -EOPNOTSUPP; /* previously attached to transport */
340+
341+
if (optlen != sizeof(int))
342+
return -EINVAL;
343+
344+
if (copy_from_user(&t_type, (int __user *)optval, sizeof(t_type)))
345+
return -EFAULT;
346+
347+
if (t_type < 0 || t_type >= RDS_TRANS_COUNT)
348+
return -EINVAL;
349+
350+
rs->rs_transport = rds_trans_get(t_type);
351+
352+
return rs->rs_transport ? 0 : -ENOPROTOOPT;
353+
}
354+
333355
static int rds_setsockopt(struct socket *sock, int level, int optname,
334356
char __user *optval, unsigned int optlen)
335357
{
@@ -363,6 +385,11 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
363385
case RDS_CONN_RESET:
364386
ret = rds_user_reset(rs, optval, optlen);
365387
break;
388+
case SO_RDS_TRANSPORT:
389+
lock_sock(sock->sk);
390+
ret = rds_set_transport(rs, optval, optlen);
391+
release_sock(sock->sk);
392+
break;
366393
default:
367394
ret = -ENOPROTOOPT;
368395
}

net/rds/bind.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
197197
if (ret)
198198
goto out;
199199

200+
if (rs->rs_transport) { /* previously bound */
201+
ret = 0;
202+
goto out;
203+
}
200204
trans = rds_trans_get_preferred(sin->sin_addr.s_addr);
201205
if (!trans) {
202206
ret = -EADDRNOTAVAIL;

net/rds/rds.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ struct rds_transport *rds_trans_get_preferred(__be32 addr);
894894
void rds_trans_put(struct rds_transport *trans);
895895
unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
896896
unsigned int avail);
897+
struct rds_transport *rds_trans_get(int t_type);
897898
int rds_trans_init(void);
898899
void rds_trans_exit(void);
899900

net/rds/transport.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,27 @@ struct rds_transport *rds_trans_get_preferred(__be32 addr)
101101
return ret;
102102
}
103103

104+
struct rds_transport *rds_trans_get(int t_type)
105+
{
106+
struct rds_transport *ret = NULL;
107+
struct rds_transport *trans;
108+
unsigned int i;
109+
110+
down_read(&rds_trans_sem);
111+
for (i = 0; i < RDS_TRANS_COUNT; i++) {
112+
trans = transports[i];
113+
114+
if (trans && trans->t_type == t_type &&
115+
(!trans->t_owner || try_module_get(trans->t_owner))) {
116+
ret = trans;
117+
break;
118+
}
119+
}
120+
up_read(&rds_trans_sem);
121+
122+
return ret;
123+
}
124+
104125
/*
105126
* This returns the number of stats entries in the snapshot and only
106127
* copies them using the iter if there is enough space for them. The

0 commit comments

Comments
 (0)