Skip to content

Commit fc68c99

Browse files
sbrivio-rhdavem330
authored andcommitted
vxlan: Support for PMTU discovery on directly bridged links
If the interface is a bridge or Open vSwitch port, and we can't forward a packet because it exceeds the local PMTU estimate, trigger an ICMP or ICMPv6 reply to the sender, using the same interface to forward it back. If metadata collection is enabled, reverse destination and source addresses, so that Open vSwitch is able to match this packet against the existing, reverse flow. v2: Use netif_is_any_bridge_port() (David Ahern) Signed-off-by: Stefano Brivio <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4cb47a8 commit fc68c99

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

drivers/net/vxlan.c

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2500,7 +2500,8 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
25002500

25012501
/* Bypass encapsulation if the destination is local */
25022502
static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
2503-
struct vxlan_dev *dst_vxlan, __be32 vni)
2503+
struct vxlan_dev *dst_vxlan, __be32 vni,
2504+
bool snoop)
25042505
{
25052506
struct pcpu_sw_netstats *tx_stats, *rx_stats;
25062507
union vxlan_addr loopback;
@@ -2532,7 +2533,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
25322533
goto drop;
25332534
}
25342535

2535-
if (dst_vxlan->cfg.flags & VXLAN_F_LEARN)
2536+
if ((dst_vxlan->cfg.flags & VXLAN_F_LEARN) && snoop)
25362537
vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0, vni);
25372538

25382539
u64_stats_update_begin(&tx_stats->syncp);
@@ -2581,7 +2582,7 @@ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
25812582

25822583
return -ENOENT;
25832584
}
2584-
vxlan_encap_bypass(skb, vxlan, dst_vxlan, vni);
2585+
vxlan_encap_bypass(skb, vxlan, dst_vxlan, vni, true);
25852586
return 1;
25862587
}
25872588

@@ -2617,7 +2618,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
26172618
if (vxlan_addr_any(dst)) {
26182619
if (did_rsc) {
26192620
/* short-circuited back to local bridge */
2620-
vxlan_encap_bypass(skb, vxlan, vxlan, default_vni);
2621+
vxlan_encap_bypass(skb, vxlan, vxlan,
2622+
default_vni, true);
26212623
return;
26222624
}
26232625
goto drop;
@@ -2720,7 +2722,23 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
27202722
}
27212723

27222724
ndst = &rt->dst;
2723-
skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM, false);
2725+
err = skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM,
2726+
netif_is_any_bridge_port(dev));
2727+
if (err < 0) {
2728+
goto tx_error;
2729+
} else if (err) {
2730+
if (info) {
2731+
struct in_addr src, dst;
2732+
2733+
src = remote_ip.sin.sin_addr;
2734+
dst = local_ip.sin.sin_addr;
2735+
info->key.u.ipv4.src = src.s_addr;
2736+
info->key.u.ipv4.dst = dst.s_addr;
2737+
}
2738+
vxlan_encap_bypass(skb, vxlan, vxlan, vni, false);
2739+
dst_release(ndst);
2740+
goto out_unlock;
2741+
}
27242742

27252743
tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb);
27262744
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
@@ -2760,7 +2778,24 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
27602778
goto out_unlock;
27612779
}
27622780

2763-
skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM, false);
2781+
err = skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM,
2782+
netif_is_any_bridge_port(dev));
2783+
if (err < 0) {
2784+
goto tx_error;
2785+
} else if (err) {
2786+
if (info) {
2787+
struct in6_addr src, dst;
2788+
2789+
src = remote_ip.sin6.sin6_addr;
2790+
dst = local_ip.sin6.sin6_addr;
2791+
info->key.u.ipv6.src = src;
2792+
info->key.u.ipv6.dst = dst;
2793+
}
2794+
2795+
vxlan_encap_bypass(skb, vxlan, vxlan, vni, false);
2796+
dst_release(ndst);
2797+
goto out_unlock;
2798+
}
27642799

27652800
tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb);
27662801
ttl = ttl ? : ip6_dst_hoplimit(ndst);

0 commit comments

Comments
 (0)