Message ID | 20181001084320.32453-7-mmanning@vyatta.att-mail.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Series | vrf: allow simultaneous service instances in default and other VRFs | expand |
On 10/1/18 2:43 AM, Mike Manning wrote: > From: Duncan Eastoe <deastoe@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 <deastoe@vyatta.att-mail.com> > Signed-off-by: Mike Manning <mmanning@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)) >
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))