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 /net/9p | |
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>
Diffstat (limited to 'net/9p')
-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); |