-
-
Notifications
You must be signed in to change notification settings - Fork 52
Description
With TCP and IPv6 link-local addresses, it is required to specify the outgoing interface:
mptcp_net-next/net/ipv6/tcp_ipv6.c
Lines 191 to 206 in 1302d43
| if (addr_type&IPV6_ADDR_LINKLOCAL) { | |
| if (addr_len >= sizeof(struct sockaddr_in6) && | |
| usin->sin6_scope_id) { | |
| /* If interface is set while binding, indices | |
| * must coincide. | |
| */ | |
| if (!sk_dev_equal_l3scope(sk, usin->sin6_scope_id)) | |
| return -EINVAL; | |
| sk->sk_bound_dev_if = usin->sin6_scope_id; | |
| } | |
| /* Connect to link-local address requires an interface */ | |
| if (!sk->sk_bound_dev_if) | |
| return -EINVAL; | |
| } |
On the userspace side, getaddrinfo(fd, "fe80::(...)%<IFACE>", ...) will fill sin6_scope_id field in the returned struct sockaddr_in6 *ai_addr address thanks to the give <IFACE>.
When using the in-kernel PM, the outgoing interface will be set when endpoints are added with dev <IFACE>. This is good when subflow, fullmesh and / or laminar flags are set. But if there are no endpoints with a laminar flag (or a fullmesh flag, or the C-flag exception with subflow endpoints), the routing rules will be used to determine the source IP, and no outgoing interface will be set. In other words, when an ADD_ADDR containing a link-local address is received, and if the in-kernel PM will doesn't have appropriated endpoints, the in-kernel will not be able to establish new subflows (see the MPJoinSynTx* MIB counters with nstat).
I think the proper solution is to use laminar (or fullmesh) endpoints for this.
If we want to have a solution relying on the routing rules, the in-kernel PM will need to do a lookup before the connect() (only when the remote address is a link-local address). Do we want to do that?
Note: linked to discussions from #587