* [PATCH 1/4 v3 net-next] ip_tunnel: allow to inherit from VLAN encapsulated IP
2022-07-11 9:17 [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP Matthias May
@ 2022-07-11 9:17 ` Matthias May
2022-07-11 9:17 ` [PATCH 2/4 net-next] ip6_gre: set DSCP for non-IP Matthias May
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Matthias May @ 2022-07-11 9:17 UTC (permalink / raw)
To: netdev
Cc: davem, yoshfuji, dsahern, edumazet, kuba, pabeni, linux-kernel,
Matthias May
The current code allows to inherit the TOS, TTL, DF 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 <matthias.may@westermo.com>
---
v2 -> v3:
- Instead of manual parsing, use skb_protocol() as suggested by Eyal Birger
v1 -> v2:
- Add support for ETH_P_8021AD as suggested by Jakub Kicinski.
---
net/ipv4/ip_tunnel.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 94017a8c3994..dbe18c16b9f6 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -641,6 +641,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
const struct iphdr *inner_iph;
unsigned int max_headroom; /* The extra header space needed */
struct rtable *rt = NULL; /* Route to the other host */
+ __be16 payload_protocol;
bool use_cache = false;
struct flowi4 fl4;
bool md = false;
@@ -651,6 +652,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
connected = (tunnel->parms.iph.daddr != 0);
+ payload_protocol = skb_protocol(skb, true);
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
@@ -670,13 +672,12 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
dst = tun_info->key.u.ipv4.dst;
md = true;
connected = true;
- }
- else if (skb->protocol == htons(ETH_P_IP)) {
+ } else if (payload_protocol == htons(ETH_P_IP)) {
rt = skb_rtable(skb);
dst = rt_nexthop(rt, inner_iph->daddr);
}
#if IS_ENABLED(CONFIG_IPV6)
- else if (skb->protocol == htons(ETH_P_IPV6)) {
+ else if (payload_protocol == htons(ETH_P_IPV6)) {
const struct in6_addr *addr6;
struct neighbour *neigh;
bool do_tx_error_icmp;
@@ -716,10 +717,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
tos = tnl_params->tos;
if (tos & 0x1) {
tos &= ~0x1;
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (payload_protocol == htons(ETH_P_IP)) {
tos = inner_iph->tos;
connected = false;
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ } else if (payload_protocol == htons(ETH_P_IPV6)) {
tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
connected = false;
}
@@ -765,7 +766,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
}
df = tnl_params->frag_off;
- if (skb->protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
+ if (payload_protocol == htons(ETH_P_IP) && !tunnel->ignore_df)
df |= (inner_iph->frag_off & htons(IP_DF));
if (tnl_update_pmtu(dev, skb, rt, df, inner_iph, 0, 0, false)) {
@@ -786,10 +787,10 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
tos = ip_tunnel_ecn_encap(tos, inner_iph, skb);
ttl = tnl_params->ttl;
if (ttl == 0) {
- if (skb->protocol == htons(ETH_P_IP))
+ if (payload_protocol == htons(ETH_P_IP))
ttl = inner_iph->ttl;
#if IS_ENABLED(CONFIG_IPV6)
- else if (skb->protocol == htons(ETH_P_IPV6))
+ else if (payload_protocol == htons(ETH_P_IPV6))
ttl = ((const struct ipv6hdr *)inner_iph)->hop_limit;
#endif
else
--
2.35.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/4 net-next] ip6_gre: set DSCP for non-IP
2022-07-11 9:17 [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP Matthias May
2022-07-11 9:17 ` [PATCH 1/4 v3 net-next] ip_tunnel: allow " Matthias May
@ 2022-07-11 9:17 ` Matthias May
2022-07-11 9:17 ` [PATCH 3/4 net-next] ip6_gre: use actual protocol to select xmit Matthias May
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Matthias May @ 2022-07-11 9:17 UTC (permalink / raw)
To: netdev
Cc: davem, yoshfuji, dsahern, edumazet, kuba, pabeni, linux-kernel,
Matthias May
The current code always forces a dscp of 0 for all non-IP frames.
However when setting a specific TOS with the command
ip link add name tep0 type ip6gretap local fdd1:ced0:5d88:3fce::1
remote fdd1:ced0:5d88:3fce::2 tos 0xa0
one would expect all GRE encapsulated frames to have a TOS of 0xA0.
and not only when the payload is IPv4/IPv6.
Signed-off-by: Matthias May <matthias.may@westermo.com>
---
net/ipv6/ip6_gre.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index a9051df0625d..5fe0db88bea8 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -701,6 +701,33 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *skb,
return 0;
}
+static int prepare_ip6gre_xmit_other(struct sk_buff *skb,
+ struct net_device *dev,
+ struct flowi6 *fl6, __u8 *dsfield,
+ int *encap_limit)
+{
+ struct ip6_tnl *t = netdev_priv(dev);
+
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+ *encap_limit = t->parms.encap_limit;
+
+ memcpy(fl6, &t->fl.u.ip6, sizeof(*fl6));
+
+ if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
+ *dsfield = 0;
+ else
+ *dsfield = ip6_tclass(t->parms.flowinfo);
+
+ if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
+ fl6->flowi6_mark = skb->mark;
+ else
+ fl6->flowi6_mark = t->parms.fwmark;
+
+ fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
+
+ return 0;
+}
+
static struct ip_tunnel_info *skb_tunnel_info_txcheck(struct sk_buff *skb)
{
struct ip_tunnel_info *tun_info;
@@ -868,20 +895,18 @@ static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev)
struct ip6_tnl *t = netdev_priv(dev);
int encap_limit = -1;
struct flowi6 fl6;
+ __u8 dsfield = 0;
__u32 mtu;
int err;
- if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
- encap_limit = t->parms.encap_limit;
-
- if (!t->parms.collect_md)
- memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
+ if (!t->parms.collect_md &&
+ prepare_ip6gre_xmit_other(skb, dev, &fl6, &dsfield, &encap_limit))
+ return -1;
err = gre_handle_offloads(skb, !!(t->parms.o_flags & TUNNEL_CSUM));
if (err)
return err;
-
- err = __gre6_xmit(skb, dev, 0, &fl6, encap_limit, &mtu, skb->protocol);
+ err = __gre6_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu, skb->protocol);
return err;
}
--
2.35.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/4 net-next] ip6_gre: use actual protocol to select xmit
2022-07-11 9:17 [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP Matthias May
2022-07-11 9:17 ` [PATCH 1/4 v3 net-next] ip_tunnel: allow " Matthias May
2022-07-11 9:17 ` [PATCH 2/4 net-next] ip6_gre: set DSCP for non-IP Matthias May
@ 2022-07-11 9:17 ` Matthias May
2022-07-11 9:17 ` [PATCH 4/4 net-next] ip6_tunnel: allow to inherit from VLAN encapsulated IP Matthias May
2022-07-13 11:20 ` [PATCH 0/4 net-next] Allow " patchwork-bot+netdevbpf
4 siblings, 0 replies; 6+ messages in thread
From: Matthias May @ 2022-07-11 9:17 UTC (permalink / raw)
To: netdev
Cc: davem, yoshfuji, dsahern, edumazet, kuba, pabeni, linux-kernel,
Matthias May
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 <matthias.may@westermo.com>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/4 net-next] ip6_tunnel: allow to inherit from VLAN encapsulated IP
2022-07-11 9:17 [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP Matthias May
` (2 preceding siblings ...)
2022-07-11 9:17 ` [PATCH 3/4 net-next] ip6_gre: use actual protocol to select xmit Matthias May
@ 2022-07-11 9:17 ` Matthias May
2022-07-13 11:20 ` [PATCH 0/4 net-next] Allow " patchwork-bot+netdevbpf
4 siblings, 0 replies; 6+ messages in thread
From: Matthias May @ 2022-07-11 9:17 UTC (permalink / raw)
To: netdev
Cc: davem, yoshfuji, dsahern, edumazet, kuba, pabeni, linux-kernel,
Matthias May
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 <matthias.may@westermo.com>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP
2022-07-11 9:17 [PATCH 0/4 net-next] Allow to inherit from VLAN encapsulated IP Matthias May
` (3 preceding siblings ...)
2022-07-11 9:17 ` [PATCH 4/4 net-next] ip6_tunnel: allow to inherit from VLAN encapsulated IP Matthias May
@ 2022-07-13 11:20 ` patchwork-bot+netdevbpf
4 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-07-13 11:20 UTC (permalink / raw)
To: Matthias May
Cc: netdev, davem, yoshfuji, dsahern, edumazet, kuba, pabeni,
linux-kernel
Hello:
This series was applied to netdev/net-next.git (master)
by David S. Miller <davem@davemloft.net>:
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
^ permalink raw reply [flat|nested] 6+ messages in thread