diff options
| author | Dominique Martinet <dominique.martinet@cea.fr> | 2015-01-09 07:07:00 -0500 |
|---|---|---|
| committer | Eric Van Hensbergen <ericvh@gmail.com> | 2015-03-21 22:32:33 -0400 |
| commit | f569d3ef8254d4b3b8daa4f131f9397d48bf296c (patch) | |
| tree | 7dd31bd87ffb0e7a0bf63fb09d4a9046974c0a46 | |
| parent | 5c4086b8de6989f10ae814f5746604fc44a02a21 (diff) | |
net/9p: add a privport option for RDMA transport.
RDMA can use the same kind of weak security as TCP by checking the
client can bind to a privileged port, which is better than nothing
if TAUTH isn't implemented.
Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
| -rw-r--r-- | net/9p/trans_rdma.c | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 14ad43b5cf89..3533d2a53ab6 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
| @@ -139,6 +139,7 @@ struct p9_rdma_opts { | |||
| 139 | int sq_depth; | 139 | int sq_depth; |
| 140 | int rq_depth; | 140 | int rq_depth; |
| 141 | long timeout; | 141 | long timeout; |
| 142 | int privport; | ||
| 142 | }; | 143 | }; |
| 143 | 144 | ||
| 144 | /* | 145 | /* |
| @@ -146,7 +147,10 @@ struct p9_rdma_opts { | |||
| 146 | */ | 147 | */ |
| 147 | enum { | 148 | enum { |
| 148 | /* Options that take integer arguments */ | 149 | /* Options that take integer arguments */ |
| 149 | Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout, Opt_err, | 150 | Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout, |
| 151 | /* Options that take no argument */ | ||
| 152 | Opt_privport, | ||
| 153 | Opt_err, | ||
| 150 | }; | 154 | }; |
| 151 | 155 | ||
| 152 | static match_table_t tokens = { | 156 | static match_table_t tokens = { |
| @@ -154,6 +158,7 @@ static match_table_t tokens = { | |||
| 154 | {Opt_sq_depth, "sq=%u"}, | 158 | {Opt_sq_depth, "sq=%u"}, |
| 155 | {Opt_rq_depth, "rq=%u"}, | 159 | {Opt_rq_depth, "rq=%u"}, |
| 156 | {Opt_timeout, "timeout=%u"}, | 160 | {Opt_timeout, "timeout=%u"}, |
| 161 | {Opt_privport, "privport"}, | ||
| 157 | {Opt_err, NULL}, | 162 | {Opt_err, NULL}, |
| 158 | }; | 163 | }; |
| 159 | 164 | ||
| @@ -175,6 +180,7 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 175 | opts->sq_depth = P9_RDMA_SQ_DEPTH; | 180 | opts->sq_depth = P9_RDMA_SQ_DEPTH; |
| 176 | opts->rq_depth = P9_RDMA_RQ_DEPTH; | 181 | opts->rq_depth = P9_RDMA_RQ_DEPTH; |
| 177 | opts->timeout = P9_RDMA_TIMEOUT; | 182 | opts->timeout = P9_RDMA_TIMEOUT; |
| 183 | opts->privport = 0; | ||
| 178 | 184 | ||
| 179 | if (!params) | 185 | if (!params) |
| 180 | return 0; | 186 | return 0; |
| @@ -193,13 +199,13 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 193 | if (!*p) | 199 | if (!*p) |
| 194 | continue; | 200 | continue; |
| 195 | token = match_token(p, tokens, args); | 201 | token = match_token(p, tokens, args); |
| 196 | if (token == Opt_err) | 202 | if ((token != Opt_err) && (token != Opt_privport)) { |
| 197 | continue; | 203 | r = match_int(&args[0], &option); |
| 198 | r = match_int(&args[0], &option); | 204 | if (r < 0) { |
| 199 | if (r < 0) { | 205 | p9_debug(P9_DEBUG_ERROR, |
| 200 | p9_debug(P9_DEBUG_ERROR, | 206 | "integer field, but no integer?\n"); |
| 201 | "integer field, but no integer?\n"); | 207 | continue; |
| 202 | continue; | 208 | } |
| 203 | } | 209 | } |
| 204 | switch (token) { | 210 | switch (token) { |
| 205 | case Opt_port: | 211 | case Opt_port: |
| @@ -214,6 +220,9 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
| 214 | case Opt_timeout: | 220 | case Opt_timeout: |
| 215 | opts->timeout = option; | 221 | opts->timeout = option; |
| 216 | break; | 222 | break; |
| 223 | case Opt_privport: | ||
| 224 | opts->privport = 1; | ||
| 225 | break; | ||
| 217 | default: | 226 | default: |
| 218 | continue; | 227 | continue; |
| 219 | } | 228 | } |
| @@ -607,6 +616,23 @@ static int rdma_cancelled(struct p9_client *client, struct p9_req_t *req) | |||
| 607 | return 0; | 616 | return 0; |
| 608 | } | 617 | } |
| 609 | 618 | ||
| 619 | static int p9_rdma_bind_privport(struct p9_trans_rdma *rdma) | ||
| 620 | { | ||
| 621 | struct sockaddr_in cl = { | ||
| 622 | .sin_family = AF_INET, | ||
| 623 | .sin_addr.s_addr = htonl(INADDR_ANY), | ||
| 624 | }; | ||
| 625 | int port, err = -EINVAL; | ||
| 626 | |||
| 627 | for (port = P9_DEF_MAX_RESVPORT; port >= P9_DEF_MIN_RESVPORT; port--) { | ||
| 628 | cl.sin_port = htons((ushort)port); | ||
| 629 | err = rdma_bind_addr(rdma->cm_id, (struct sockaddr *)&cl); | ||
| 630 | if (err != -EADDRINUSE) | ||
| 631 | break; | ||
| 632 | } | ||
| 633 | return err; | ||
| 634 | } | ||
| 635 | |||
| 610 | /** | 636 | /** |
| 611 | * trans_create_rdma - Transport method for creating atransport instance | 637 | * trans_create_rdma - Transport method for creating atransport instance |
| 612 | * @client: client instance | 638 | * @client: client instance |
| @@ -642,6 +668,16 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args) | |||
| 642 | /* Associate the client with the transport */ | 668 | /* Associate the client with the transport */ |
| 643 | client->trans = rdma; | 669 | client->trans = rdma; |
| 644 | 670 | ||
| 671 | /* Bind to a privileged port if we need to */ | ||
| 672 | if (opts.privport) { | ||
| 673 | err = p9_rdma_bind_privport(rdma); | ||
| 674 | if (err < 0) { | ||
| 675 | pr_err("%s (%d): problem binding to privport: %d\n", | ||
| 676 | __func__, task_pid_nr(current), -err); | ||
| 677 | goto error; | ||
| 678 | } | ||
| 679 | } | ||
| 680 | |||
| 645 | /* Resolve the server's address */ | 681 | /* Resolve the server's address */ |
| 646 | rdma->addr.sin_family = AF_INET; | 682 | rdma->addr.sin_family = AF_INET; |
| 647 | rdma->addr.sin_addr.s_addr = in_aton(addr); | 683 | rdma->addr.sin_addr.s_addr = in_aton(addr); |
