On 10/1/18 2:43 AM, Mike Manning wrote: > From: Duncan Eastoe <deas...@vyatta.att-mail.com> > > If setsockopt(IP_MULTICAST_IF) or setsockopt(IPV6_MULTICAST_IF) is > called on a socket which is not bound to a VRF then we should ensure > that the output device chosen is also not bound to a VRF master.
Why does it matter? An app can set IP_MULTICAST_IF on the socket in the same way it can set the device bind. This breaks existing apps. > > This avoids inadvertently sending traffic out of the wrong interface. > This can be particularly problematic for IP_MULTICAST_IF since the > interface lookup can be performed by address as well as ifindex. If > there are interfaces with the same address, one unbound and one bound > to a VRF, then the interface bound to the VRF may be chosen when the > sockopt is called on an unbound socket. > > Signed-off-by: Duncan Eastoe <deas...@vyatta.att-mail.com> > Signed-off-by: Mike Manning <mmann...@vyatta.att-mail.com> > --- > net/ipv4/ip_sockglue.c | 3 +++ > net/ipv6/ipv6_sockglue.c | 3 +++ > 2 files changed, 6 insertions(+) > > diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c > index c0fe5ad996f2..026971314c43 100644 > --- a/net/ipv4/ip_sockglue.c > +++ b/net/ipv4/ip_sockglue.c > @@ -892,6 +892,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, > dev_put(dev); > > err = -EINVAL; > + if (!sk->sk_bound_dev_if && midx) > + break; > + > if (sk->sk_bound_dev_if && > mreq.imr_ifindex != sk->sk_bound_dev_if && > (!midx || midx != sk->sk_bound_dev_if)) > diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c > index c0cac9cc3a28..7dfbc797b130 100644 > --- a/net/ipv6/ipv6_sockglue.c > +++ b/net/ipv6/ipv6_sockglue.c > @@ -626,6 +626,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, > int optname, > > rcu_read_unlock(); > > + if (!sk->sk_bound_dev_if && midx) > + goto e_inval; > + > if (sk->sk_bound_dev_if && > sk->sk_bound_dev_if != val && > (!midx || midx != sk->sk_bound_dev_if)) >