summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorMatthias May <matthias.may@westermo.com>2022-07-11 11:17:20 +0200
committerDavid S. Miller <davem@davemloft.net>2022-07-13 12:10:22 +0100
commit41337f52b967b09a7a2cb34ecfce6dd71e5ab4f6 (patch)
tree40a1ae5edddfb92292399f8cb3d0a635dc36ac16 /net/ipv6
parent7ae29fd1be431763041f52b8bca017b76cb7b06d (diff)
downloadlinux-41337f52b967b09a7a2cb34ecfce6dd71e5ab4f6.tar.gz
linux-41337f52b967b09a7a2cb34ecfce6dd71e5ab4f6.tar.bz2
linux-41337f52b967b09a7a2cb34ecfce6dd71e5ab4f6.zip
ip6_gre: set DSCP for non-IP
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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_gre.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 1bd10ae332e8..f0aeca609ab7 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;
}