xfrm: Convert __xfrm4_dst_lookup() and its callers to dscp_t.
Subsystems (3)
cover xfrm: Convert __xfrm4_dst_lookup() and its callers to dscp_t.
This patch series continues to prepare users of ->flowi4_tos to a future conversion of this field (__u8 to dscp_t). This time, we convert __xfrm4_dst_lookup() and its call chain.
The objective is to eventually make all users of ->flowi4_tos use a dscp_t value. Making ->flowi4_tos a dscp_t field will help avoiding regressions where ECN bits are erroneously interpreted as DSCP bits.
Guillaume Nault (6):
xfrm: Convert xfrm_get_tos() to dscp_t.
xfrm: Convert xfrm_bundle_create() to dscp_t.
xfrm: Convert xfrm_dst_lookup() to dscp_t.
xfrm: Convert __xfrm_dst_lookup() to dscp_t.
xfrm: Convert the ->dst_lookup() callback to dscp_t.
xfrm: Convert __xfrm4_dst_lookup() to dscp_t.
include/net/xfrm.h | 7 ++++--- net/ipv4/xfrm4_policy.c | 14 ++++++++------ net/ipv6/xfrm6_policy.c | 5 +++-- net/xfrm/xfrm_policy.c | 20 ++++++++++---------- 4 files changed, 25 insertions(+), 21 deletions(-)
Note: I'm sending this series to net-next as these are generic networking changes, although they only touch xfrm files. But I'm happy to rebase over ipsec-next if that's prefered. Just let me know.
Signature · 1 line
2.39.2
PATCH 1/6 xfrm: Convert xfrm_get_tos() to dscp_t.
Return a dscp_t variable to prepare for the future conversion of xfrm_bundle_create() to dscp_t.
While there, rename the function "xfrm_get_dscp", to align its name with the new return type.
--- net/xfrm/xfrm_policy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/xfrm/xfrm_policy.c +3 -3
@@ -2550,10 +2550,10 @@ xfrm_tmpl_resolve(struct xfrm_policy **pols, int npols, const struct flowi *fl, } -static int xfrm_get_tos (const struct flowi *fl,int family) +static dscp_t xfrm_get_dscp (const struct flowi *fl,int family) {if (family ==AF_INET ) -return fl->u.ip4.flowi4_tos &INET_DSCP_MASK ; +return inet_dsfield_to_dscp (fl->u.ip4.flowi4_tos);return 0 ; }
@@ -2647,7 +2647,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,xfrm_flowi_addr_get (fl, &saddr, &daddr, family); - tos =xfrm_get_tos (fl, family); + tos =inet_dscp_to_dsfield (xfrm_get_dscp (fl, family));dst_hold (dst);
Signature · 1 line
2.39.2
PATCH 2/6 xfrm: Convert xfrm_bundle_create() to dscp_t.
In reply to Guillaume NaultUse a dscp_t variable to store the result of xfrm_get_dscp(). This prepares for the future conversion of xfrm_dst_lookup().
--- net/xfrm/xfrm_policy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/xfrm/xfrm_policy.c +4 -3
@@ -2641,13 +2641,13 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,int header_len =0 ;int nfheader_len =0 ;int trailer_len =0 ; -int tos; +dscp_t dscp;int family = policy->selector.family;xfrm_address_t saddr, daddr;xfrm_flowi_addr_get (fl, &saddr, &daddr, family); - tos =inet_dscp_to_dsfield (xfrm_get_dscp (fl, family)); + dscp =xfrm_get_dscp (fl, family);dst_hold (dst);
@@ -2695,7 +2695,8 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, family = xfrm[i]->props.family; oif = fl->flowi_oif ? : fl->flowi_l3mdev; - dst =xfrm_dst_lookup (xfrm[i], tos, oif, + dst =xfrm_dst_lookup (xfrm[i], +inet_dscp_to_dsfield (dscp), oif, &saddr, &daddr, family, mark); err =PTR_ERR (dst);if (IS_ERR (dst))
Signature · 1 line
2.39.2
PATCH 3/6 xfrm: Convert xfrm_dst_lookup() to dscp_t.
In reply to Guillaume NaultPass a dscp_t variable to xfrm_dst_lookup(), instead of an int, to prevent accidental setting of ECN bits in ->flowi4_tos.
Only xfrm_bundle_create() actually calls xfrm_dst_lookup(). Since it already has a dscp_t variable to pass as parameter, we only need to remove the inet_dscp_to_dsfield() conversion.
--- net/xfrm/xfrm_policy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/xfrm/xfrm_policy.c +5 -5
@@ -291,7 +291,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,EXPORT_SYMBOL (__xfrm_dst_lookup);static inline struct dst_entry *xfrm_dst_lookup (struct xfrm_state *x, -int tos,int oif, +dscp_t dscp,int oif,xfrm_address_t *prev_saddr,xfrm_address_t *prev_daddr,int family,u32 mark)
@@ -310,7 +310,8 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, daddr = x->coaddr; } - dst =__xfrm_dst_lookup (net, tos, oif, saddr, daddr, family, mark); + dst =__xfrm_dst_lookup (net,inet_dscp_to_dsfield (dscp), oif, saddr, + daddr, family, mark);if (!IS_ERR (dst)) {if (prev_saddr != saddr)
@@ -2695,9 +2696,8 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, family = xfrm[i]->props.family; oif = fl->flowi_oif ? : fl->flowi_l3mdev; - dst =xfrm_dst_lookup (xfrm[i], -inet_dscp_to_dsfield (dscp), oif, - &saddr, &daddr, family, mark); + dst =xfrm_dst_lookup (xfrm[i], dscp, oif, &saddr, + &daddr, family, mark); err =PTR_ERR (dst);if (IS_ERR (dst)) goto put_states;
Signature · 1 line
2.39.2
Re: [PATCH net-next 3/6] xfrm: Convert xfrm_dst_lookup() to dscp_t.
Quoted 18 lines · Guillaume Nault
Pass a
dscp_tvariable toxfrm_dst_lookup(), instead of an int, to prevent accidental setting of ECN bits in ->flowi4_tos.Only
xfrm_bundle_create()actually callsxfrm_dst_lookup(). Since it already has adscp_tvariable to pass as parameter, we only need to remove theinet_dscp_to_dsfield()conversion.Signed-off-by Guillaume Nault <[email protected]>--- net/xfrm/xfrm_policy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)net/xfrm/xfrm_policy.c +0
-0
net/xfrm/xfrm_policy.c struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif, · line 294
Quoted 5 lines
net/xfrm/xfrm_policy.c +1
-1@@ -291,7 +291,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,EXPORT_SYMBOL (__xfrm_dst_lookup); static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, - int tos, int oif, + dscp_t dscp, int oif,
FWIW this looks like it's going to conflict with a commit currently in the ipsec tree:
https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git/commit/?id=e509996b16728e37d5a909a5c63c1bd64f23b306
Eyal.
Re: [PATCH net-next 3/6] xfrm: Convert xfrm_dst_lookup() to dscp_t.
Quoted 21 lines · Eyal Birger
Quoted 20 lines · Guillaume Nault
Pass a
dscp_tvariable toxfrm_dst_lookup(), instead of an int, to prevent accidental setting of ECN bits in ->flowi4_tos.Only
xfrm_bundle_create()actually callsxfrm_dst_lookup(). Since it already has adscp_tvariable to pass as parameter, we only need to remove theinet_dscp_to_dsfield()conversion.Signed-off-by Guillaume Nault <[email protected]>--- net/xfrm/xfrm_policy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)net/xfrm/xfrm_policy.c +0
-0@@ -291,7 +291,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,EXPORT_SYMBOL (__xfrm_dst_lookup);
Quoted 8 lines
net/xfrm/xfrm_policy.c struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif, · line 294
Quoted 3 lines
net/xfrm/xfrm_policy.c +1
-1static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, - int tos, int oif, + dscp_t dscp, int oif,FWIW this looks like it's going to conflict with a commit currently in the ipsec tree:
https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git/commit/?id=e509996b16728e37d5a909a5c63c1bd64f23b306
Indeed. I'll send v2 once the ipsec tree will be merged. Thanks!
Quoted 2 lines
Eyal.
PATCH 4/6 xfrm: Convert __xfrm_dst_lookup() to dscp_t.
In reply to Guillaume NaultPass a dscp_t variable to __xfrm_dst_lookup(), instead of an int, to prevent accidental setting of ECN bits in ->flowi4_tos.
Callers of ip_mc_validate_source() to consider are:
* xfrm_dst_lookup() which already has a dscp_t variable to pass as parameter. We just need to remove the inet_dscp_to_dsfield() conversion.
* xfrm_dev_state_add() in net/xfrm/xfrm_device.c. This function sets the tos parameter to 0, which is already a valid dscp_t value, so it doesn't need to be adjusted for the new prototype.
--- include/net/xfrm.h | 3 ++- net/xfrm/xfrm_policy.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-)
include/net/xfrm.h +2 -1
@@ -19,6 +19,7 @@#include <net/sock.h> #include <net/dst.h> +#include <net/inet_dscp.h> #include <net/ip.h> #include <net/route.h> #include <net/ipv6.h>
@@ -1764,7 +1765,7 @@ static inline int xfrm_user_policy(struct sock *sk, int optname, }#endif -struct dst_entry *__xfrm_dst_lookup (struct net *net,int tos,int oif, +struct dst_entry *__xfrm_dst_lookup (struct net *net,dscp_t dscp,int oif,const xfrm_address_t *saddr,const xfrm_address_t *daddr,int family,u32 mark);
net/xfrm/xfrm_policy.c +4 -4
@@ -270,7 +270,7 @@ static const struct xfrm_if_cb *xfrm_if_get_cb(void)return rcu_dereference (xfrm_if_cb); } -struct dst_entry *__xfrm_dst_lookup (struct net *net,int tos,int oif, +struct dst_entry *__xfrm_dst_lookup (struct net *net,dscp_t dscp,int oif,const xfrm_address_t *saddr,const xfrm_address_t *daddr,int family,u32 mark)
@@ -282,7 +282,8 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos, int oif,if (unlikely (afinfo ==NULL ))return ERR_PTR (-EAFNOSUPPORT ); - dst = afinfo->dst_lookup (net, tos, oif, saddr, daddr, mark); + dst = afinfo->dst_lookup (net,inet_dscp_to_dsfield (dscp), oif, saddr, + daddr, mark);rcu_read_unlock ();
@@ -310,8 +311,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, daddr = x->coaddr; } - dst =__xfrm_dst_lookup (net,inet_dscp_to_dsfield (dscp), oif, saddr, - daddr, family, mark); + dst =__xfrm_dst_lookup (net, dscp, oif, saddr, daddr, family, mark);if (!IS_ERR (dst)) {if (prev_saddr != saddr)
Signature · 1 line
2.39.2
PATCH 5/6 xfrm: Convert the ->dst_lookup() callback to dscp_t.
In reply to Guillaume NaultPass a dscp_t variable to ->dst_lookup() callbacks (struct xfrm_policy_afinfo), instead of an int, to prevent accidental setting of ECN bits in ->flowi4_tos.
This callback is only called by __xfrm_dst_lookup(), which already has a dscp_t variable to pass as parameter. We just need to remove the inet_dscp_to_dsfield() conversion.
There are two implementations of this callback: xfrm6_dst_lookup(), which doesn't use the modified parameter, and xfrm4_dst_lookup() which needs to convert it again before calling __xfrm4_dst_lookup().
--- include/net/xfrm.h | 4 ++-- net/ipv4/xfrm4_policy.c | 8 +++++--- net/ipv6/xfrm6_policy.c | 5 +++-- net/xfrm/xfrm_policy.c | 3 +-- 4 files changed, 11 insertions(+), 9 deletions(-)
include/net/xfrm.h +2 -2
@@ -355,8 +355,8 @@ struct xfrm_type;struct xfrm_dst ;struct xfrm_policy_afinfo {struct dst_ops *dst_ops; -struct dst_entry *(*dst_lookup)(struct net *net, -int tos,int oif, +struct dst_entry *(*dst_lookup)(struct net *net,dscp_t dscp, +int oif,const xfrm_address_t *saddr,const xfrm_address_t *daddr,u32 mark);
net/ipv4/xfrm4_policy.c +5 -3
@@ -11,6 +11,7 @@#include <linux/err.h> #include <linux/kernel.h> +#include <net/inet_dscp.h> #include <linux/inetdevice.h> #include <net/dst.h> #include <net/xfrm.h>
@@ -40,14 +41,15 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,return ERR_CAST (rt); } -static struct dst_entry *xfrm4_dst_lookup (struct net *net,int tos,int oif, -const xfrm_address_t *saddr, +static struct dst_entry *xfrm4_dst_lookup (struct net *net,dscp_t dscp, +int oif,const xfrm_address_t *saddr,const xfrm_address_t *daddr,u32 mark) {struct flowi4 fl4; -return __xfrm4_dst_lookup (net, &fl4, tos, oif, saddr, daddr, mark); +return __xfrm4_dst_lookup (net, &fl4,inet_dscp_to_dsfield (dscp), oif, + saddr, daddr, mark); } static int xfrm4_get_saddr(struct net *net, int oif,
net/ipv6/xfrm6_policy.c +3 -2
@@ -18,13 +18,14 @@#include <net/addrconf.h> #include <net/dst.h> #include <net/xfrm.h> +#include <net/inet_dscp.h> #include <net/ip.h> #include <net/ipv6.h> #include <net/ip6_route.h> #include <net/l3mdev.h> -static struct dst_entry *xfrm6_dst_lookup (struct net *net,int tos,int oif, -const xfrm_address_t *saddr, +static struct dst_entry *xfrm6_dst_lookup (struct net *net,dscp_t dscp, +int oif,const xfrm_address_t *saddr,const xfrm_address_t *daddr,u32 mark) {
net/xfrm/xfrm_policy.c +1 -2
@@ -282,8 +282,7 @@ struct dst_entry *__xfrm_dst_lookup(struct net *net, dscp_t dscp, int oif,if (unlikely (afinfo ==NULL ))return ERR_PTR (-EAFNOSUPPORT ); - dst = afinfo->dst_lookup (net,inet_dscp_to_dsfield (dscp), oif, saddr, - daddr, mark); + dst = afinfo->dst_lookup (net, dscp, oif, saddr, daddr, mark);rcu_read_unlock ();
Signature · 1 line
2.39.2
PATCH 6/6 xfrm: Convert __xfrm4_dst_lookup() to dscp_t.
In reply to Guillaume NaultPass a dscp_t variable to __xfrm4_dst_lookup(), instead of an int, to prevent accidental setting of ECN bits in ->flowi4_tos.
Callers of __xfrm4_dst_lookup() to consider are:
* xfrm4_dst_lookup(), which already has a dscp_t variable to pass as parameter. We just need to remove the inet_dscp_to_dsfield() conversion.
* xfrm4_get_saddr(). This function sets the tos parameter to 0, which is already a valid dscp_t value, so it doesn't need to be adjusted for the new prototype.
--- net/ipv4/xfrm4_policy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/ipv4/xfrm4_policy.c +5 -5
@@ -18,8 +18,9 @@#include <net/ip.h> #include <net/l3mdev.h> -static struct dst_entry *__xfrm4_dst_lookup (struct net *net,struct flowi4 *fl4, -int tos,int oif, +static struct dst_entry *__xfrm4_dst_lookup (struct net *net, +struct flowi4 *fl4,dscp_t dscp, +int oif,const xfrm_address_t *saddr,const xfrm_address_t *daddr,u32 mark)
@@ -28,7 +29,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,memset (fl4,0 ,sizeof (*fl4)); fl4->daddr = daddr->a4; - fl4->flowi4_tos = tos; + fl4->flowi4_tos =inet_dscp_to_dsfield (dscp); fl4->flowi4_l3mdev =l3mdev_master_ifindex_by_index (net, oif); fl4->flowi4_mark = mark;if (saddr)
@@ -48,8 +49,7 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, dscp_t dscp, {struct flowi4 fl4; -return __xfrm4_dst_lookup (net, &fl4,inet_dscp_to_dsfield (dscp), oif, - saddr, daddr, mark); +return __xfrm4_dst_lookup (net, &fl4, dscp, oif, saddr, daddr, mark); } static int xfrm4_get_saddr(struct net *net, int oif,
Signature · 1 line
2.39.2