All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs
@ 2018-11-07 15:36 Mike Manning
  2018-11-07 15:36 ` [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket Mike Manning
                   ` (9 more replies)
  0 siblings, 10 replies; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev

Services currently have to be VRF-aware if they are using an unbound
socket. One cannot have multiple service instances running in the
default and other VRFs for services that are not VRF-aware and listen
on an unbound socket. This is because there is no easy way of isolating
packets received in the default VRF from those arriving in other VRFs.

This series provides this isolation for stream sockets subject to the
existing kernel parameter net.ipv4.tcp_l3mdev_accept not being set,
given that this is documented as allowing a single service instance to
work across all VRF domains. Similarly, net.ipv4.udp_l3mdev_accept is
checked for datagram sockets, and net.ipv4.raw_l3mdev_accept is
introduced for raw sockets. The functionality applies to UDP & TCP
services as well as those using raw sockets, and is for IPv4 and IPv6.

Example of running ssh instances in default and blue VRF:

$ /usr/sbin/sshd -D
$ ip vrf exec vrf-blue /usr/sbin/sshd
$ ss -ta | egrep 'State|ssh'
State   Recv-Q   Send-Q           Local Address:Port       Peer Address:Port
LISTEN  0        128           0.0.0.0%vrf-blue:ssh             0.0.0.0:*
LISTEN  0        128                    0.0.0.0:ssh             0.0.0.0:*
ESTAB   0        0              192.168.122.220:ssh       192.168.122.1:50282
LISTEN  0        128              [::]%vrf-blue:ssh                [::]:*
LISTEN  0        128                       [::]:ssh                [::]:*
ESTAB   0        0           [3000::2]%vrf-blue:ssh           [3000::9]:45896
ESTAB   0        0                    [2000::2]:ssh           [2000::9]:46398

v1:
   - Address Paolo Abeni's comments (patch 4/5)
   - Fix build when CONFIG_NET_L3_MASTER_DEV not defined (patch 1/5)
v2:
   - Address David Aherns' comments (patches 4/5 and 5/5)
   - Remove patches 3/5 and 5/5 from series for individual submissions
   - Include a sysctl for raw sockets as recommended by David Ahern
   - Expand series into 10 patches and provide improved descriptions
v3:
   - Update description for patch 1/10 and remove patch 6/10
v4:
   - Set default to enabled for raw socket sysctl as recommended by David Ahern
v5:
   - Address review comments from David Ahern in patches 2-5

Dewi Morgan (1):
  ipv6: do not drop vrf udp multicast packets

Duncan Eastoe (1):
  net: fix raw socket lookup device bind matching with VRFs

Mike Manning (6):
  net: ensure unbound stream socket to be chosen when not in a VRF
  net: ensure unbound datagram socket to be chosen when not in a VRF
  net: provide a sysctl raw_l3mdev_accept for raw socket lookup with
    VRFs
  vrf: mark skb for multicast or link-local as enslaved to VRF
  ipv6: allow ping to link-local address in VRF
  ipv6: handling of multicast packets received in VRF

Robert Shearman (1):
  net: allow binding socket in a VRF when there's an unbound socket

 Documentation/networking/ip-sysctl.txt | 12 ++++++++++++
 Documentation/networking/vrf.txt       | 22 +++++++++++++++++----
 drivers/net/vrf.c                      | 19 +++++++++---------
 include/net/inet6_hashtables.h         |  5 ++---
 include/net/inet_hashtables.h          | 24 ++++++++++++++++-------
 include/net/inet_sock.h                | 21 ++++++++++++++++++++
 include/net/netns/ipv4.h               |  3 +++
 include/net/raw.h                      | 14 +++++++++++++-
 include/net/udp.h                      | 11 +++++++++++
 net/core/sock.c                        |  2 ++
 net/ipv4/af_inet.c                     |  2 ++
 net/ipv4/inet_connection_sock.c        | 13 ++++++++++---
 net/ipv4/inet_hashtables.c             | 34 ++++++++++++++++++++-------------
 net/ipv4/raw.c                         | 31 ++++++++++++++++++++++++++----
 net/ipv4/sysctl_net_ipv4.c             | 11 +++++++++++
 net/ipv4/udp.c                         | 15 ++++++---------
 net/ipv6/datagram.c                    | 10 +++++++---
 net/ipv6/inet6_hashtables.c            | 14 ++++++--------
 net/ipv6/ip6_input.c                   | 35 +++++++++++++++++++++++++++++++---
 net/ipv6/ipv6_sockglue.c               |  2 +-
 net/ipv6/raw.c                         |  5 ++---
 net/ipv6/udp.c                         | 22 ++++++++++-----------
 22 files changed, 243 insertions(+), 84 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:06   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 2/9] net: ensure unbound stream socket to be chosen when not in a VRF Mike Manning
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev; +Cc: Robert Shearman

From: Robert Shearman <rshearma@vyatta.att-mail.com>

Change the inet socket lookup to avoid packets arriving on a device
enslaved to an l3mdev from matching unbound sockets by removing the
wildcard for non sk_bound_dev_if and instead relying on check against
the secondary device index, which will be 0 when the input device is
not enslaved to an l3mdev and so match against an unbound socket and
not match when the input device is enslaved.

Change the socket binding to take the l3mdev into account to allow an
unbound socket to not conflict sockets bound to an l3mdev given the
datapath isolation now guaranteed.

Signed-off-by: Robert Shearman <rshearma@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 Documentation/networking/vrf.txt |  9 +++++----
 include/net/inet6_hashtables.h   |  5 ++---
 include/net/inet_hashtables.h    | 13 ++++++-------
 include/net/inet_sock.h          | 13 +++++++++++++
 net/ipv4/inet_connection_sock.c  | 13 ++++++++++---
 net/ipv4/inet_hashtables.c       | 20 +++++++++++++++-----
 6 files changed, 51 insertions(+), 22 deletions(-)

diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt
index 8ff7b4c8f91b..d4b129402d57 100644
--- a/Documentation/networking/vrf.txt
+++ b/Documentation/networking/vrf.txt
@@ -103,6 +103,11 @@ VRF device:
 
 or to specify the output device using cmsg and IP_PKTINFO.
 
+By default the scope of the port bindings for unbound sockets is
+limited to the default VRF. That is, it will not be matched by packets
+arriving on interfaces enslaved to an l3mdev and processes may bind to
+the same port if they bind to an l3mdev.
+
 TCP & UDP services running in the default VRF context (ie., not bound
 to any VRF device) can work across all VRF domains by enabling the
 tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
@@ -112,10 +117,6 @@ tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
 netfilter rules on the VRF device can be used to limit access to services
 running in the default VRF context as well.
 
-The default VRF does not have limited scope with respect to port bindings.
-That is, if a process does a wildcard bind to a port in the default VRF it
-owns the port across all VRF domains within the network namespace.
-
 ################################################################################
 
 Using iproute2 for VRFs
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 6e91e38a31da..9db98af46985 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -115,9 +115,8 @@ int inet6_hash(struct sock *sk);
 	 ((__sk)->sk_family == AF_INET6)			&&	\
 	 ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr))		&&	\
 	 ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr))	&&	\
