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>

Sage Weil 39139f64 d06dbaf6

+19 -6
+19 -6
fs/ceph/messenger.c
··· 997 struct sockaddr_in *in4 = (void *)ss; 998 struct sockaddr_in6 *in6 = (void *)ss; 999 int port; 1000 1001 memset(ss, 0, sizeof(*ss)); 1002 if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr, 1003 - ',', &ipend)) { 1004 ss->ss_family = AF_INET; 1005 - } else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, 1006 - ',', &ipend)) { 1007 ss->ss_family = AF_INET6; 1008 - } else { 1009 goto bad; 1010 - } 1011 p = ipend; 1012 1013 /* port? */ 1014 if (p < end && *p == ':') { ··· 1056 return 0; 1057 1058 bad: 1059 - pr_err("parse_ips bad ip '%s'\n", c); 1060 return -EINVAL; 1061 } 1062
··· 997 struct sockaddr_in *in4 = (void *)ss; 998 struct sockaddr_in6 *in6 = (void *)ss; 999 int port; 1000 + char delim = ','; 1001 + 1002 + if (*p == '[') { 1003 + delim = ']'; 1004 + p++; 1005 + } 1006 1007 memset(ss, 0, sizeof(*ss)); 1008 if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr, 1009 + delim, &ipend)) 1010 ss->ss_family = AF_INET; 1011 + else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, 1012 + delim, &ipend)) 1013 ss->ss_family = AF_INET6; 1014 + else 1015 goto bad; 1016 p = ipend; 1017 + 1018 + if (delim == ']') { 1019 + if (*p != ']') { 1020 + dout("missing matching ']'\n"); 1021 + goto bad; 1022 + } 1023 + p++; 1024 + } 1025 1026 /* port? */ 1027 if (p < end && *p == ':') { ··· 1043 return 0; 1044 1045 bad: 1046 + pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c); 1047 return -EINVAL; 1048 } 1049