Commit 72f6d71e authored by Hangbin Liu's avatar Hangbin Liu Committed by David S. Miller

vxlan: add ttl inherit support

Like tos inherit, ttl inherit should also means inherit the inner protocol's
ttl values, which actually not implemented in vxlan yet.

But we could not treat ttl == 0 as "use the inner TTL", because that would be
used also when the "ttl" option is not specified and that would be a behavior
change, and breaking real use cases.

So add a different attribute IFLA_VXLAN_TTL_INHERIT when "ttl inherit" is
specified with ip cmd.
Reported-by: default avatarJianlin Shi <jishi@redhat.com>
Suggested-by: default avatarJiri Benc <jbenc@redhat.com>
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 062b3e1b
...@@ -2085,9 +2085,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ...@@ -2085,9 +2085,13 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
local_ip = vxlan->cfg.saddr; local_ip = vxlan->cfg.saddr;
dst_cache = &rdst->dst_cache; dst_cache = &rdst->dst_cache;
md->gbp = skb->mark; md->gbp = skb->mark;
ttl = vxlan->cfg.ttl; if (flags & VXLAN_F_TTL_INHERIT) {
if (!ttl && vxlan_addr_multicast(dst)) ttl = ip_tunnel_get_ttl(old_iph, skb);
ttl = 1; } else {
ttl = vxlan->cfg.ttl;
if (!ttl && vxlan_addr_multicast(dst))
ttl = 1;
}
tos = vxlan->cfg.tos; tos = vxlan->cfg.tos;
if (tos == 1) if (tos == 1)
...@@ -2709,6 +2713,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = { ...@@ -2709,6 +2713,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
[IFLA_VXLAN_GBP] = { .type = NLA_FLAG, }, [IFLA_VXLAN_GBP] = { .type = NLA_FLAG, },
[IFLA_VXLAN_GPE] = { .type = NLA_FLAG, }, [IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG }, [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
[IFLA_VXLAN_TTL_INHERIT] = { .type = NLA_FLAG },
}; };
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[], static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
...@@ -3254,6 +3259,12 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], ...@@ -3254,6 +3259,12 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
if (data[IFLA_VXLAN_TTL]) if (data[IFLA_VXLAN_TTL])
conf->ttl = nla_get_u8(data[IFLA_VXLAN_TTL]); conf->ttl = nla_get_u8(data[IFLA_VXLAN_TTL]);
if (data[IFLA_VXLAN_TTL_INHERIT]) {
if (changelink)
return -EOPNOTSUPP;
conf->flags |= VXLAN_F_TTL_INHERIT;
}
if (data[IFLA_VXLAN_LABEL]) if (data[IFLA_VXLAN_LABEL])
conf->label = nla_get_be32(data[IFLA_VXLAN_LABEL]) & conf->label = nla_get_be32(data[IFLA_VXLAN_LABEL]) &
IPV6_FLOWLABEL_MASK; IPV6_FLOWLABEL_MASK;
......
...@@ -379,6 +379,17 @@ static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph, ...@@ -379,6 +379,17 @@ static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
return 0; return 0;
} }
static inline u8 ip_tunnel_get_ttl(const struct iphdr *iph,
const struct sk_buff *skb)
{
if (skb->protocol == htons(ETH_P_IP))
return iph->ttl;
else if (skb->protocol == htons(ETH_P_IPV6))
return ((const struct ipv6hdr *)iph)->hop_limit;
else
return 0;
}
/* Propogate ECN bits out */ /* Propogate ECN bits out */
static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph, static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
const struct sk_buff *skb) const struct sk_buff *skb)
......
...@@ -262,6 +262,7 @@ struct vxlan_dev { ...@@ -262,6 +262,7 @@ struct vxlan_dev {
#define VXLAN_F_COLLECT_METADATA 0x2000 #define VXLAN_F_COLLECT_METADATA 0x2000
#define VXLAN_F_GPE 0x4000 #define VXLAN_F_GPE 0x4000
#define VXLAN_F_IPV6_LINKLOCAL 0x8000 #define VXLAN_F_IPV6_LINKLOCAL 0x8000
#define VXLAN_F_TTL_INHERIT 0x10000
/* Flags that are used in the receive path. These flags must match in /* Flags that are used in the receive path. These flags must match in
* order for a socket to be shareable * order for a socket to be shareable
......
...@@ -516,6 +516,7 @@ enum { ...@@ -516,6 +516,7 @@ enum {
IFLA_VXLAN_COLLECT_METADATA, IFLA_VXLAN_COLLECT_METADATA,
IFLA_VXLAN_LABEL, IFLA_VXLAN_LABEL,
IFLA_VXLAN_GPE, IFLA_VXLAN_GPE,
IFLA_VXLAN_TTL_INHERIT,
__IFLA_VXLAN_MAX __IFLA_VXLAN_MAX
}; };
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment