Skip to content

in-kernel PM: not established paths when used with IPv6 link-local addresses #591

@matttbe

Description

@matttbe

With TCP and IPv6 link-local addresses, it is required to specify the outgoing interface:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions