2022-07-11 10:17:47

by Matthias May

[permalink] [raw]
Subject: [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP

Currently IPv4 and IPv6 tunnels are able to inherit IP header fields
like TOS, TTL or the DF from their payload, when the payload is IPv4
or IPv6. Some types of tunnels, like GRETAP or VXLAN are able to carry
VLANs. The visible skb->protocol shows in this case as protocol
ETH_P_8021Q or ETH_P_8021AD. However all the relevant structures for IP
payload are correct and just need to be used.

Patch 1 allows tunnels with IPv4 as outer header to inherit from VLAN
encapsulated payload.
Patch 2 fixes a bug, where the DSCP for tunnels with IPv6 as outer header
is never set.
Patch 3 allows tunnels with IPv6 as outer header to inherit the TTL from
VLAN encapsulated payload.
Patch 4 allows IP6GRETAP tunnels with IPv6 as outer header to inherit the
TOS from VLAN encapsulated payload.

Matthias May (4):
ip_tunnel: allow to inherit from VLAN encapsulated IP
ip6_gre: set DSCP for non-IP
ip6_gre: use actual protocol to select xmit
ip6_tunnel: allow to inherit from VLAN encapsulated IP

net/ipv4/ip_tunnel.c | 17 +++++++++--------
net/ipv6/ip6_gre.c | 43 +++++++++++++++++++++++++++++++++++--------
net/ipv6/ip6_tunnel.c | 11 +++++++----
3 files changed, 51 insertions(+), 20 deletions(-)

--
2.35.1


2022-07-11 10:18:13

by Matthias May

[permalink] [raw]
Subject: [PATCH 4/4 net-next] ip6_tunnel: allow to inherit from VLAN encapsulated IP

The current code allows to inherit the TTL (hop_limit) from the
payload when skb->protocol is ETH_P_IP or ETH_P_IPV6.
However when the payload is VLAN encapsulated (e.g because the tunnel
is of type GRETAP), then this inheriting does not work, because the
visible skb->protocol is of type ETH_P_8021Q or ETH_P_8021AD.

Instead of skb->protocol, use skb_protocol().

Signed-off-by: Matthias May <[email protected]>
---
net/ipv6/ip6_tunnel.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 19325b7600bb..4244a66eb859 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1085,10 +1085,13 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
unsigned int eth_hlen = t->dev->type == ARPHRD_ETHER ? ETH_HLEN : 0;
unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen;
unsigned int max_headroom = psh_hlen;
+ __be16 payload_protocol;
bool use_cache = false;
u8 hop_limit;
int err = -1;

+ payload_protocol = skb_protocol(skb, true);
+
if (t->parms.collect_md) {
hop_limit = skb_tunnel_info(skb)->key.ttl;
goto route_lookup;
@@ -1098,7 +1101,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,

/* NBMA tunnel */
if (ipv6_addr_any(&t->parms.raddr)) {
- if (skb->protocol == htons(ETH_P_IPV6)) {
+ if (payload_protocol == htons(ETH_P_IPV6)) {
struct in6_addr *addr6;
struct neighbour *neigh;
int addr_type;
@@ -1119,7 +1122,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,

memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
neigh_release(neigh);
- } else if (skb->protocol == htons(ETH_P_IP)) {
+ } else if (payload_protocol == htons(ETH_P_IP)) {
const struct rtable *rt = skb_rtable(skb);

if (!rt)
@@ -1230,9 +1233,9 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
skb_dst_set(skb, dst);

if (hop_limit == 0) {
- if (skb->protocol == htons(ETH_P_IP))
+ if (payload_protocol == htons(ETH_P_IP))
hop_limit = ip_hdr(skb)->ttl;
- else if (skb->protocol == htons(ETH_P_IPV6))
+ else if (payload_protocol == htons(ETH_P_IPV6))
hop_limit = ipv6_hdr(skb)->hop_limit;
else
hop_limit = ip6_dst_hoplimit(dst);
--
2.35.1

2022-07-11 10:35:32

by Matthias May

[permalink] [raw]
Subject: [PATCH 3/4 net-next] ip6_gre: use actual protocol to select xmit

When the payload is a VLAN encapsulated IPv6/IPv6 frame, we can
skip the 802.1q/802.1ad ethertypes and jump to the actual protocol.
This way we treat IPv4/IPv6 frames as IP instead of as "other".

Signed-off-by: Matthias May <[email protected]>
---
net/ipv6/ip6_gre.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 5fe0db88bea8..cd0202016da0 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -916,6 +916,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
{
struct ip6_tnl *t = netdev_priv(dev);
struct net_device_stats *stats = &t->dev->stats;
+ __be16 payload_protocol;
int ret;

if (!pskb_inet_may_pull(skb))
@@ -924,7 +925,8 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
goto tx_err;

- switch (skb->protocol) {
+ payload_protocol = skb_protocol(skb, true);
+ switch (payload_protocol) {
case htons(ETH_P_IP):
ret = ip6gre_xmit_ipv4(skb, dev);
break;
--
2.35.1

2022-07-13 11:56:28

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP

Hello:

This series was applied to netdev/net-next.git (master)
by David S. Miller <[email protected]>:

On Mon, 11 Jul 2022 11:17:18 +0200 you wrote:
> Currently IPv4 and IPv6 tunnels are able to inherit IP header fields
> like TOS, TTL or the DF from their payload, when the payload is IPv4
> or IPv6. Some types of tunnels, like GRETAP or VXLAN are able to carry
> VLANs. The visible skb->protocol shows in this case as protocol
> ETH_P_8021Q or ETH_P_8021AD. However all the relevant structures for IP
> payload are correct and just need to be used.
>
> [...]

Here is the summary with links:
- [1/4,v3,net-next] ip_tunnel: allow to inherit from VLAN encapsulated IP
https://git.kernel.org/netdev/net-next/c/7ae29fd1be43
- [2/4,net-next] ip6_gre: set DSCP for non-IP
https://git.kernel.org/netdev/net-next/c/41337f52b967
- [3/4,net-next] ip6_gre: use actual protocol to select xmit
https://git.kernel.org/netdev/net-next/c/3f8a8447fd0b
- [4/4,net-next] ip6_tunnel: allow to inherit from VLAN encapsulated IP
https://git.kernel.org/netdev/net-next/c/b09ab9c92e50

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html