History

vxlan: Allow configuration of DF behaviour

Allow users to set the IPv4 DF bit in outgoing packets, or to inherit its value from the IPv4 inner header. If the encapsulated protocol is IPv6 and DF is configured to be inherited, always set it. For IPv4, inheriting DF from the inner header was probably intended from the very beginning judging by the comment to vxlan_xmit(), but it wasn't actually implemented -- also because it would have done more harm than good, without handling for ICMP Fragmentation Needed messages. According to RFC 7348, "Path MTU discovery MAY be used". An expired RFC draft, draft-saum-nvo3-pmtud-over-vxlan-05, whose purpose was to describe PMTUD implementation, says that "is a MUST that Vxlan gateways [...] SHOULD set the DF-bit [...]", whatever that means. Given this background, the only sane option is probably to let the user decide, and keep the current behaviour as default. This only applies to non-lwt tunnels: if an external control plane is used, tunnel key will still control the DF flag. v2: - DF behaviour configuration only applies for non-lwt tunnels, move DF setting to if (!info) block in vxlan_xmit_one() (Stephen Hemminger)

Stefano Brivio committed 8 years ago

Commit b4d30691 parent c3a43b93 files · +38 −1Browse files

Unified · Split

3 files
  1. drivers/net/vxlan.c +28 −1
  2. include/net/vxlan.h +1 −0
  3. include/uapi/linux/if_link.h +9 −0
