@@ -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);
@@ -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,
@@ -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)
{
@@ -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();
Pass 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(). Signed-off-by: Guillaume Nault <gnault@redhat.com> --- 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(-)