diff options
| author | Guillaume Nault <gnault@redhat.com> | 2025-08-25 15:37:43 +0200 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-08-26 17:34:31 -0700 |
| commit | 1bec9d0c0046fe4e2bfb6a1c5aadcb5d56cdb0fb (patch) | |
| tree | a516f54685a0fdf9b85fe042ff7ae2cffa097892 /drivers/net | |
| parent | dded99427d1a1e753e9554ebc9f27604154277ca (diff) | |
ipv4: Convert ->flowi4_tos to dscp_t.
Convert the ->flowic_tos field of struct flowi_common from __u8 to
dscp_t, rename it ->flowic_dscp and propagate these changes to struct
flowi and struct flowi4.
We've had several bugs in the past where ECN bits could interfere with
IPv4 routing, because these bits were not properly cleared when setting
->flowi4_tos. These bugs should be fixed now and the dscp_t type has
been introduced to ensure that variables carrying DSCP values don't
accidentally have any ECN bits set. Several variables and structure
fields have been converted to dscp_t already, but the main IPv4 routing
structure, struct flowi4, is still using a __u8. To avoid any future
regression, this patch converts it to dscp_t.
There are many users to convert at once. Fortunately, around half of
->flowi4_tos users already have a dscp_t value at hand, which they
currently convert to __u8 using inet_dscp_to_dsfield(). For all of
these users, we just need to drop that conversion.
But, although we try to do the __u8 <-> dscp_t conversions at the
boundaries of the network or of user space, some places still store
TOS/DSCP variables as __u8 in core networking code. Those can hardly be
converted either because the data structure is part of UAPI or because
the same variable or field is also used for handling ECN in other parts
of the code. In all of these cases where we don't have a dscp_t
variable at hand, we need to use inet_dsfield_to_dscp() when
interacting with ->flowi4_dscp.
Changes since v1:
* Fix space alignment in __bpf_redirect_neigh_v4() (Ido).
Signed-off-by: Guillaume Nault <gnault@redhat.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/29acecb45e911d17446b9a3dbdb1ab7b821ea371.1756128932.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/amt.c | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/tc_encap_actions.c | 4 | ||||
| -rw-r--r-- | drivers/net/gtp.c | 7 | ||||
| -rw-r--r-- | drivers/net/ipvlan/ipvlan_core.c | 4 | ||||
| -rw-r--r-- | drivers/net/vrf.c | 4 |
6 files changed, 19 insertions, 13 deletions
diff --git a/drivers/net/amt.c b/drivers/net/amt.c index ed86537b2f61..902c817a0dea 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -11,6 +11,7 @@ #include <linux/net.h> #include <linux/igmp.h> #include <linux/workqueue.h> +#include <net/flow.h> #include <net/pkt_sched.h> #include <net/net_namespace.h> #include <net/ip.h> @@ -28,6 +29,7 @@ #include <net/addrconf.h> #include <net/ip6_route.h> #include <net/inet_common.h> +#include <net/inet_dscp.h> #include <net/ip6_checksum.h> static struct workqueue_struct *amt_wq; @@ -1018,7 +1020,7 @@ static bool amt_send_membership_update(struct amt_dev *amt, fl4.flowi4_oif = amt->stream_dev->ifindex; fl4.daddr = amt->remote_ip; fl4.saddr = amt->local_ip; - fl4.flowi4_tos = AMT_TOS; + fl4.flowi4_dscp = inet_dsfield_to_dscp(AMT_TOS); fl4.flowi4_proto = IPPROTO_UDP; rt = ip_route_output_key(amt->net, &fl4); if (IS_ERR(rt)) { @@ -1133,7 +1135,7 @@ static bool amt_send_membership_query(struct amt_dev *amt, fl4.flowi4_oif = amt->stream_dev->ifindex; fl4.daddr = tunnel->ip4; fl4.saddr = amt->local_ip; - fl4.flowi4_tos = AMT_TOS; + fl4.flowi4_dscp = inet_dsfield_to_dscp(AMT_TOS); fl4.flowi4_proto = IPPROTO_UDP; rt = ip_route_output_key(amt->net, &fl4); if (IS_ERR(rt)) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c index 2162d776fe35..a14f216048cd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* Copyright (c) 2018 Mellanox Technologies. */ -#include <net/inet_ecn.h> +#include <net/flow.h> +#include <net/inet_dscp.h> #include <net/vxlan.h> #include <net/gre.h> #include <net/geneve.h> @@ -233,7 +234,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, int err; /* add the IP fields */ - attr.fl.fl4.flowi4_tos = tun_key->tos & ~INET_ECN_MASK; + attr.fl.fl4.flowi4_dscp = inet_dsfield_to_dscp(tun_key->tos); attr.fl.fl4.daddr = tun_key->u.ipv4.dst; attr.fl.fl4.saddr = tun_key->u.ipv4.src; attr.ttl = tun_key->ttl; @@ -349,7 +350,7 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, int err; /* add the IP fields */ - attr.fl.fl4.flowi4_tos = tun_key->tos & ~INET_ECN_MASK; + attr.fl.fl4.flowi4_dscp = inet_dsfield_to_dscp(tun_key->tos); attr.fl.fl4.daddr = tun_key->u.ipv4.dst; attr.fl.fl4.saddr = tun_key->u.ipv4.src; attr.ttl = tun_key->ttl; diff --git a/drivers/net/ethernet/sfc/tc_encap_actions.c b/drivers/net/ethernet/sfc/tc_encap_actions.c index e872f926e438..eef06e48185d 100644 --- a/drivers/net/ethernet/sfc/tc_encap_actions.c +++ b/drivers/net/ethernet/sfc/tc_encap_actions.c @@ -11,6 +11,8 @@ #include "tc_encap_actions.h" #include "tc.h" #include "mae.h" +#include <net/flow.h> +#include <net/inet_dscp.h> #include <net/vxlan.h> #include <net/geneve.h> #include <net/netevent.h> @@ -99,7 +101,7 @@ static int efx_bind_neigh(struct efx_nic *efx, case EFX_ENCAP_TYPE_GENEVE: flow4.flowi4_proto = IPPROTO_UDP; flow4.fl4_dport = encap->key.tp_dst; - flow4.flowi4_tos = encap->key.tos; + flow4.flowi4_dscp = inet_dsfield_to_dscp(encap->key.tos); flow4.daddr = encap->key.u.ipv4.dst; flow4.saddr = encap->key.u.ipv4.src; break; diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 4b668ebaa0f7..5cb59d72bc82 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -21,9 +21,10 @@ #include <linux/file.h> #include <linux/gtp.h> +#include <net/flow.h> +#include <net/inet_dscp.h> #include <net/net_namespace.h> #include <net/protocol.h> -#include <net/inet_dscp.h> #include <net/inet_sock.h> #include <net/ip.h> #include <net/ipv6.h> @@ -352,7 +353,7 @@ static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4, fl4->flowi4_oif = sk->sk_bound_dev_if; fl4->daddr = daddr; fl4->saddr = saddr; - fl4->flowi4_tos = inet_dscp_to_dsfield(inet_sk_dscp(inet_sk(sk))); + fl4->flowi4_dscp = inet_sk_dscp(inet_sk(sk)); fl4->flowi4_scope = ip_sock_rt_scope(sk); fl4->flowi4_proto = sk->sk_protocol; @@ -2401,7 +2402,7 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) udp_tunnel_xmit_skb(rt, sk, skb_to_send, fl4.saddr, fl4.daddr, - fl4.flowi4_tos, + inet_dscp_to_dsfield(fl4.flowi4_dscp), ip4_dst_hoplimit(&rt->dst), 0, port, port, diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index e3e65772c599..d7e3ddbcab6f 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -2,7 +2,7 @@ /* Copyright (c) 2014 Mahesh Bandewar <maheshb@google.com> */ -#include <net/inet_dscp.h> +#include <net/flow.h> #include <net/ip.h> #include "ipvlan.h" @@ -433,7 +433,7 @@ static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) ip4h = ip_hdr(skb); fl4.daddr = ip4h->daddr; fl4.saddr = ip4h->saddr; - fl4.flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h)); + fl4.flowi4_dscp = ip4h_dscp(ip4h); rt = ip_route_output_flow(net, &fl4, NULL); if (IS_ERR(rt)) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 3ccd649913b5..571847a7f86d 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -26,6 +26,7 @@ #include <linux/inetdevice.h> #include <net/arp.h> +#include <net/flow.h> #include <net/ip.h> #include <net/ip_fib.h> #include <net/ip6_fib.h> @@ -38,7 +39,6 @@ #include <net/sch_generic.h> #include <net/netns/generic.h> #include <net/netfilter/nf_conntrack.h> -#include <net/inet_dscp.h> #define DRV_NAME "vrf" #define DRV_VERSION "1.1" @@ -505,7 +505,7 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb, /* needed to match OIF rule */ fl4.flowi4_l3mdev = vrf_dev->ifindex; fl4.flowi4_iif = LOOPBACK_IFINDEX; - fl4.flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp(ip4h)); + fl4.flowi4_dscp = ip4h_dscp(ip4h); fl4.flowi4_flags = FLOWI_FLAG_ANYSRC; fl4.flowi4_proto = ip4h->protocol; fl4.daddr = ip4h->daddr; |
