summaryrefslogtreecommitdiffstats
path: root/net/switchdev/switchdev.c
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2015-12-15 10:03:35 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-15 11:58:20 -0500
commit6ff64f6f9242d7e50f3e99cb280f69d1927a5fa6 (patch)
tree85d9661650c22ab27fe654433360f9e33172f7b9 /net/switchdev/switchdev.c
parent9d547833f02fb8b52ab824adae8f850f3c22fd4f (diff)
switchdev: Pass original device to port netdev driver
switchdev drivers need to know the netdev on which the switchdev op was invoked. For example, the STP state of a VLAN interface configured on top of a port can change while being member in a bridge. In this case, the underlying driver should only change the STP state of that particular VLAN and not of all the VLANs configured on the port. However, current switchdev infrastructure only passes the port netdev down to the driver. Solve that by passing the original device down to the driver as part of the required switchdev object / attribute. This doesn't entail any change in current switchdev drivers. It simply enables those supporting stacked devices to know the originating device and act accordingly. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r--net/switchdev/switchdev.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index f34e535e93bd..df790d3385a2 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -723,6 +723,7 @@ static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev,
723 u32 filter_mask) 723 u32 filter_mask)
724{ 724{
725 struct switchdev_vlan_dump dump = { 725 struct switchdev_vlan_dump dump = {
726 .vlan.obj.orig_dev = dev,
726 .vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, 727 .vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
727 .skb = skb, 728 .skb = skb,
728 .filter_mask = filter_mask, 729 .filter_mask = filter_mask,
@@ -757,6 +758,7 @@ int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
757 int nlflags) 758 int nlflags)
758{ 759{
759 struct switchdev_attr attr = { 760 struct switchdev_attr attr = {
761 .orig_dev = dev,
760 .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, 762 .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
761 }; 763 };
762 u16 mode = BRIDGE_MODE_UNDEF; 764 u16 mode = BRIDGE_MODE_UNDEF;
@@ -778,6 +780,7 @@ static int switchdev_port_br_setflag(struct net_device *dev,
778 unsigned long brport_flag) 780 unsigned long brport_flag)
779{ 781{
780 struct switchdev_attr attr = { 782 struct switchdev_attr attr = {
783 .orig_dev = dev,
781 .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, 784 .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
782 }; 785 };
783 u8 flag = nla_get_u8(nlattr); 786 u8 flag = nla_get_u8(nlattr);
@@ -853,6 +856,7 @@ static int switchdev_port_br_afspec(struct net_device *dev,
853 struct nlattr *attr; 856 struct nlattr *attr;
854 struct bridge_vlan_info *vinfo; 857 struct bridge_vlan_info *vinfo;
855 struct switchdev_obj_port_vlan vlan = { 858 struct switchdev_obj_port_vlan vlan = {
859 .obj.orig_dev = dev,
856 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, 860 .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
857 }; 861 };
858 int rem; 862 int rem;
@@ -975,6 +979,7 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
975 u16 vid, u16 nlm_flags) 979 u16 vid, u16 nlm_flags)
976{ 980{
977 struct switchdev_obj_port_fdb fdb = { 981 struct switchdev_obj_port_fdb fdb = {
982 .obj.orig_dev = dev,
978 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, 983 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
979 .vid = vid, 984 .vid = vid,
980 }; 985 };
@@ -1000,6 +1005,7 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
1000 u16 vid) 1005 u16 vid)
1001{ 1006{
1002 struct switchdev_obj_port_fdb fdb = { 1007 struct switchdev_obj_port_fdb fdb = {
1008 .obj.orig_dev = dev,
1003 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, 1009 .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
1004 .vid = vid, 1010 .vid = vid,
1005 }; 1011 };
@@ -1077,6 +1083,7 @@ int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
1077 struct net_device *filter_dev, int idx) 1083 struct net_device *filter_dev, int idx)
1078{ 1084{
1079 struct switchdev_fdb_dump dump = { 1085 struct switchdev_fdb_dump dump = {
1086 .fdb.obj.orig_dev = dev,
1080 .fdb.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB, 1087 .fdb.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
1081 .dev = dev, 1088 .dev = dev,
1082 .skb = skb, 1089 .skb = skb,
@@ -1135,6 +1142,7 @@ static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
1135 if (!dev) 1142 if (!dev)
1136 return NULL; 1143 return NULL;
1137 1144
1145 attr.orig_dev = dev;
1138 if (switchdev_port_attr_get(dev, &attr)) 1146 if (switchdev_port_attr_get(dev, &attr))
1139 return NULL; 1147 return NULL;
1140 1148
@@ -1194,6 +1202,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
1194 if (!dev) 1202 if (!dev)
1195 return 0; 1203 return 0;
1196 1204
1205 ipv4_fib.obj.orig_dev = dev;
1197 err = switchdev_port_obj_add(dev, &ipv4_fib.obj); 1206 err = switchdev_port_obj_add(dev, &ipv4_fib.obj);
1198 if (!err) 1207 if (!err)
1199 fi->fib_flags |= RTNH_F_OFFLOAD; 1208 fi->fib_flags |= RTNH_F_OFFLOAD;
@@ -1238,6 +1247,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
1238 if (!dev) 1247 if (!dev)
1239 return 0; 1248 return 0;
1240 1249
1250 ipv4_fib.obj.orig_dev = dev;
1241 err = switchdev_port_obj_del(dev, &ipv4_fib.obj); 1251 err = switchdev_port_obj_del(dev, &ipv4_fib.obj);
1242 if (!err) 1252 if (!err)
1243 fi->fib_flags &= ~RTNH_F_OFFLOAD; 1253 fi->fib_flags &= ~RTNH_F_OFFLOAD;
@@ -1270,10 +1280,12 @@ static bool switchdev_port_same_parent_id(struct net_device *a,
1270 struct net_device *b) 1280 struct net_device *b)
1271{ 1281{
1272 struct switchdev_attr a_attr = { 1282 struct switchdev_attr a_attr = {
1283 .orig_dev = a,
1273 .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, 1284 .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
1274 .flags = SWITCHDEV_F_NO_RECURSE, 1285 .flags = SWITCHDEV_F_NO_RECURSE,
1275 }; 1286 };
1276 struct switchdev_attr b_attr = { 1287 struct switchdev_attr b_attr = {
1288 .orig_dev = b,
1277 .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID, 1289 .id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
1278 .flags = SWITCHDEV_F_NO_RECURSE, 1290 .flags = SWITCHDEV_F_NO_RECURSE,
1279 }; 1291 };