On Mon, Aug 15, 2016 at 4:39 PM, YOSHIFUJI Hideaki <hideaki.yoshif...@miraclelinux.com> wrote: > > > and then in the various sendmsg functions: > > > > if (!inet_check_bound_oif(sk, oif)) > > return -EINVAL; > > > > Yes, something like that.
There's another complication. inet6_bind and raw_bind take sin6_scope_id and assign it to sk_bound_dev_if: if (addr_len >= sizeof(struct sockaddr_in6) && addr->sin6_scope_id) { if (addr->sin6_scope_id != sk /* Override any existing binding, if another * one is supplied by user. */ sk->sk_bound_dev_if = addr->sin6_scope_id; } The reason they do this is that the only place in the socket to score the scope ID is sk_bound_dev_if. The scope ID has to be stored in the socket, because it's the only way to ensure the semantics of scoped addresses, where the address without the scope ID is not unique, and thus the scope ID is effectively part of the address. For example: 1. A socket bound to fe80::1%eth0 and a socket bound to fe80::1%wlan0 must never see each other's packets. This means that things like udp6_lib_lookup must take the scope ID into account. 2. Calling getpeername() on a socket that's bound to fe80::1%eth0 must return eth0's ifindex in sin6_scope_id. Unless we add a scope ID field to the socket, changing this behaviour would cause substantial breakage. It's perfectly legal to bind a socket to fe80::1%eth0 and then fe80::2%wlan0, for example. So we can't just say that sk_bound_dev_if must always take precedence on sin6_scope_id. I also don't see how the VRF behaviour where sk_bound_dev_if sets the master interface and pktinto selects the slave interface" can be made to work at all in the presence of scoped addresses. I don't see any way to support a socket bound to fe80::1%eth0 and a socket bound to fe80::1%wlan0 in the same VRF.