diff options
author | Sage Weil <sage@newdream.net> | 2010-07-08 09:54:52 -0700 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-07-09 15:00:18 -0700 |
commit | 39139f64e14684cf2370770deb79d929d27cfd9b (patch) | |
tree | 7ea80cd49b3afd0816eacf7fbf191647c44d5661 /fs/ceph/messenger.c | |
parent | d06dbaf6c2c7187938f3f6745d9e4938a2d0ec47 (diff) | |
download | linux-3.10-39139f64e14684cf2370770deb79d929d27cfd9b.tar.gz linux-3.10-39139f64e14684cf2370770deb79d929d27cfd9b.tar.bz2 linux-3.10-39139f64e14684cf2370770deb79d929d27cfd9b.zip |
ceph: fix parsing of ipv6 addresses
Check for brackets around the ipv6 address to avoid ambiguity with the port
number.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/messenger.c')
-rw-r--r-- | fs/ceph/messenger.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index e8c5a2d0e88..3ddef155645 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -997,19 +997,32 @@ int ceph_parse_ips(const char *c, const char *end, struct sockaddr_in *in4 = (void *)ss; struct sockaddr_in6 *in6 = (void *)ss; int port; + char delim = ','; + + if (*p == '[') { + delim = ']'; + p++; + } memset(ss, 0, sizeof(*ss)); if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr, - ',', &ipend)) { + delim, &ipend)) ss->ss_family = AF_INET; - } else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, - ',', &ipend)) { + else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, + delim, &ipend)) ss->ss_family = AF_INET6; - } else { + else goto bad; - } p = ipend; + if (delim == ']') { + if (*p != ']') { + dout("missing matching ']'\n"); + goto bad; + } + p++; + } + /* port? */ if (p < end && *p == ':') { port = 0; @@ -1043,7 +1056,7 @@ int ceph_parse_ips(const char *c, const char *end, return 0; bad: - pr_err("parse_ips bad ip '%s'\n", c); + pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c); return -EINVAL; } |