geneve: Fix incorrect inner network header offset when innerprotoinherit is set
[ Upstream commit c6ae073f5903f6c6439d0ac855836a4da5c0a701 ] When innerprotoinherit is set, the tunneled packets do not have an inner Ethernet header. Change 'maclen' to not always assume the header length is ETH_HLEN, as there might not be a MAC header. This resolves issues with drivers (e.g. mlx5, in mlx5e_tx_tunnel_accel()) who rely on the skb inner network header offset to be correct, and use it for TX offloads. Fixes: d8a6213d70ac ("geneve: fix header validation in geneve[6]_xmit_skb") Signed-off-by: Gal Pressman <gal@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net> Stable-dep-of: c471236b2359 ("bareudp: Pull inner IP header on xmit.") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
0315c150d1
commit
08dc6b0262
2 changed files with 9 additions and 6 deletions
|
@ -912,6 +912,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
struct geneve_dev *geneve,
|
||||
const struct ip_tunnel_info *info)
|
||||
{
|
||||
bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
|
||||
bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
|
||||
struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
|
||||
const struct ip_tunnel_key *key = &info->key;
|
||||
|
@ -923,7 +924,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
__be16 sport;
|
||||
int err;
|
||||
|
||||
if (!skb_vlan_inet_prepare(skb))
|
||||
if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
|
||||
return -EINVAL;
|
||||
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
|
@ -996,7 +997,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
}
|
||||
|
||||
err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
|
||||
geneve->cfg.inner_proto_inherit);
|
||||
inner_proto_inherit);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
|
@ -1012,6 +1013,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
struct geneve_dev *geneve,
|
||||
const struct ip_tunnel_info *info)
|
||||
{
|
||||
bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
|
||||
bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
|
||||
struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
|
||||
const struct ip_tunnel_key *key = &info->key;
|
||||
|
@ -1021,7 +1023,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
__be16 sport;
|
||||
int err;
|
||||
|
||||
if (!skb_vlan_inet_prepare(skb))
|
||||
if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
|
||||
return -EINVAL;
|
||||
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
|
@ -1076,7 +1078,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
|||
ttl = ttl ? : ip6_dst_hoplimit(dst);
|
||||
}
|
||||
err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
|
||||
geneve->cfg.inner_proto_inherit);
|
||||
inner_proto_inherit);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
|
|
|
@ -335,9 +335,10 @@ static inline bool pskb_inet_may_pull(struct sk_buff *skb)
|
|||
|
||||
/* Variant of pskb_inet_may_pull().
|
||||
*/
|
||||
static inline bool skb_vlan_inet_prepare(struct sk_buff *skb)
|
||||
static inline bool skb_vlan_inet_prepare(struct sk_buff *skb,
|
||||
bool inner_proto_inherit)
|
||||
{
|
||||
int nhlen = 0, maclen = ETH_HLEN;
|
||||
int nhlen = 0, maclen = inner_proto_inherit ? 0 : ETH_HLEN;
|
||||
__be16 type = skb->protocol;
|
||||
|
||||
/* Essentially this is skb_protocol(skb, true)
|
||||
|
|
Loading…
Reference in a new issue