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

switchdev: remove pointers from switchdev objects

When object is used in deferred work, we cannot use pointers in
switchdev object structures because the memory they point at may be already
used by someone else. So rather do local copy of the value.
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Acked-by: default avatarScott Feldman <sfeldma@gmail.com>
Reviewed-by: default avatarJohn Fastabend <john.r.fastabend@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0bc05d58
...@@ -4469,7 +4469,7 @@ static int rocker_port_obj_add(struct net_device *dev, ...@@ -4469,7 +4469,7 @@ static int rocker_port_obj_add(struct net_device *dev,
fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj); fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
err = rocker_port_fib_ipv4(rocker_port, trans, err = rocker_port_fib_ipv4(rocker_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);
break; break;
case SWITCHDEV_OBJ_ID_PORT_FDB: case SWITCHDEV_OBJ_ID_PORT_FDB:
err = rocker_port_fdb_add(rocker_port, trans, err = rocker_port_fdb_add(rocker_port, trans,
...@@ -4541,7 +4541,7 @@ static int rocker_port_obj_del(struct net_device *dev, ...@@ -4541,7 +4541,7 @@ static int rocker_port_obj_del(struct net_device *dev,
fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj); fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
err = rocker_port_fib_ipv4(rocker_port, NULL, err = rocker_port_fib_ipv4(rocker_port, NULL,
htonl(fib4->dst), fib4->dst_len, htonl(fib4->dst), fib4->dst_len,
fib4->fi, fib4->tb_id, &fib4->fi, fib4->tb_id,
ROCKER_OP_FLAG_REMOVE); ROCKER_OP_FLAG_REMOVE);
break; break;
case SWITCHDEV_OBJ_ID_PORT_FDB: case SWITCHDEV_OBJ_ID_PORT_FDB:
...@@ -4571,7 +4571,7 @@ static int rocker_port_fdb_dump(const struct rocker_port *rocker_port, ...@@ -4571,7 +4571,7 @@ static int rocker_port_fdb_dump(const struct rocker_port *rocker_port,
hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, found, entry) { hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, found, entry) {
if (found->key.rocker_port != rocker_port) if (found->key.rocker_port != rocker_port)
continue; continue;
fdb->addr = found->key.addr; ether_addr_copy(fdb->addr, found->key.addr);
fdb->ndm_state = NUD_REACHABLE; fdb->ndm_state = NUD_REACHABLE;
fdb->vid = rocker_port_vlan_to_vid(rocker_port, fdb->vid = rocker_port_vlan_to_vid(rocker_port,
found->key.vlan_id); found->key.vlan_id);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/list.h> #include <linux/list.h>
#include <net/ip_fib.h>
#define SWITCHDEV_F_NO_RECURSE BIT(0) #define SWITCHDEV_F_NO_RECURSE BIT(0)
#define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1) #define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1)
...@@ -59,8 +60,6 @@ struct switchdev_attr { ...@@ -59,8 +60,6 @@ struct switchdev_attr {
} u; } u;
}; };
struct fib_info;
enum switchdev_obj_id { enum switchdev_obj_id {
SWITCHDEV_OBJ_ID_UNDEFINED, SWITCHDEV_OBJ_ID_UNDEFINED,
SWITCHDEV_OBJ_ID_PORT_VLAN, SWITCHDEV_OBJ_ID_PORT_VLAN,
...@@ -88,7 +87,7 @@ struct switchdev_obj_ipv4_fib { ...@@ -88,7 +87,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;
...@@ -101,7 +100,7 @@ struct switchdev_obj_ipv4_fib { ...@@ -101,7 +100,7 @@ struct switchdev_obj_ipv4_fib {
/* SWITCHDEV_OBJ_ID_PORT_FDB */ /* SWITCHDEV_OBJ_ID_PORT_FDB */
struct switchdev_obj_port_fdb { struct switchdev_obj_port_fdb {
struct switchdev_obj obj; struct switchdev_obj obj;
const unsigned char *addr; unsigned char addr[ETH_ALEN];
u16 vid; u16 vid;
u16 ndm_state; u16 ndm_state;
}; };
......
...@@ -135,10 +135,10 @@ static void fdb_del_external_learn(struct net_bridge_fdb_entry *f) ...@@ -135,10 +135,10 @@ static void fdb_del_external_learn(struct net_bridge_fdb_entry *f)
{ {
struct switchdev_obj_port_fdb fdb = { struct switchdev_obj_port_fdb fdb = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
.addr = f->addr.addr,
.vid = f->vlan_id, .vid = f->vlan_id,
}; };
ether_addr_copy(fdb.addr, f->addr.addr);
switchdev_port_obj_del(f->dst->dev, &fdb.obj); switchdev_port_obj_del(f->dst->dev, &fdb.obj);
} }
......
...@@ -393,7 +393,7 @@ static int dsa_slave_port_fdb_dump(struct net_device *dev, ...@@ -393,7 +393,7 @@ static int dsa_slave_port_fdb_dump(struct net_device *dev,
if (ret < 0) if (ret < 0)
break; break;
fdb->addr = addr; ether_addr_copy(fdb->addr, addr);
fdb->vid = vid; fdb->vid = vid;
fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE; fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -891,10 +892,10 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], ...@@ -891,10 +892,10 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
{ {
struct switchdev_obj_port_fdb fdb = { struct switchdev_obj_port_fdb fdb = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
.addr = addr,
.vid = vid, .vid = vid,
}; };
ether_addr_copy(fdb.addr, addr);
return switchdev_port_obj_add(dev, &fdb.obj); return switchdev_port_obj_add(dev, &fdb.obj);
} }
EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); EXPORT_SYMBOL_GPL(switchdev_port_fdb_add);
...@@ -916,10 +917,10 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], ...@@ -916,10 +917,10 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
{ {
struct switchdev_obj_port_fdb fdb = { struct switchdev_obj_port_fdb fdb = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
.addr = addr,
.vid = vid, .vid = vid,
}; };
ether_addr_copy(fdb.addr, addr);
return switchdev_port_obj_del(dev, &fdb.obj); return switchdev_port_obj_del(dev, &fdb.obj);
} }
EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
...@@ -1081,7 +1082,6 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1081,7 +1082,6 @@ 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,
...@@ -1090,6 +1090,8 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1090,6 +1090,8 @@ 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.
*/ */
...@@ -1133,7 +1135,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1133,7 +1135,6 @@ 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,
...@@ -1142,6 +1143,8 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, ...@@ -1142,6 +1143,8 @@ 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