Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c62adb7d authored by Bart Van Assche's avatar Bart Van Assche Committed by Doug Ledford
Browse files

IB/srp: Fix IPv6 address parsing



Split IPv6 addresses at the colon that separates the IPv6 address
and the port number instead of at a colon in the middle of the IPv6
address. Check whether the IPv6 address is surrounded with square
brackets.

Fixes: 19f31343 ("IB/srp: Add RDMA/CM support")
Signed-off-by: default avatarBart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 19b1f540
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -3414,18 +3414,37 @@ static const match_table_t srp_opt_tokens = {
	{ SRP_OPT_ERR,			NULL 			}
};

/**
 * srp_parse_in - parse an IP address and port number combination
 *
 * Parse the following address formats:
 * - IPv4: <ip_address>:<port>, e.g. 1.2.3.4:5.
 * - IPv6: \[<ipv6_address>\]:<port>, e.g. [1::2:3%4]:5.
 */
static int srp_parse_in(struct net *net, struct sockaddr_storage *sa,
			const char *addr_port_str)
{
	char *addr = kstrdup(addr_port_str, GFP_KERNEL);
	char *port_str = addr;
	char *addr_end, *addr = kstrdup(addr_port_str, GFP_KERNEL);
	char *port_str;
	int ret;

	if (!addr)
		return -ENOMEM;
	strsep(&port_str, ":");
	ret = inet_pton_with_scope(net, AF_UNSPEC, addr, port_str, sa);
	port_str = strrchr(addr, ':');
	if (!port_str)
		return -EINVAL;
	*port_str++ = '\0';
	ret = inet_pton_with_scope(net, AF_INET, addr, port_str, sa);
	if (ret && addr[0]) {
		addr_end = addr + strlen(addr) - 1;
		if (addr[0] == '[' && *addr_end == ']') {
			*addr_end = '\0';
			ret = inet_pton_with_scope(net, AF_INET6, addr + 1,
						   port_str, sa);
		}
	}
	kfree(addr);
	pr_debug("%s -> %pISpfsc\n", addr_port_str, sa);
	return ret;
}