geneve: add ttl inherit support
Similar with commit 72f6d71e49
("vxlan: add ttl inherit support"),
currently ttl == 0 means "use whatever default value" on geneve instead
of inherit inner ttl. To respect compatibility with old behavior, let's
add a new IFLA_GENEVE_TTL_INHERIT for geneve ttl inherit support.
Reported-by: Jianlin Shi <jishi@redhat.com>
Suggested-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d700ec4118
commit
52d0d404d3
@ -69,6 +69,7 @@ struct geneve_dev {
|
|||||||
struct gro_cells gro_cells;
|
struct gro_cells gro_cells;
|
||||||
bool collect_md;
|
bool collect_md;
|
||||||
bool use_udp6_rx_checksums;
|
bool use_udp6_rx_checksums;
|
||||||
|
bool ttl_inherit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct geneve_sock {
|
struct geneve_sock {
|
||||||
@ -843,7 +844,11 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||||||
ttl = key->ttl;
|
ttl = key->ttl;
|
||||||
} else {
|
} else {
|
||||||
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
|
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
|
||||||
ttl = key->ttl ? : ip4_dst_hoplimit(&rt->dst);
|
if (geneve->ttl_inherit)
|
||||||
|
ttl = ip_tunnel_get_ttl(ip_hdr(skb), skb);
|
||||||
|
else
|
||||||
|
ttl = key->ttl;
|
||||||
|
ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
|
||||||
}
|
}
|
||||||
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
||||||
|
|
||||||
@ -889,7 +894,11 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||||||
} else {
|
} else {
|
||||||
prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
|
prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
|
||||||
ip_hdr(skb), skb);
|
ip_hdr(skb), skb);
|
||||||
ttl = key->ttl ? : ip6_dst_hoplimit(dst);
|
if (geneve->ttl_inherit)
|
||||||
|
ttl = ip_tunnel_get_ttl(ip_hdr(skb), skb);
|
||||||
|
else
|
||||||
|
ttl = key->ttl;
|
||||||
|
ttl = ttl ? : ip6_dst_hoplimit(dst);
|
||||||
}
|
}
|
||||||
err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr));
|
err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr));
|
||||||
if (unlikely(err))
|
if (unlikely(err))
|
||||||
@ -1091,6 +1100,7 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
|
|||||||
[IFLA_GENEVE_UDP_CSUM] = { .type = NLA_U8 },
|
[IFLA_GENEVE_UDP_CSUM] = { .type = NLA_U8 },
|
||||||
[IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
|
[IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
|
||||||
[IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
|
[IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
|
||||||
|
[IFLA_GENEVE_TTL_INHERIT] = { .type = NLA_U8 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
|
static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||||
@ -1170,7 +1180,8 @@ static bool geneve_dst_addr_equal(struct ip_tunnel_info *a,
|
|||||||
static int geneve_configure(struct net *net, struct net_device *dev,
|
static int geneve_configure(struct net *net, struct net_device *dev,
|
||||||
struct netlink_ext_ack *extack,
|
struct netlink_ext_ack *extack,
|
||||||
const struct ip_tunnel_info *info,
|
const struct ip_tunnel_info *info,
|
||||||
bool metadata, bool ipv6_rx_csum)
|
bool metadata, bool ipv6_rx_csum,
|
||||||
|
bool ttl_inherit)
|
||||||
{
|
{
|
||||||
struct geneve_net *gn = net_generic(net, geneve_net_id);
|
struct geneve_net *gn = net_generic(net, geneve_net_id);
|
||||||
struct geneve_dev *t, *geneve = netdev_priv(dev);
|
struct geneve_dev *t, *geneve = netdev_priv(dev);
|
||||||
@ -1219,6 +1230,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
|
|||||||
geneve->info = *info;
|
geneve->info = *info;
|
||||||
geneve->collect_md = metadata;
|
geneve->collect_md = metadata;
|
||||||
geneve->use_udp6_rx_checksums = ipv6_rx_csum;
|
geneve->use_udp6_rx_checksums = ipv6_rx_csum;
|
||||||
|
geneve->ttl_inherit = ttl_inherit;
|
||||||
|
|
||||||
err = register_netdevice(dev);
|
err = register_netdevice(dev);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1237,7 +1249,8 @@ static void init_tnl_info(struct ip_tunnel_info *info, __u16 dst_port)
|
|||||||
static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
|
static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
|
||||||
struct netlink_ext_ack *extack,
|
struct netlink_ext_ack *extack,
|
||||||
struct ip_tunnel_info *info, bool *metadata,
|
struct ip_tunnel_info *info, bool *metadata,
|
||||||
bool *use_udp6_rx_checksums, bool changelink)
|
bool *use_udp6_rx_checksums, bool *ttl_inherit,
|
||||||
|
bool changelink)
|
||||||
{
|
{
|
||||||
int attrtype;
|
int attrtype;
|
||||||
|
|
||||||
@ -1315,6 +1328,9 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
|
|||||||
if (data[IFLA_GENEVE_TTL])
|
if (data[IFLA_GENEVE_TTL])
|
||||||
info->key.ttl = nla_get_u8(data[IFLA_GENEVE_TTL]);
|
info->key.ttl = nla_get_u8(data[IFLA_GENEVE_TTL]);
|
||||||
|
|
||||||
|
if (data[IFLA_GENEVE_TTL_INHERIT])
|
||||||
|
*ttl_inherit = true;
|
||||||
|
|
||||||
if (data[IFLA_GENEVE_TOS])
|
if (data[IFLA_GENEVE_TOS])
|
||||||
info->key.tos = nla_get_u8(data[IFLA_GENEVE_TOS]);
|
info->key.tos = nla_get_u8(data[IFLA_GENEVE_TOS]);
|
||||||
|
|
||||||
@ -1438,17 +1454,18 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
|
|||||||
{
|
{
|
||||||
bool use_udp6_rx_checksums = false;
|
bool use_udp6_rx_checksums = false;
|
||||||
struct ip_tunnel_info info;
|
struct ip_tunnel_info info;
|
||||||
|
bool ttl_inherit = false;
|
||||||
bool metadata = false;
|
bool metadata = false;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
init_tnl_info(&info, GENEVE_UDP_PORT);
|
init_tnl_info(&info, GENEVE_UDP_PORT);
|
||||||
err = geneve_nl2info(tb, data, extack, &info, &metadata,
|
err = geneve_nl2info(tb, data, extack, &info, &metadata,
|
||||||
&use_udp6_rx_checksums, false);
|
&use_udp6_rx_checksums, &ttl_inherit, false);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = geneve_configure(net, dev, extack, &info, metadata,
|
err = geneve_configure(net, dev, extack, &info, metadata,
|
||||||
use_udp6_rx_checksums);
|
use_udp6_rx_checksums, ttl_inherit);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -1511,6 +1528,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
|
|||||||
struct ip_tunnel_info info;
|
struct ip_tunnel_info info;
|
||||||
bool metadata;
|
bool metadata;
|
||||||
bool use_udp6_rx_checksums;
|
bool use_udp6_rx_checksums;
|
||||||
|
bool ttl_inherit;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* If the geneve device is configured for metadata (or externally
|
/* If the geneve device is configured for metadata (or externally
|
||||||
@ -1523,8 +1541,9 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
|
|||||||
memcpy(&info, &geneve->info, sizeof(info));
|
memcpy(&info, &geneve->info, sizeof(info));
|
||||||
metadata = geneve->collect_md;
|
metadata = geneve->collect_md;
|
||||||
use_udp6_rx_checksums = geneve->use_udp6_rx_checksums;
|
use_udp6_rx_checksums = geneve->use_udp6_rx_checksums;
|
||||||
|
ttl_inherit = geneve->ttl_inherit;
|
||||||
err = geneve_nl2info(tb, data, extack, &info, &metadata,
|
err = geneve_nl2info(tb, data, extack, &info, &metadata,
|
||||||
&use_udp6_rx_checksums, true);
|
&use_udp6_rx_checksums, &ttl_inherit, true);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -1537,6 +1556,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
|
|||||||
geneve->info = info;
|
geneve->info = info;
|
||||||
geneve->collect_md = metadata;
|
geneve->collect_md = metadata;
|
||||||
geneve->use_udp6_rx_checksums = use_udp6_rx_checksums;
|
geneve->use_udp6_rx_checksums = use_udp6_rx_checksums;
|
||||||
|
geneve->ttl_inherit = ttl_inherit;
|
||||||
geneve_unquiesce(geneve, gs4, gs6);
|
geneve_unquiesce(geneve, gs4, gs6);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1562,6 +1582,7 @@ static size_t geneve_get_size(const struct net_device *dev)
|
|||||||
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_CSUM */
|
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_CSUM */
|
||||||
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_ZERO_CSUM6_TX */
|
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_ZERO_CSUM6_TX */
|
||||||
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_ZERO_CSUM6_RX */
|
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_UDP_ZERO_CSUM6_RX */
|
||||||
|
nla_total_size(sizeof(__u8)) + /* IFLA_GENEVE_TTL_INHERIT */
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1569,6 +1590,7 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct geneve_dev *geneve = netdev_priv(dev);
|
struct geneve_dev *geneve = netdev_priv(dev);
|
||||||
struct ip_tunnel_info *info = &geneve->info;
|
struct ip_tunnel_info *info = &geneve->info;
|
||||||
|
bool ttl_inherit = geneve->ttl_inherit;
|
||||||
bool metadata = geneve->collect_md;
|
bool metadata = geneve->collect_md;
|
||||||
__u8 tmp_vni[3];
|
__u8 tmp_vni[3];
|
||||||
__u32 vni;
|
__u32 vni;
|
||||||
@ -1614,6 +1636,9 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
|||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (nla_put_u8(skb, IFLA_GENEVE_TTL_INHERIT, ttl_inherit))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
@ -1650,7 +1675,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
|
|||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
init_tnl_info(&info, dst_port);
|
init_tnl_info(&info, dst_port);
|
||||||
err = geneve_configure(net, dev, NULL, &info, true, true);
|
err = geneve_configure(net, dev, NULL, &info, true, true, false);
|
||||||
if (err) {
|
if (err) {
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
@ -555,6 +555,7 @@ enum {
|
|||||||
IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
|
IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
|
||||||
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
|
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
|
||||||
IFLA_GENEVE_LABEL,
|
IFLA_GENEVE_LABEL,
|
||||||
|
IFLA_GENEVE_TTL_INHERIT,
|
||||||
__IFLA_GENEVE_MAX
|
__IFLA_GENEVE_MAX
|
||||||
};
|
};
|
||||||
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
|
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
|
||||||
|
@ -542,6 +542,7 @@ enum {
|
|||||||
IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
|
IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
|
||||||
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
|
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
|
||||||
IFLA_GENEVE_LABEL,
|
IFLA_GENEVE_LABEL,
|
||||||
|
IFLA_GENEVE_TTL_INHERIT,
|
||||||
__IFLA_GENEVE_MAX
|
__IFLA_GENEVE_MAX
|
||||||
};
|
};
|
||||||
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
|
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user