Commit da4ed551 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

switchdev: pass pointer to fib_info instead of copy

The problem is that fib_info->nh is [0] so the struct fib_info
allocation size depends on number of nexthops. If we just copy fib_info,
we do not copy the nexthops info and driver accesses memory which is not
ours.

Given the fact that fib4 does not defer operations and therefore it does
not need copy, just pass the pointer down to drivers as it was done
before.

Fixes: 850d0cbc ("switchdev: remove pointers from switchdev objects")
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dc327f89
...@@ -2727,7 +2727,7 @@ static int ofdpa_port_obj_fib4_add(struct rocker_port *rocker_port, ...@@ -2727,7 +2727,7 @@ static int ofdpa_port_obj_fib4_add(struct rocker_port *rocker_port,
return ofdpa_port_fib_ipv4(ofdpa_port, trans, return ofdpa_port_fib_ipv4(ofdpa_port, trans,
htonl(fib4->dst), fib4->dst_len, htonl(fib4->dst), fib4->dst_len,
&fib4->fi, fib4->tb_id, 0); fib4->fi, fib4->tb_id, 0);
} }
static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port, static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port,
...@@ -2737,7 +2737,7 @@ static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port, ...@@ -2737,7 +2737,7 @@ static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port,
return ofdpa_port_fib_ipv4(ofdpa_port, NULL, return ofdpa_port_fib_ipv4(ofdpa_port, NULL,
htonl(fib4->dst), fib4->dst_len, htonl(fib4->dst), fib4->dst_len,
&fib4->fi, fib4->tb_id, fib4->fi, fib4->tb_id,
OFDPA_OP_FLAG_REMOVE); OFDPA_OP_FLAG_REMOVE);
} }
......
...@@ -97,7 +97,7 @@ struct switchdev_obj_ipv4_fib { ...@@ -97,7 +97,7 @@ struct switchdev_obj_ipv4_fib {
struct switchdev_obj obj; struct switchdev_obj obj;
u32 dst; u32 dst;
int dst_len; int dst_len;
struct fib_info fi; struct fib_info *fi;
u8 tos; u8 tos;
u8 type; u8 type;
u32 nlflags; u32 nlflags;
......
...@@ -1188,6 +1188,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1188,6 +1188,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
.obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
.dst = dst, .dst = dst,
.dst_len = dst_len, .dst_len = dst_len,
.fi = fi,
.tos = tos, .tos = tos,
.type = type, .type = type,
.nlflags = nlflags, .nlflags = nlflags,
...@@ -1196,8 +1197,6 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1196,8 +1197,6 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
struct net_device *dev; struct net_device *dev;
int err = 0; int err = 0;
memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
/* Don't offload route if using custom ip rules or if /* Don't offload route if using custom ip rules or if
* IPv4 FIB offloading has been disabled completely. * IPv4 FIB offloading has been disabled completely.
*/ */
...@@ -1242,6 +1241,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1242,6 +1241,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
.obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
.dst = dst, .dst = dst,
.dst_len = dst_len, .dst_len = dst_len,
.fi = fi,
.tos = tos, .tos = tos,
.type = type, .type = type,
.nlflags = 0, .nlflags = 0,
...@@ -1250,8 +1250,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1250,8 +1250,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
struct net_device *dev; struct net_device *dev;
int err = 0; int err = 0;
memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
if (!(fi->fib_flags & RTNH_F_OFFLOAD)) if (!(fi->fib_flags & RTNH_F_OFFLOAD))
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment