aboutsummaryrefslogtreecommitdiffstats
path: root/net/switchdev
diff options
context:
space:
mode:
authorJiri Pirko <jiri@mellanox.com>2015-10-14 13:40:51 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-15 09:09:49 -0400
commit850d0cbc9171f63f0418afffb0d89a84db927851 (patch)
tree21ecd5e1adb0d14f8c455484d57795d0a86379ea /net/switchdev
parent0bc05d585d381c30de3fdf955730df31593d2101 (diff)
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: Jiri Pirko <jiri@mellanox.com> Acked-by: Scott Feldman <sfeldma@gmail.com> Reviewed-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/switchdev')
-rw-r--r--net/switchdev/switchdev.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 007b8f40df06..5963d7ac1026 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -15,6 +15,7 @@
15#include <linux/mutex.h> 15#include <linux/mutex.h>
16#include <linux/notifier.h> 16#include <linux/notifier.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/etherdevice.h>
18#include <linux/if_bridge.h> 19#include <linux/if_bridge.h>
19#include <linux/list.h> 20#include <linux/list.h>
20#include <linux/workqueue.h> 21#include <linux/workqueue.h>
@@ -891,10 +892,10 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
891{ 892{
892 struct switchdev_obj_port_fdb fdb = { 893 struct switchdev_obj_port_fdb fdb = {
893 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, 894 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
894 .addr = addr,
895 .vid = vid, 895 .vid = vid,
896 }; 896 };
897 897
898 ether_addr_copy(fdb.addr, addr);
898 return switchdev_port_obj_add(dev, &fdb.obj); 899 return switchdev_port_obj_add(dev, &fdb.obj);
899} 900}
900EXPORT_SYMBOL_GPL(switchdev_port_fdb_add); 901EXPORT_SYMBOL_GPL(switchdev_port_fdb_add);
@@ -916,10 +917,10 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
916{ 917{
917 struct switchdev_obj_port_fdb fdb = { 918 struct switchdev_obj_port_fdb fdb = {
918 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, 919 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
919 .addr = addr,
920 .vid = vid, 920 .vid = vid,
921 }; 921 };
922 922
923 ether_addr_copy(fdb.addr, addr);
923 return switchdev_port_obj_del(dev, &fdb.obj); 924 return switchdev_port_obj_del(dev, &fdb.obj);
924} 925}
925EXPORT_SYMBOL_GPL(switchdev_port_fdb_del); 926EXPORT_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 .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, 1082 .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
1082 .dst = dst, 1083 .dst = dst,
1083 .dst_len = dst_len, 1084 .dst_len = dst_len,
1084 .fi = fi,
1085 .tos = tos, 1085 .tos = tos,
1086 .type = type, 1086 .type = type,
1087 .nlflags = nlflags, 1087 .nlflags = nlflags,
@@ -1090,6 +1090,8 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
1090 struct net_device *dev; 1090 struct net_device *dev;
1091 int err = 0; 1091 int err = 0;
1092 1092
1093 memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
1094
1093 /* Don't offload route if using custom ip rules or if 1095 /* Don't offload route if using custom ip rules or if
1094 * IPv4 FIB offloading has been disabled completely. 1096 * IPv4 FIB offloading has been disabled completely.
1095 */ 1097 */
@@ -1133,7 +1135,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
1133 .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB, 1135 .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
1134 .dst = dst, 1136 .dst = dst,
1135 .dst_len = dst_len, 1137 .dst_len = dst_len,
1136 .fi = fi,
1137 .tos = tos, 1138 .tos = tos,
1138 .type = type, 1139 .type = type,
1139 .nlflags = 0, 1140 .nlflags = 0,
@@ -1142,6 +1143,8 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
1142 struct net_device *dev; 1143 struct net_device *dev;
1143 int err = 0; 1144 int err = 0;
1144 1145
1146 memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
1147
1145 if (!(fi->fib_flags & RTNH_F_OFFLOAD)) 1148 if (!(fi->fib_flags & RTNH_F_OFFLOAD))
1146 return 0; 1149 return 0;
1147 1150