-	 (!(__sk)->sk_bound_dev_if	||				\
-	   ((__sk)->sk_bound_dev_if == (__dif))	||			\
-	   ((__sk)->sk_bound_dev_if == (__sdif)))		&&	\
+	 (((__sk)->sk_bound_dev_if == (__dif))	||			\
+	  ((__sk)->sk_bound_dev_if == (__sdif)))		&&	\
 	 net_eq(sock_net(__sk), (__net)))
 
 #endif /* _INET6_HASHTABLES_H */
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 9141e95529e7..4ae060b4bac2 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -79,6 +79,7 @@ struct inet_ehash_bucket {
 
 struct inet_bind_bucket {
 	possible_net_t		ib_net;
+	int			l3mdev;
 	unsigned short		port;
 	signed char		fastreuse;
 	signed char		fastreuseport;
@@ -191,7 +192,7 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
 struct inet_bind_bucket *
 inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
 			struct inet_bind_hashbucket *head,
-			const unsigned short snum);
+			const unsigned short snum, int l3mdev);
 void inet_bind_bucket_destroy(struct kmem_cache *cachep,
 			      struct inet_bind_bucket *tb);
 
@@ -282,9 +283,8 @@ static inline struct sock *inet_lookup_listener(struct net *net,
 #define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
 	(((__sk)->sk_portpair == (__ports))			&&	\
 	 ((__sk)->sk_addrpair == (__cookie))			&&	\
-	 (!(__sk)->sk_bound_dev_if	||				\
-	   ((__sk)->sk_bound_dev_if == (__dif))			||	\
-	   ((__sk)->sk_bound_dev_if == (__sdif)))		&&	\
+	 (((__sk)->sk_bound_dev_if == (__dif))			||	\
+	  ((__sk)->sk_bound_dev_if == (__sdif)))		&&	\
 	 net_eq(sock_net(__sk), (__net)))
 #else /* 32-bit arch */
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
@@ -294,9 +294,8 @@ static inline struct sock *inet_lookup_listener(struct net *net,
 	(((__sk)->sk_portpair == (__ports))		&&		\
 	 ((__sk)->sk_daddr	== (__saddr))		&&		\
 	 ((__sk)->sk_rcv_saddr	== (__daddr))		&&		\
-	 (!(__sk)->sk_bound_dev_if	||				\
-	   ((__sk)->sk_bound_dev_if == (__dif))		||		\
-	   ((__sk)->sk_bound_dev_if == (__sdif)))	&&		\
+	 (((__sk)->sk_bound_dev_if == (__dif))		||		\
+	  ((__sk)->sk_bound_dev_if == (__sdif)))	&&		\
 	 net_eq(sock_net(__sk), (__net)))
 #endif /* 64-bit arch */
 
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index a80fd0ac4563..ed3f723af00b 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -130,6 +130,19 @@ static inline int inet_request_bound_dev_if(const struct sock *sk,
 	return sk->sk_bound_dev_if;
 }
 
+static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+{
+#ifdef CONFIG_NET_L3_MASTER_DEV
+	struct net *net = sock_net(sk);
+
+	if (!net->ipv4.sysctl_tcp_l3mdev_accept)
+		return l3mdev_master_ifindex_by_index(net,
+						      sk->sk_bound_dev_if);
+#endif
+
+	return 0;
+}
+
 struct inet_cork {
 	unsigned int		flags;
 	__be32			addr;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 15e7f7915a21..5c63449130d9 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -183,7 +183,9 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
 	int i, low, high, attempt_half;
 	struct inet_bind_bucket *tb;
 	u32 remaining, offset;
+	int l3mdev;
 
+	l3mdev = inet_sk_bound_l3mdev(sk);
 	attempt_half = (sk->sk_reuse == SK_CAN_REUSE) ? 1 : 0;
 other_half_scan:
 	inet_get_local_port_range(net, &low, &high);
@@ -219,7 +221,8 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
 						  hinfo->bhash_size)];
 		spin_lock_bh(&head->lock);
 		inet_bind_bucket_for_each(tb, &head->chain)
-			if (net_eq(ib_net(tb), net) && tb->port == port) {
+			if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+			    tb->port == port) {
 				if (!inet_csk_bind_conflict(sk, tb, false, false))
 					goto success;
 				goto next_port;
@@ -293,6 +296,9 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
 	struct net *net = sock_net(sk);
 	struct inet_bind_bucket *tb = NULL;
 	kuid_t uid = sock_i_uid(sk);
+	int l3mdev;
+
+	l3mdev = inet_sk_bound_l3mdev(sk);
 
 	if (!port) {
 		head = inet_csk_find_open_port(sk, &tb, &port);
@@ -306,11 +312,12 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
 					  hinfo->bhash_size)];
 	spin_lock_bh(&head->lock);
 	inet_bind_bucket_for_each(tb, &head->chain)
-		if (net_eq(ib_net(tb), net) && tb->port == port)
+		if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+		    tb->port == port)
 			goto tb_found;
 tb_not_found:
 	tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
-				     net, head, port);
+				     net, head, port, l3mdev);
 	if (!tb)
 		goto fail_unlock;
 tb_found:
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index f5c9ef2586de..260531dc6458 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -65,12 +65,14 @@ static u32 sk_ehashfn(const struct sock *sk)
 struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
 						 struct net *net,
 						 struct inet_bind_hashbucket *head,