drivers/net/vxlan.c+28−1
@@ -2278,13 +2278,24 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, · 2277 unmodified lines
2278 goto tx_error;2278 goto tx_error;
2279 }2279 }
2280 2280
2281 /* Bypass encapsulation if the destination is local */
2282 if (!info) {2281 if (!info) {
2282 /* Bypass encapsulation if the destination is local */
2283 err = encap_bypass_if_local(skb, dev, vxlan, dst,2283 err = encap_bypass_if_local(skb, dev, vxlan, dst,
2284 dst_port, ifindex, vni,2284 dst_port, ifindex, vni,
2285 &rt->dst, rt->rt_flags);2285 &rt->dst, rt->rt_flags);
2286 if (err)2286 if (err)
2287 goto out_unlock;2287 goto out_unlock;
2288
2289 if (vxlan->cfg.df == VXLAN_DF_SET) {
2290 df = htons(IP_DF);
2291 } else if (vxlan->cfg.df == VXLAN_DF_INHERIT) {
2292 struct ethhdr *eth = eth_hdr(skb);
2293
2294 if (ntohs(eth->h_proto) == ETH_P_IPV6 ||
2295 (ntohs(eth->h_proto) == ETH_P_IP &&
2296 old_iph->frag_off & htons(IP_DF)))
2297 df = htons(IP_DF);
2298 }
2288 } else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT) {2299 } else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT) {
2289 df = htons(IP_DF);2300 df = htons(IP_DF);
2290 }2301 }
@@ -2837,6 +2848,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = { · 546 unmodified lines
2837 [IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },2848 [IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },
2838 [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },2849 [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
2839 [IFLA_VXLAN_TTL_INHERIT] = { .type = NLA_FLAG },2850 [IFLA_VXLAN_TTL_INHERIT] = { .type = NLA_FLAG },
2851 [IFLA_VXLAN_DF] = { .type = NLA_U8 },
2840};2852};
2841 2853
2842static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],2854static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -2893,6 +2905,16 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[], · 50 unmodified lines
2893 }2905 }
2894 }2906 }
2895 2907
2908 if (data[IFLA_VXLAN_DF]) {
2909 enum ifla_vxlan_df df = nla_get_u8(data[IFLA_VXLAN_DF]);
2910
2911 if (df < 0 || df > VXLAN_DF_MAX) {
2912 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_DF],
2913 "Invalid DF attribute");
2914 return -EINVAL;
2915 }
2916 }
2917
2896 return 0;2918 return 0;
2897}2919}
2898 2920
@@ -3538,6 +3560,9 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], · 639 unmodified lines
3538 conf->mtu = nla_get_u32(tb[IFLA_MTU]);3560 conf->mtu = nla_get_u32(tb[IFLA_MTU]);
3539 }3561 }
3540 3562
3563 if (data[IFLA_VXLAN_DF])
3564 conf->df = nla_get_u8(data[IFLA_VXLAN_DF]);
3565
3541 return 0;3566 return 0;
3542}3567}
3543 3568
@@ -3630,6 +3655,7 @@ static size_t vxlan_get_size(const struct net_device *dev) · 86 unmodified lines
3630 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TTL */3655 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TTL */
3631 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TTL_INHERIT */3656 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TTL_INHERIT */
3632 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TOS */3657 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_TOS */
3658 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_DF */
3633 nla_total_size(sizeof(__be32)) + /* IFLA_VXLAN_LABEL */3659 nla_total_size(sizeof(__be32)) + /* IFLA_VXLAN_LABEL */
3634 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LEARNING */3660 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LEARNING */
3635 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_PROXY */3661 nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_PROXY */
@@ -3696,6 +3722,7 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev) · 60 unmodified lines
3696 nla_put_u8(skb, IFLA_VXLAN_TTL_INHERIT,3722 nla_put_u8(skb, IFLA_VXLAN_TTL_INHERIT,
3697 !!(vxlan->cfg.flags & VXLAN_F_TTL_INHERIT)) ||3723 !!(vxlan->cfg.flags & VXLAN_F_TTL_INHERIT)) ||
3698 nla_put_u8(skb, IFLA_VXLAN_TOS, vxlan->cfg.tos) ||3724 nla_put_u8(skb, IFLA_VXLAN_TOS, vxlan->cfg.tos) ||
3725 nla_put_u8(skb, IFLA_VXLAN_DF, vxlan->cfg.df) ||
3699 nla_put_be32(skb, IFLA_VXLAN_LABEL, vxlan->cfg.label) ||3726 nla_put_be32(skb, IFLA_VXLAN_LABEL, vxlan->cfg.label) ||
3700 nla_put_u8(skb, IFLA_VXLAN_LEARNING,3727 nla_put_u8(skb, IFLA_VXLAN_LEARNING,
3701 !!(vxlan->cfg.flags & VXLAN_F_LEARN)) ||3728 !!(vxlan->cfg.flags & VXLAN_F_LEARN)) ||
include/net/vxlan.h+1−0
@@ -216,6 +216,7 @@ struct vxlan_config { · 215 unmodified lines
216 unsigned long age_interval;216 unsigned long age_interval;
217 unsigned int addrmax;217 unsigned int addrmax;
218 bool no_share;218 bool no_share;
219 enum ifla_vxlan_df df;
219};220};
220 221
221struct vxlan_dev_node {222struct vxlan_dev_node {
include/uapi/linux/if_link.h+9−0
@@ -533,6 +533,7 @@ enum { · 532 unmodified lines
533 IFLA_VXLAN_LABEL,533 IFLA_VXLAN_LABEL,
534 IFLA_VXLAN_GPE,534 IFLA_VXLAN_GPE,
535 IFLA_VXLAN_TTL_INHERIT,535 IFLA_VXLAN_TTL_INHERIT,
536 IFLA_VXLAN_DF,
536 __IFLA_VXLAN_MAX537 __IFLA_VXLAN_MAX
537};538};
538#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)539#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
@@ -542,6 +543,14 @@ struct ifla_vxlan_port_range { · 3 unmodified lines
542 __be16 high;543 __be16 high;
543};544};
544 545
546enum ifla_vxlan_df {
547 VXLAN_DF_UNSET = 0,
548 VXLAN_DF_SET,
549 VXLAN_DF_INHERIT,
550 __VXLAN_DF_END,
551 VXLAN_DF_MAX = __VXLAN_DF_END - 1,
552};
553
545/* GENEVE section */554/* GENEVE section */
546enum {555enum {
547 IFLA_GENEVE_UNSPEC,556 IFLA_GENEVE_UNSPEC,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t