diff mbox series

[net-next,v2,1/6] ipv4: route: Ignore output interface in FIB lookup for PMTU route

Message ID ec94f1f590e6cb57d128ce10e4306e589544944d.1596520062.git.sbrivio@redhat.com
State Accepted
Delegated to: David Miller
Headers show
Series Support PMTU discovery with bridged UDP tunnels | expand

Commit Message

Stefano Brivio Aug. 4, 2020, 5:53 a.m. UTC
Currently, processes sending traffic to a local bridge with an
encapsulation device as a port don't get ICMP errors if they exceed
the PMTU of the encapsulated link.

David Ahern suggested this as a hack, but it actually looks like
the correct solution: when we update the PMTU for a given destination
by means of updating or creating a route exception, the encapsulation
might trigger this because of PMTU discovery happening either on the
encapsulation device itself, or its lower layer. This happens on
bridged encapsulations only.

The output interface shouldn't matter, because we already have a
valid destination. Drop the output interface restriction from the
associated route lookup.

For UDP tunnels, we will now have a route exception created for the
encapsulation itself, with a MTU value reflecting its headroom, which
allows a bridge forwarding IP packets originated locally to deliver
errors back to the sending socket.

The behaviour is now consistent with IPv6 and verified with selftests
pmtu_ipv{4,6}_br_{geneve,vxlan}{4,6}_exception introduced later in
this series.

v2:
- reset output interface only for bridge ports (David Ahern)
- add and use netif_is_any_bridge_port() helper (David Ahern)

Suggested-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 include/linux/netdevice.h | 5 +++++
 net/ipv4/route.c          | 5 +++++
 2 files changed, 10 insertions(+)

Comments

David Ahern Aug. 4, 2020, 1:54 p.m. UTC | #1
On 8/3/20 11:53 PM, Stefano Brivio wrote:
> Currently, processes sending traffic to a local bridge with an
> encapsulation device as a port don't get ICMP errors if they exceed
> the PMTU of the encapsulated link.
> 
> David Ahern suggested this as a hack, but it actually looks like
> the correct solution: when we update the PMTU for a given destination
> by means of updating or creating a route exception, the encapsulation
> might trigger this because of PMTU discovery happening either on the
> encapsulation device itself, or its lower layer. This happens on
> bridged encapsulations only.
> 
> The output interface shouldn't matter, because we already have a
> valid destination. Drop the output interface restriction from the
> associated route lookup.
> 
> For UDP tunnels, we will now have a route exception created for the
> encapsulation itself, with a MTU value reflecting its headroom, which
> allows a bridge forwarding IP packets originated locally to deliver
> errors back to the sending socket.
> 
> The behaviour is now consistent with IPv6 and verified with selftests
> pmtu_ipv{4,6}_br_{geneve,vxlan}{4,6}_exception introduced later in
> this series.
> 
> v2:
> - reset output interface only for bridge ports (David Ahern)
> - add and use netif_is_any_bridge_port() helper (David Ahern)
> 
> Suggested-by: David Ahern <dsahern@gmail.com>
> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
> ---
>  include/linux/netdevice.h | 5 +++++
>  net/ipv4/route.c          | 5 +++++
>  2 files changed, 10 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@gmail.com>
diff mbox series

Patch

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 88d40b9abaa1..90444622b703 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4840,6 +4840,11 @@  static inline bool netif_is_ovs_port(const struct net_device *dev)
 	return dev->priv_flags & IFF_OVS_DATAPATH;
 }
 
+static inline bool netif_is_any_bridge_port(const struct net_device *dev)
+{
+	return netif_is_bridge_port(dev) || netif_is_ovs_port(dev);
+}
+
 static inline bool netif_is_team_master(const struct net_device *dev)
 {
 	return dev->priv_flags & IFF_TEAM;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a01efa062f6b..8ca6bcab7b03 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1050,6 +1050,11 @@  static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
 	struct flowi4 fl4;
 
 	ip_rt_build_flow_key(&fl4, sk, skb);
+
+	/* Don't make lookup fail for bridged encapsulations */
+	if (skb && netif_is_any_bridge_port(skb->dev))
+		fl4.flowi4_oif = 0;
+
 	__ip_rt_update_pmtu(rt, &fl4, mtu);
 }