-						 const unsigned short snum)
+						 const unsigned short snum,
+						 int l3mdev)
 {
 	struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
 
 	if (tb) {
 		write_pnet(&tb->ib_net, net);
+		tb->l3mdev    = l3mdev;
 		tb->port      = snum;
 		tb->fastreuse = 0;
 		tb->fastreuseport = 0;
@@ -135,6 +137,7 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
 			table->bhash_size);
 	struct inet_bind_hashbucket *head = &table->bhash[bhash];
 	struct inet_bind_bucket *tb;
+	int l3mdev;
 
 	spin_lock(&head->lock);
 	tb = inet_csk(sk)->icsk_bind_hash;
@@ -143,6 +146,8 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
 		return -ENOENT;
 	}
 	if (tb->port != port) {
+		l3mdev = inet_sk_bound_l3mdev(sk);
+
 		/* NOTE: using tproxy and redirecting skbs to a proxy
 		 * on a different listener port breaks the assumption
 		 * that the listener socket's icsk_bind_hash is the same
@@ -150,12 +155,13 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
 		 * create a new bind bucket for the child here. */
 		inet_bind_bucket_for_each(tb, &head->chain) {
 			if (net_eq(ib_net(tb), sock_net(sk)) &&
-			    tb->port == port)
+			    tb->l3mdev == l3mdev && tb->port == port)
 				break;
 		}
 		if (!tb) {
 			tb = inet_bind_bucket_create(table->bind_bucket_cachep,
-						     sock_net(sk), head, port);
+						     sock_net(sk), head, port,
+						     l3mdev);
 			if (!tb) {
 				spin_unlock(&head->lock);
 				return -ENOMEM;
@@ -675,6 +681,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 	u32 remaining, offset;
 	int ret, i, low, high;
 	static u32 hint;
+	int l3mdev;
 
 	if (port) {
 		head = &hinfo->bhash[inet_bhashfn(net, port,
@@ -693,6 +700,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 		return ret;
 	}
 
+	l3mdev = inet_sk_bound_l3mdev(sk);
+
 	inet_get_local_port_range(net, &low, &high);
 	high++; /* [32768, 60999] -> [32768, 61000[ */
 	remaining = high - low;
@@ -719,7 +728,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 		 * the established check is already unique enough.
 		 */
 		inet_bind_bucket_for_each(tb, &head->chain) {
-			if (net_eq(ib_net(tb), net) && tb->port == port) {
+			if (net_eq(ib_net(tb), net) && tb->l3mdev == l3mdev &&
+			    tb->port == port) {
 				if (tb->fastreuse >= 0 ||
 				    tb->fastreuseport >= 0)
 					goto next_port;
@@ -732,7 +742,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 		}
 
 		tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
-					     net, head, port);
+					     net, head, port, l3mdev);
 		if (!tb) {
 			spin_unlock_bh(&head->lock);
 			return -ENOMEM;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 2/9] net: ensure unbound stream socket to be chosen when not in a VRF
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
  2018-11-07 15:36 ` [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:06   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 3/9] net: ensure unbound datagram " Mike Manning
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev

The commit a04a480d4392 ("net: Require exact match for TCP socket
lookups if dif is l3mdev") only ensures that the correct socket is
selected for packets in a VRF. However, there is no guarantee that
the unbound socket will be selected for packets when not in a VRF.
By checking for a device match in compute_score() also for the case
when there is no bound device and attaching a score to this, the
unbound socket is selected. And if a failure is returned when there
is no device match, this ensures that bound sockets are never selected,
even if there is no unbound socket.

Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 include/net/inet_hashtables.h | 11 +++++++++++
 include/net/inet_sock.h       |  8 ++++++++
 net/ipv4/inet_hashtables.c    | 14 ++++++--------
 net/ipv6/inet6_hashtables.c   | 14 ++++++--------
 4 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 4ae060b4bac2..0ce460e93dc4 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -189,6 +189,17 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
 	hashinfo->ehash_locks = NULL;
 }
 
+static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+					int dif, int sdif)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+	return inet_bound_dev_eq(!!net->ipv4.sysctl_tcp_l3mdev_accept,
+				 bound_dev_if, dif, sdif);
+#else
+	return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+#endif
+}
+
 struct inet_bind_bucket *
 inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
 			struct inet_bind_hashbucket *head,
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index ed3f723af00b..e8eef85006aa 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -143,6 +143,14 @@ static inline int inet_sk_bound_l3mdev(const struct sock *sk)
 	return 0;
 }
 
+static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if,
+				     int dif, int sdif)
+{
+	if (!bound_dev_if)
+		return !sdif || l3mdev_accept;
+	return bound_dev_if == dif || bound_dev_if == sdif;
+}
+
 struct inet_cork {
 	unsigned int		flags;
 	__be32			addr;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 260531dc6458..2ec684057ebd 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -235,6 +235,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
 {
 	int score = -1;
 	struct inet_sock *inet = inet_sk(sk);
+	bool dev_match;
 
 	if (net_eq(sock_net(sk), net) && inet->inet_num == hnum &&
 			!ipv6_only_sock(sk)) {
@@ -245,15 +246,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
 				return -1;
 			score += 4;
 		}
-		if (sk->sk_bound_dev_if || exact_dif) {
-			bool dev_match = (sk->sk_bound_dev_if == dif ||
-					  sk->sk_bound_dev_if == sdif);
+		dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+						 dif, sdif);
+		if (!dev_match)
+			return -1;
+		score += 4;
 
-			if (!dev_match)
-				return -1;
-			if (sk->sk_bound_dev_if)
-				score += 4;
-		}
 		if (sk->sk_incoming_cpu == raw_smp_processor_id())
 			score++;
 	}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 3d7c7460a0c5..5eeeba7181a1 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -99,6 +99,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
 				const int dif, const int sdif, bool exact_dif)
 {
 	int score = -1;
+	bool dev_match;
 
 	if (net_eq(sock_net(sk), net) && inet_sk(sk)->inet_num == hnum &&
 	    sk->sk_family == PF_INET6) {
@@ -109,15 +110,12 @@ static inline int compute_score(struct sock *sk, struct net *net,
 				return -1;
 			score++;
 		}
-		if (sk->sk_bound_dev_if || exact_dif) {
-			bool dev_match = (sk->sk_bound_dev_if == dif ||
-					  sk->sk_bound_dev_if == sdif);
+		dev_match = inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+						 dif, sdif);
+		if (!dev_match)
+			return -1;
+		score++;
 
-			if (!dev_match)
-				return -1;
-			if (sk->sk_bound_dev_if)
-				score++;
-		}
 		if (sk->sk_incoming_cpu == raw_smp_processor_id())
 			score++;
 	}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 3/9] net: ensure unbound datagram socket to be chosen when not in a VRF
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
  2018-11-07 15:36 ` [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket Mike Manning
  2018-11-07 15:36 ` [PATCH net-next v5 2/9] net: ensure unbound stream socket to be chosen when not in a VRF Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:06   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 4/9] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs Mike Manning
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev

Ensure an unbound datagram skt is chosen when not in a VRF. The check
for a device match in compute_score() for UDP must be performed when
there is no device match. For this, a failure is returned when there is
no device match. This ensures that bound sockets are never selected,
even if there is no unbound socket.

Allow IPv6 packets to be sent over a datagram skt bound to a VRF. These
packets are currently blocked, as flowi6_oif was set to that of the
master vrf device, and the ipi6_ifindex is that of the slave device.
Allow these packets to be sent by checking the device with ipi6_ifindex
has the same L3 scope as that of the bound device of the skt, which is
the master vrf device. Note that this check always succeeds if the skt
is unbound.

Even though the right datagram skt is now selected by compute_score(),
a different skt is being returned that is bound to the wrong vrf. The
difference between these and stream sockets is the handling of the skt
option for SO_REUSEPORT. While the handling when adding a skt for reuse
correctly checks that the bound device of the skt is a match, the skts
in the hashslot are already incorrect. So for the same hash, a skt for
the wrong vrf may be selected for the required port. The root cause is
that the skt is immediately placed into a slot when it is created,
but when the skt is then bound using SO_BINDTODEVICE, it remains in the
same slot. The solution is to move the skt to the correct slot by
forcing a rehash.

Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 include/net/udp.h   | 11 +++++++++++
 net/core/sock.c     |  2 ++
 net/ipv4/udp.c      | 15 ++++++---------
 net/ipv6/datagram.c | 10 +++++++---
 net/ipv6/udp.c      | 14 +++++---------
 5 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/include/net/udp.h b/include/net/udp.h
index 9e82cb391dea..a496e441645e 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -252,6 +252,17 @@ static inline int udp_rqueue_get(struct sock *sk)
 	return sk_rmem_alloc_get(sk) - READ_ONCE(udp_sk(sk)->forward_deficit);
 }
 
+static inline bool udp_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+				       int dif, int sdif)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+	return inet_bound_dev_eq(!!net->ipv4.sysctl_udp_l3mdev_accept,
+				 bound_dev_if, dif, sdif);
+#else
+	return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+#endif
+}
+
 /* net/ipv4/udp.c */
 void udp_destruct_sock(struct sock *sk);
 void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
diff --git a/net/core/sock.c b/net/core/sock.c
index 7e8796a6a089..2fff1796dcba 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -567,6 +567,8 @@ static int sock_setbindtodevice(struct sock *sk, char __user *optval,
 
 	lock_sock(sk);
 	sk->sk_bound_dev_if = index;
+	if (sk->sk_prot->rehash)
+		sk->sk_prot->rehash(sk);
 	sk_dst_reset(sk);
 	release_sock(sk);
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 07d6fb80f433..2c01d52a8dd9 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -371,6 +371,7 @@ static int compute_score(struct sock *sk, struct net *net,
 {
 	int score;
 	struct inet_sock *inet;
+	bool dev_match;
 
 	if (!net_eq(sock_net(sk), net) ||
 	    udp_sk(sk)->udp_port_hash != hnum ||
@@ -398,15 +399,11 @@ static int compute_score(struct sock *sk, struct net *net,
 		score += 4;
 	}
 
-	if (sk->sk_bound_dev_if || exact_dif) {
-		bool dev_match = (sk->sk_bound_dev_if == dif ||
-				  sk->sk_bound_dev_if == sdif);
-
-		if (!dev_match)
-			return -1;
-		if (sk->sk_bound_dev_if)
-			score += 4;
-	}
+	dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+					dif, sdif);
+	if (!dev_match)
+		return -1;
+	score += 4;
 
 	if (sk->sk_incoming_cpu == raw_smp_processor_id())
 		score++;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 1ede7a16a0be..bde08aa549f3 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -772,6 +772,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 		case IPV6_2292PKTINFO:
 		    {
 			struct net_device *dev = NULL;
+			int src_idx;
 
 			if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
 				err = -EINVAL;
@@ -779,12 +780,15 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
 			}
 
 			src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
+			src_idx = src_info->ipi6_ifindex;
 
-			if (src_info->ipi6_ifindex) {
+			if (src_idx) {
 				if (fl6->flowi6_oif &&
-				    src_info->ipi6_ifindex != fl6->flowi6_oif)
+				    src_idx != fl6->flowi6_oif &&
+				    (sk->sk_bound_dev_if != fl6->flowi6_oif ||
+				     !sk_dev_equal_l3scope(sk, src_idx)))
 					return -EINVAL;
-				fl6->flowi6_oif = src_info->ipi6_ifindex;
+				fl6->flowi6_oif = src_idx;
 			}
 
 			addr_type = __ipv6_addr_type(&src_info->ipi6_addr);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5dc6949ed956..895fa77bde90 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -117,6 +117,7 @@ static int compute_score(struct sock *sk, struct net *net,
 {
 	int score;
 	struct inet_sock *inet;
+	bool dev_match;
 
 	if (!net_eq(sock_net(sk), net) ||
 	    udp_sk(sk)->udp_port_hash != hnum ||
@@ -144,15 +145,10 @@ static int compute_score(struct sock *sk, struct net *net,
 		score++;
 	}
 
-	if (sk->sk_bound_dev_if || exact_dif) {
-		bool dev_match = (sk->sk_bound_dev_if == dif ||
-				  sk->sk_bound_dev_if == sdif);
-
-		if (!dev_match)
-			return -1;
-		if (sk->sk_bound_dev_if)
-			score++;
-	}
+	dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif);
+	if (!dev_match)
+		return -1;
+	score++;
 
 	if (sk->sk_incoming_cpu == raw_smp_processor_id())
 		score++;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 4/9] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (2 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 3/9] net: ensure unbound datagram " Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:07   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 5/9] net: fix raw socket lookup device bind matching " Mike Manning
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev

Add a sysctl raw_l3mdev_accept to control raw socket lookup in a manner
similar to use of tcp_l3mdev_accept for stream and of udp_l3mdev_accept
for datagram sockets. Have this default to enabled for reasons of
backwards compatibility. This is so as to specify the output device
with cmsg and IP_PKTINFO, but using a socket not bound to the
corresponding VRF. This allows e.g. older ping implementations to be
run with specifying the device but without executing it in the VRF.
If the option is disabled, packets received in a VRF context are only
handled by a raw socket bound to the VRF, and correspondingly packets
in the default VRF are only handled by a socket not bound to any VRF.

Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 Documentation/networking/ip-sysctl.txt | 12 ++++++++++++
 Documentation/networking/vrf.txt       | 13 +++++++++++++
 include/net/netns/ipv4.h               |  3 +++
 include/net/raw.h                      |  1 +
 net/ipv4/af_inet.c                     |  2 ++
 net/ipv4/raw.c                         | 28 ++++++++++++++++++++++++++--
 net/ipv4/sysctl_net_ipv4.c             | 11 +++++++++++
 7 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 163b5ff1073c..e0e72e2ff6b2 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -359,6 +359,7 @@ tcp_l3mdev_accept - BOOLEAN
 	derived from the listen socket to be bound to the L3 domain in
 	which the packets originated. Only valid when the kernel was
 	compiled with CONFIG_NET_L3_MASTER_DEV.
+        Default: 0 (disabled)
 
 tcp_low_latency - BOOLEAN
 	This is a legacy option, it has no effect anymore.
@@ -762,6 +763,7 @@ udp_l3mdev_accept - BOOLEAN
 	being received regardless of the L3 domain in which they
 	originated. Only valid when the kernel was compiled with
 	CONFIG_NET_L3_MASTER_DEV.
+        Default: 0 (disabled)
 
 udp_mem - vector of 3 INTEGERs: min, pressure, max
 	Number of pages allowed for queueing by all UDP sockets.
@@ -788,6 +790,16 @@ udp_wmem_min - INTEGER
 	total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
 	Default: 4K
 
+RAW variables:
+
+raw_l3mdev_accept - BOOLEAN
+	Enabling this option allows a "global" bound socket to work
+	across L3 master domains (e.g., VRFs) with packets capable of
+	being received regardless of the L3 domain in which they
+	originated. Only valid when the kernel was compiled with
+	CONFIG_NET_L3_MASTER_DEV.
+	Default: 1 (enabled)
+
 CIPSOv4 Variables:
 
 cipso_cache_enable - BOOLEAN
diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt
index d4b129402d57..a5f103b083a0 100644
--- a/Documentation/networking/vrf.txt
+++ b/Documentation/networking/vrf.txt
@@ -111,9 +111,22 @@ the same port if they bind to an l3mdev.
 TCP & UDP services running in the default VRF context (ie., not bound
 to any VRF device) can work across all VRF domains by enabling the
 tcp_l3mdev_accept and udp_l3mdev_accept sysctl options:
+
     sysctl -w net.ipv4.tcp_l3mdev_accept=1
     sysctl -w net.ipv4.udp_l3mdev_accept=1
 
+These options are disabled by default so that a socket in a VRF is only
+selected for packets in that VRF. There is a similar option for RAW
+sockets, which is enabled by default for reasons of backwards compatibility.
+This is so as to specify the output device with cmsg and IP_PKTINFO, but
+using a socket not bound to the corresponding VRF. This allows e.g. older ping
+implementations to be run with specifying the device but without executing it
+in the VRF. This option can be disabled so that packets received in a VRF
+context are only handled by a raw socket bound to the VRF, and packets in the
+default VRF are only handled by a socket not bound to any VRF:
+
+    sysctl -w net.ipv4.raw_l3mdev_accept=0
+
 netfilter rules on the VRF device can be used to limit access to services
 running in the default VRF context as well.
 
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index e47503b4e4d1..104a6669e344 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -103,6 +103,9 @@ struct netns_ipv4 {
 	/* Shall we try to damage output packets if routing dev changes? */
 	int sysctl_ip_dynaddr;
 	int sysctl_ip_early_demux;
+#ifdef CONFIG_NET_L3_MASTER_DEV
+	int sysctl_raw_l3mdev_accept;
+#endif
 	int sysctl_tcp_early_demux;
 	int sysctl_udp_early_demux;
 
diff --git a/include/net/raw.h b/include/net/raw.h
index 9c9fa98a91a4..20ebf0b3dfa8 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -61,6 +61,7 @@ void raw_seq_stop(struct seq_file *seq, void *v);
 
 int raw_hash_sk(struct sock *sk);
 void raw_unhash_sk(struct sock *sk);
+void raw_init(void);
 
 struct raw_sock {
 	/* inet_sock has to be the first member */
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 1fbe2f815474..07749c5b0a50 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1964,6 +1964,8 @@ static int __init inet_init(void)
 	/* Add UDP-Lite (RFC 3828) */
 	udplite4_register();
 
+	raw_init();
+
 	ping_init();
 
 	/*
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 8ca3eb06ba04..1ebd29abe79c 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -805,7 +805,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	return copied;
 }
 
-static int raw_init(struct sock *sk)
+static int raw_sk_init(struct sock *sk)
 {
 	struct raw_sock *rp = raw_sk(sk);
 
@@ -970,7 +970,7 @@ struct proto raw_prot = {
 	.connect	   = ip4_datagram_connect,
 	.disconnect	   = __udp_disconnect,
 	.ioctl		   = raw_ioctl,
-	.init		   = raw_init,
+	.init		   = raw_sk_init,
 	.setsockopt	   = raw_setsockopt,
 	.getsockopt	   = raw_getsockopt,
 	.sendmsg	   = raw_sendmsg,
@@ -1133,4 +1133,28 @@ void __init raw_proc_exit(void)
 {
 	unregister_pernet_subsys(&raw_net_ops);
 }
+
+static void raw_sysctl_init_net(struct net *net)
+{
+#ifdef CONFIG_NET_L3_MASTER_DEV
+	net->ipv4.sysctl_raw_l3mdev_accept = 1;
+#endif
+}
+
+static int __net_init raw_sysctl_init(struct net *net)
+{
+	raw_sysctl_init_net(net);
+	return 0;
+}
+
+static struct pernet_operations __net_initdata raw_sysctl_ops = {
+	.init	= raw_sysctl_init,
+};
+
+void __init raw_init(void)
+{
+	raw_sysctl_init_net(&init_net);
+	if (register_pernet_subsys(&raw_sysctl_ops))
+		panic("RAW: failed to init sysctl parameters.\n");
+}
 #endif /* CONFIG_PROC_FS */
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 891ed2f91467..ba0fc4b18465 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -602,6 +602,17 @@ static struct ctl_table ipv4_net_table[] = {
 		.mode		= 0644,
 		.proc_handler	= ipv4_ping_group_range,
 	},
+#ifdef CONFIG_NET_L3_MASTER_DEV
+	{
+		.procname	= "raw_l3mdev_accept",
+		.data		= &init_net.ipv4.sysctl_raw_l3mdev_accept,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &one,
+	},
+#endif
 	{
 		.procname	= "tcp_ecn",
 		.data		= &init_net.ipv4.sysctl_tcp_ecn,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 5/9] net: fix raw socket lookup device bind matching with VRFs
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (3 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 4/9] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:07   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 6/9] vrf: mark skb for multicast or link-local as enslaved to VRF Mike Manning
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev; +Cc: Duncan Eastoe

From: Duncan Eastoe <deastoe@vyatta.att-mail.com>

When there exist a pair of raw sockets one unbound and one bound
to a VRF but equal in all other respects, when a packet is received
in the VRF context, __raw_v4_lookup() matches on both sockets.

This results in the packet being delivered over both sockets,
instead of only the raw socket bound to the VRF. The bound device
checks in __raw_v4_lookup() are replaced with a call to
raw_sk_bound_dev_eq() which correctly handles whether the packet
should be delivered over the unbound socket in such cases.

In __raw_v6_lookup() the match on the device binding of the socket is
similarly updated to use raw_sk_bound_dev_eq() which matches the
handling in __raw_v4_lookup().

Importantly raw_sk_bound_dev_eq() takes the raw_l3mdev_accept sysctl
into account.

Signed-off-by: Duncan Eastoe <deastoe@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 include/net/raw.h | 13 ++++++++++++-
 net/ipv4/raw.c    |  3 +--
 net/ipv6/raw.c    |  5 ++---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/include/net/raw.h b/include/net/raw.h
index 20ebf0b3dfa8..821ff4887f77 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -17,7 +17,7 @@
 #ifndef _RAW_H
 #define _RAW_H
 
-
+#include <net/inet_sock.h>
 #include <net/protocol.h>
 #include <linux/icmp.h>
 
@@ -75,4 +75,15 @@ static inline struct raw_sock *raw_sk(const struct sock *sk)
 	return (struct raw_sock *)sk;
 }
 
+static inline bool raw_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+				       int dif, int sdif)
+{
+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+	return inet_bound_dev_eq(!!net->ipv4.sysctl_raw_l3mdev_accept,
+				 bound_dev_if, dif, sdif);
+#else
+	return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+#endif
+}
+
 #endif	/* _RAW_H */
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 1ebd29abe79c..fb1f02015a15 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -131,8 +131,7 @@ struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
 		if (net_eq(sock_net(sk), net) && inet->inet_num == num	&&
 		    !(inet->inet_daddr && inet->inet_daddr != raddr) 	&&
 		    !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
-		    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
-		      sk->sk_bound_dev_if != sdif))
+		    raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
 			goto found; /* gotcha */
 	}
 	sk = NULL;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 5e0efd3954e9..aed7eb5c2123 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -86,9 +86,8 @@ struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
 			    !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
 				continue;
 
-			if (sk->sk_bound_dev_if &&
-			    sk->sk_bound_dev_if != dif &&
-			    sk->sk_bound_dev_if != sdif)
+			if (!raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+						 dif, sdif))
 				continue;
 
 			if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 6/9] vrf: mark skb for multicast or link-local as enslaved to VRF
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (4 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 5/9] net: fix raw socket lookup device bind matching " Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:07   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 7/9] ipv6: allow ping to link-local address in VRF Mike Manning
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev

The skb for packets that are multicast or to a link-local address are
not marked as being enslaved to a VRF, if they are received on a socket
bound to the VRF. This is needed for ND and it is preferable for the
kernel not to have to deal with the additional use-cases if ll or mcast
packets are handled as enslaved. However, this does not allow service
instances listening on unbound and bound to VRF sockets to distinguish
the VRF used, if packets are sent as multicast or to a link-local
address. The fix is for the VRF driver to also mark these skb as being
enslaved to the VRF.

Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 drivers/net/vrf.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 69b7227c637e..21ad4b1d7f03 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -981,24 +981,23 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
 				   struct sk_buff *skb)
 {
 	int orig_iif = skb->skb_iif;
-	bool need_strict;
+	bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
+	bool is_ndisc = ipv6_ndisc_frame(skb);
 
-	/* loopback traffic; do not push through packet taps again.
-	 * Reset pkt_type for upper layers to process skb
+	/* loopback, multicast & non-ND link-local traffic; do not push through
+	 * packet taps again. Reset pkt_type for upper layers to process skb
 	 */
-	if (skb->pkt_type == PACKET_LOOPBACK) {
+	if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
 		skb->dev = vrf_dev;
 		skb->skb_iif = vrf_dev->ifindex;
 		IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
-		skb->pkt_type = PACKET_HOST;
+		if (skb->pkt_type == PACKET_LOOPBACK)
+			skb->pkt_type = PACKET_HOST;
 		goto out;
 	}
 
-	/* if packet is NDISC or addressed to multicast or link-local
-	 * then keep the ingress interface
-	 */
-	need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
-	if (!ipv6_ndisc_frame(skb) && !need_strict) {
+	/* if packet is NDISC then keep the ingress interface */
+	if (!is_ndisc) {
 		vrf_rx_stats(vrf_dev, skb->len);
 		skb->dev = vrf_dev;
 		skb->skb_iif = vrf_dev->ifindex;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 7/9] ipv6: allow ping to link-local address in VRF
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (5 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 6/9] vrf: mark skb for multicast or link-local as enslaved to VRF Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:07   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 8/9] ipv6: handling of multicast packets received " Mike Manning
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev

If link-local packets are marked as enslaved to a VRF, then to allow
ping to the link-local from a vrf, the error handling for IPV6_PKTINFO
needs to be relaxed to also allow the pkt ipi6_ifindex to be that of a
slave device to the vrf.

Note that the real device also needs to be retrieved in icmp6_iif()
to set the ipv6 flow oif to this for icmp echo reply handling. The
recent commit 24b711edfc34 ("net/ipv6: Fix linklocal to global address
with VRF") takes care of this, so the sdif does not need checking here.

This fix makes ping to link-local consistent with that to global
addresses, in that this can now be done from within the same VRF that
the address is in.

Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 net/ipv6/ipv6_sockglue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 381ce38940ae..973e215c3114 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -486,7 +486,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 				retv = -EFAULT;
 				break;
 		}
-		if (sk->sk_bound_dev_if && pkt.ipi6_ifindex != sk->sk_bound_dev_if)
+		if (!sk_dev_equal_l3scope(sk, pkt.ipi6_ifindex))
 			goto e_inval;
 
 		np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 8/9] ipv6: handling of multicast packets received in VRF
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (6 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 7/9] ipv6: allow ping to link-local address in VRF Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:08   ` David Ahern
  2018-11-07 15:36 ` [PATCH net-next v5 9/9] ipv6: do not drop vrf udp multicast packets Mike Manning
  2018-11-08  0:13 ` [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs David Miller
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev; +Cc: Dewi Morgan

If the skb for multicast packets marked as enslaved to a VRF are
received, then the secondary device index should be used to obtain
the real device. And verify the multicast address against the
enslaved rather than the l3mdev device.

Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 net/ipv6/ip6_input.c | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 96577e742afd..df58e1100226 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -359,6 +359,8 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
 			}
 		} else if (ipprot->flags & INET6_PROTO_FINAL) {
 			const struct ipv6hdr *hdr;
+			int sdif = inet6_sdif(skb);
+			struct net_device *dev;
 
 			/* Only do this once for first final protocol */
 			have_final = true;
@@ -371,9 +373,19 @@ static int ip6_input_finish(struct net *net, struct sock *sk, struct sk_buff *sk
 			skb_postpull_rcsum(skb, skb_network_header(skb),
 					   skb_network_header_len(skb));
 			hdr = ipv6_hdr(skb);
+
+			/* skb->dev passed may be master dev for vrfs. */
+			if (sdif) {
+				dev = dev_get_by_index_rcu(net, sdif);
+				if (!dev)
+					goto discard;
+			} else {
+				dev = skb->dev;
+			}
+
 			if (ipv6_addr_is_multicast(&hdr->daddr) &&
-			    !ipv6_chk_mcast_addr(skb->dev, &hdr->daddr,
-			    &hdr->saddr) &&
+			    !ipv6_chk_mcast_addr(dev, &hdr->daddr,
+						 &hdr->saddr) &&
 			    !ipv6_is_mld(skb, nexthdr, skb_network_header_len(skb)))
 				goto discard;
 		}
@@ -432,15 +444,32 @@ EXPORT_SYMBOL_GPL(ip6_input);
 
 int ip6_mc_input(struct sk_buff *skb)
 {
+	int sdif = inet6_sdif(skb);
 	const struct ipv6hdr *hdr;
+	struct net_device *dev;
 	bool deliver;
 
 	__IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev),
 			 __in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST,
 			 skb->len);
 
+	/* skb->dev passed may be master dev for vrfs. */
+	if (sdif) {
+		rcu_read_lock();
+		dev = dev_get_by_index_rcu(dev_net(skb->dev), sdif);
+		if (!dev) {
+			rcu_read_unlock();
+			kfree_skb(skb);
+			return -ENODEV;
+		}
+	} else {
+		dev = skb->dev;
+	}
+
 	hdr = ipv6_hdr(skb);
-	deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
+	deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr, NULL);
+	if (sdif)
+		rcu_read_unlock();
 
 #ifdef CONFIG_IPV6_MROUTE
 	/*
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next v5 9/9] ipv6: do not drop vrf udp multicast packets
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (7 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 8/9] ipv6: handling of multicast packets received " Mike Manning
@ 2018-11-07 15:36 ` Mike Manning
  2018-11-07 19:08   ` David Ahern
  2018-11-08  0:13 ` [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs David Miller
  9 siblings, 1 reply; 20+ messages in thread
From: Mike Manning @ 2018-11-07 15:36 UTC (permalink / raw)
  To: netdev; +Cc: Dewi Morgan

From: Dewi Morgan <morgand@vyatta.att-mail.com>

For bound udp sockets in a vrf, also check the sdif to get the index
for ingress devices enslaved to an l3mdev.

Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
---
 net/ipv6/udp.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 895fa77bde90..a905bf9ed906 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -637,7 +637,7 @@ static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
 				   __be16 loc_port, const struct in6_addr *loc_addr,
 				   __be16 rmt_port, const struct in6_addr *rmt_addr,
-				   int dif, unsigned short hnum)
+				   int dif, int sdif, unsigned short hnum)
 {
 	struct inet_sock *inet = inet_sk(sk);
 
@@ -649,7 +649,7 @@ static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
 	    (inet->inet_dport && inet->inet_dport != rmt_port) ||
 	    (!ipv6_addr_any(&sk->sk_v6_daddr) &&
 		    !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) ||
-	    (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) ||
+	    !udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif) ||
 	    (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
 		    !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr)))
 		return false;
@@ -683,6 +683,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 	unsigned int offset = offsetof(typeof(*sk), sk_node);
 	unsigned int hash2 = 0, hash2_any = 0, use_hash2 = (hslot->count > 10);
 	int dif = inet6_iif(skb);
+	int sdif = inet6_sdif(skb);
 	struct hlist_node *node;
 	struct sk_buff *nskb;
 
@@ -697,7 +698,8 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 
 	sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) {
 		if (!__udp_v6_is_mcast_sock(net, sk, uh->dest, daddr,
-					    uh->source, saddr, dif, hnum))
+					    uh->source, saddr, dif, sdif,
+					    hnum))
 			continue;
 		/* If zero checksum and no_check is not on for
 		 * the socket then skip it.
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket
  2018-11-07 15:36 ` [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket Mike Manning
@ 2018-11-07 19:06   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:06 UTC (permalink / raw)
  To: Mike Manning, netdev; +Cc: Robert Shearman

On 11/7/18 8:36 AM, Mike Manning wrote:
> From: Robert Shearman <rshearma@vyatta.att-mail.com>
> 
> Change the inet socket lookup to avoid packets arriving on a device
> enslaved to an l3mdev from matching unbound sockets by removing the
> wildcard for non sk_bound_dev_if and instead relying on check against
> the secondary device index, which will be 0 when the input device is
> not enslaved to an l3mdev and so match against an unbound socket and
> not match when the input device is enslaved.
> 
> Change the socket binding to take the l3mdev into account to allow an
> unbound socket to not conflict sockets bound to an l3mdev given the
> datapath isolation now guaranteed.
> 
> Signed-off-by: Robert Shearman <rshearma@vyatta.att-mail.com>
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  Documentation/networking/vrf.txt |  9 +++++----
>  include/net/inet6_hashtables.h   |  5 ++---
>  include/net/inet_hashtables.h    | 13 ++++++-------
>  include/net/inet_sock.h          | 13 +++++++++++++
>  net/ipv4/inet_connection_sock.c  | 13 ++++++++++---
>  net/ipv4/inet_hashtables.c       | 20 +++++++++++++++-----
>  6 files changed, 51 insertions(+), 22 deletions(-)

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 2/9] net: ensure unbound stream socket to be chosen when not in a VRF
  2018-11-07 15:36 ` [PATCH net-next v5 2/9] net: ensure unbound stream socket to be chosen when not in a VRF Mike Manning
@ 2018-11-07 19:06   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:06 UTC (permalink / raw)
  To: Mike Manning, netdev

On 11/7/18 8:36 AM, Mike Manning wrote:
> The commit a04a480d4392 ("net: Require exact match for TCP socket
> lookups if dif is l3mdev") only ensures that the correct socket is
> selected for packets in a VRF. However, there is no guarantee that
> the unbound socket will be selected for packets when not in a VRF.
> By checking for a device match in compute_score() also for the case
> when there is no bound device and attaching a score to this, the
> unbound socket is selected. And if a failure is returned when there
> is no device match, this ensures that bound sockets are never selected,
> even if there is no unbound socket.
> 
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  include/net/inet_hashtables.h | 11 +++++++++++
>  include/net/inet_sock.h       |  8 ++++++++
>  net/ipv4/inet_hashtables.c    | 14 ++++++--------
>  net/ipv6/inet6_hashtables.c   | 14 ++++++--------
>  4 files changed, 31 insertions(+), 16 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 3/9] net: ensure unbound datagram socket to be chosen when not in a VRF
  2018-11-07 15:36 ` [PATCH net-next v5 3/9] net: ensure unbound datagram " Mike Manning
@ 2018-11-07 19:06   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:06 UTC (permalink / raw)
  To: Mike Manning, netdev

On 11/7/18 8:36 AM, Mike Manning wrote:
> Ensure an unbound datagram skt is chosen when not in a VRF. The check
> for a device match in compute_score() for UDP must be performed when
> there is no device match. For this, a failure is returned when there is
> no device match. This ensures that bound sockets are never selected,
> even if there is no unbound socket.
> 
> Allow IPv6 packets to be sent over a datagram skt bound to a VRF. These
> packets are currently blocked, as flowi6_oif was set to that of the
> master vrf device, and the ipi6_ifindex is that of the slave device.
> Allow these packets to be sent by checking the device with ipi6_ifindex
> has the same L3 scope as that of the bound device of the skt, which is
> the master vrf device. Note that this check always succeeds if the skt
> is unbound.
> 
> Even though the right datagram skt is now selected by compute_score(),
> a different skt is being returned that is bound to the wrong vrf. The
> difference between these and stream sockets is the handling of the skt
> option for SO_REUSEPORT. While the handling when adding a skt for reuse
> correctly checks that the bound device of the skt is a match, the skts
> in the hashslot are already incorrect. So for the same hash, a skt for
> the wrong vrf may be selected for the required port. The root cause is
> that the skt is immediately placed into a slot when it is created,
> but when the skt is then bound using SO_BINDTODEVICE, it remains in the
> same slot. The solution is to move the skt to the correct slot by
> forcing a rehash.
> 
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  include/net/udp.h   | 11 +++++++++++
>  net/core/sock.c     |  2 ++
>  net/ipv4/udp.c      | 15 ++++++---------
>  net/ipv6/datagram.c | 10 +++++++---
>  net/ipv6/udp.c      | 14 +++++---------
>  5 files changed, 31 insertions(+), 21 deletions(-)

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 4/9] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs
  2018-11-07 15:36 ` [PATCH net-next v5 4/9] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs Mike Manning
@ 2018-11-07 19:07   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:07 UTC (permalink / raw)
  To: Mike Manning, netdev

On 11/7/18 8:36 AM, Mike Manning wrote:
> Add a sysctl raw_l3mdev_accept to control raw socket lookup in a manner
> similar to use of tcp_l3mdev_accept for stream and of udp_l3mdev_accept
> for datagram sockets. Have this default to enabled for reasons of
> backwards compatibility. This is so as to specify the output device
> with cmsg and IP_PKTINFO, but using a socket not bound to the
> corresponding VRF. This allows e.g. older ping implementations to be
> run with specifying the device but without executing it in the VRF.
> If the option is disabled, packets received in a VRF context are only
> handled by a raw socket bound to the VRF, and correspondingly packets
> in the default VRF are only handled by a socket not bound to any VRF.
> 
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  Documentation/networking/ip-sysctl.txt | 12 ++++++++++++
>  Documentation/networking/vrf.txt       | 13 +++++++++++++
>  include/net/netns/ipv4.h               |  3 +++
>  include/net/raw.h                      |  1 +
>  net/ipv4/af_inet.c                     |  2 ++
>  net/ipv4/raw.c                         | 28 ++++++++++++++++++++++++++--
>  net/ipv4/sysctl_net_ipv4.c             | 11 +++++++++++
>  7 files changed, 68 insertions(+), 2 deletions(-)

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 5/9] net: fix raw socket lookup device bind matching with VRFs
  2018-11-07 15:36 ` [PATCH net-next v5 5/9] net: fix raw socket lookup device bind matching " Mike Manning
@ 2018-11-07 19:07   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:07 UTC (permalink / raw)
  To: Mike Manning, netdev; +Cc: Duncan Eastoe

On 11/7/18 8:36 AM, Mike Manning wrote:
> From: Duncan Eastoe <deastoe@vyatta.att-mail.com>
> 
> When there exist a pair of raw sockets one unbound and one bound
> to a VRF but equal in all other respects, when a packet is received
> in the VRF context, __raw_v4_lookup() matches on both sockets.
> 
> This results in the packet being delivered over both sockets,
> instead of only the raw socket bound to the VRF. The bound device
> checks in __raw_v4_lookup() are replaced with a call to
> raw_sk_bound_dev_eq() which correctly handles whether the packet
> should be delivered over the unbound socket in such cases.
> 
> In __raw_v6_lookup() the match on the device binding of the socket is
> similarly updated to use raw_sk_bound_dev_eq() which matches the
> handling in __raw_v4_lookup().
> 
> Importantly raw_sk_bound_dev_eq() takes the raw_l3mdev_accept sysctl
> into account.
> 
> Signed-off-by: Duncan Eastoe <deastoe@vyatta.att-mail.com>
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  include/net/raw.h | 13 ++++++++++++-
>  net/ipv4/raw.c    |  3 +--
>  net/ipv6/raw.c    |  5 ++---
>  3 files changed, 15 insertions(+), 6 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 6/9] vrf: mark skb for multicast or link-local as enslaved to VRF
  2018-11-07 15:36 ` [PATCH net-next v5 6/9] vrf: mark skb for multicast or link-local as enslaved to VRF Mike Manning
@ 2018-11-07 19:07   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:07 UTC (permalink / raw)
  To: Mike Manning, netdev

On 11/7/18 8:36 AM, Mike Manning wrote:
> The skb for packets that are multicast or to a link-local address are
> not marked as being enslaved to a VRF, if they are received on a socket
> bound to the VRF. This is needed for ND and it is preferable for the
> kernel not to have to deal with the additional use-cases if ll or mcast
> packets are handled as enslaved. However, this does not allow service
> instances listening on unbound and bound to VRF sockets to distinguish
> the VRF used, if packets are sent as multicast or to a link-local
> address. The fix is for the VRF driver to also mark these skb as being
> enslaved to the VRF.
> 
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  drivers/net/vrf.c | 19 +++++++++----------
>  1 file changed, 9 insertions(+), 10 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 7/9] ipv6: allow ping to link-local address in VRF
  2018-11-07 15:36 ` [PATCH net-next v5 7/9] ipv6: allow ping to link-local address in VRF Mike Manning
@ 2018-11-07 19:07   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:07 UTC (permalink / raw)
  To: Mike Manning, netdev

On 11/7/18 8:36 AM, Mike Manning wrote:
> If link-local packets are marked as enslaved to a VRF, then to allow
> ping to the link-local from a vrf, the error handling for IPV6_PKTINFO
> needs to be relaxed to also allow the pkt ipi6_ifindex to be that of a
> slave device to the vrf.
> 
> Note that the real device also needs to be retrieved in icmp6_iif()
> to set the ipv6 flow oif to this for icmp echo reply handling. The
> recent commit 24b711edfc34 ("net/ipv6: Fix linklocal to global address
> with VRF") takes care of this, so the sdif does not need checking here.
> 
> This fix makes ping to link-local consistent with that to global
> addresses, in that this can now be done from within the same VRF that
> the address is in.
> 
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  net/ipv6/ipv6_sockglue.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 8/9] ipv6: handling of multicast packets received in VRF
  2018-11-07 15:36 ` [PATCH net-next v5 8/9] ipv6: handling of multicast packets received " Mike Manning
@ 2018-11-07 19:08   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:08 UTC (permalink / raw)
  To: Mike Manning, netdev; +Cc: Dewi Morgan

On 11/7/18 8:36 AM, Mike Manning wrote:
> If the skb for multicast packets marked as enslaved to a VRF are
> received, then the secondary device index should be used to obtain
> the real device. And verify the multicast address against the
> enslaved rather than the l3mdev device.
> 
> Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  net/ipv6/ip6_input.c | 35 ++++++++++++++++++++++++++++++++---
>  1 file changed, 32 insertions(+), 3 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 9/9] ipv6: do not drop vrf udp multicast packets
  2018-11-07 15:36 ` [PATCH net-next v5 9/9] ipv6: do not drop vrf udp multicast packets Mike Manning
@ 2018-11-07 19:08   ` David Ahern
  0 siblings, 0 replies; 20+ messages in thread
From: David Ahern @ 2018-11-07 19:08 UTC (permalink / raw)
  To: Mike Manning, netdev; +Cc: Dewi Morgan

On 11/7/18 8:36 AM, Mike Manning wrote:
> From: Dewi Morgan <morgand@vyatta.att-mail.com>
> 
> For bound udp sockets in a vrf, also check the sdif to get the index
> for ingress devices enslaved to an l3mdev.
> 
> Signed-off-by: Dewi Morgan <morgand@vyatta.att-mail.com>
> Signed-off-by: Mike Manning <mmanning@vyatta.att-mail.com>
> ---
>  net/ipv6/udp.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs
  2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
                   ` (8 preceding siblings ...)
  2018-11-07 15:36 ` [PATCH net-next v5 9/9] ipv6: do not drop vrf udp multicast packets Mike Manning
@ 2018-11-08  0:13 ` David Miller
  9 siblings, 0 replies; 20+ messages in thread
From: David Miller @ 2018-11-08  0:13 UTC (permalink / raw)
  To: mmanning; +Cc: netdev

From: Mike Manning <mmanning@vyatta.att-mail.com>
Date: Wed,  7 Nov 2018 15:36:01 +0000

> Services currently have to be VRF-aware if they are using an unbound
> socket. One cannot have multiple service instances running in the
> default and other VRFs for services that are not VRF-aware and listen
> on an unbound socket. This is because there is no easy way of isolating
> packets received in the default VRF from those arriving in other VRFs.
> 
> This series provides this isolation for stream sockets subject to the
> existing kernel parameter net.ipv4.tcp_l3mdev_accept not being set,
> given that this is documented as allowing a single service instance to
> work across all VRF domains. Similarly, net.ipv4.udp_l3mdev_accept is
> checked for datagram sockets, and net.ipv4.raw_l3mdev_accept is
> introduced for raw sockets. The functionality applies to UDP & TCP
> services as well as those using raw sockets, and is for IPv4 and IPv6.
> 
> Example of running ssh instances in default and blue VRF:
 ...

Series applied, thanks Mike.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2018-11-08  9:46 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-07 15:36 [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs Mike Manning
2018-11-07 15:36 ` [PATCH net-next v5 1/9] net: allow binding socket in a VRF when there's an unbound socket Mike Manning
2018-11-07 19:06   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 2/9] net: ensure unbound stream socket to be chosen when not in a VRF Mike Manning
2018-11-07 19:06   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 3/9] net: ensure unbound datagram " Mike Manning
2018-11-07 19:06   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 4/9] net: provide a sysctl raw_l3mdev_accept for raw socket lookup with VRFs Mike Manning
2018-11-07 19:07   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 5/9] net: fix raw socket lookup device bind matching " Mike Manning
2018-11-07 19:07   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 6/9] vrf: mark skb for multicast or link-local as enslaved to VRF Mike Manning
2018-11-07 19:07   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 7/9] ipv6: allow ping to link-local address in VRF Mike Manning
2018-11-07 19:07   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 8/9] ipv6: handling of multicast packets received " Mike Manning
2018-11-07 19:08   ` David Ahern
2018-11-07 15:36 ` [PATCH net-next v5 9/9] ipv6: do not drop vrf udp multicast packets Mike Manning
2018-11-07 19:08   ` David Ahern
2018-11-08  0:13 ` [PATCH net-next v5 0/9] vrf: allow simultaneous service instances in default and other VRFs David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.