aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/switchdev.h
diff options
context:
space:
mode:
authorScott Feldman <sfeldma@gmail.com>2015-05-10 12:47:48 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-12 18:43:53 -0400
commit3094333d9089d43e8b8f0418676fa6ae06c27b51 (patch)
treee2796ab07d0356c4fba4b0040702f3ac2172a6dc /include/net/switchdev.h
parent9d47c0a2d958e06322c88245749278633d333cca (diff)
switchdev: introduce get/set attrs ops
Add two new swdev ops for get/set switch port attributes. Most swdev interactions on a port are gets or sets on port attributes, so rather than adding ops for each attribute, let's define clean get/set ops for all attributes, and then we can have clear, consistent rules on how attributes propagate on stacked devs. Add the basic algorithms for get/set attr ops. Use the same recusive algo to walk lower devs we've used for STP updates, for example. For get, compare attr value for each lower dev and only return success if attr values match across all lower devs. For sets, set the same attr value for all lower devs. We'll use a two-phase prepare-commit transaction model for sets. In the first phase, the driver(s) are asked if attr set is OK. If all OK, the commit attr set in second phase. A driver would NACK the prepare phase if it can't set the attr due to lack of resources or support, within it's control. RTNL lock must be held across both phases because we'll recurse all lower devs first in prepare phase, and then recurse all lower devs again in commit phase. If any lower dev fails the prepare phase, we need to abort the transaction for all lower devs. If lower dev recusion isn't desired, allow a flag SWITCHDEV_F_NO_RECURSE to indicate get/set only work on port (lowest) device. Signed-off-by: Scott Feldman <sfeldma@gmail.com> Acked-by: Jiri Pirko <jiri@resnulli.us> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/switchdev.h')
-rw-r--r--include/net/switchdev.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 97b556daeef7..282043844bcf 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -14,6 +14,25 @@
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/notifier.h> 15#include <linux/notifier.h>
16 16
17#define SWITCHDEV_F_NO_RECURSE BIT(0)
18
19enum switchdev_trans {
20 SWITCHDEV_TRANS_NONE,
21 SWITCHDEV_TRANS_PREPARE,
22 SWITCHDEV_TRANS_ABORT,
23 SWITCHDEV_TRANS_COMMIT,
24};
25
26enum switchdev_attr_id {
27 SWITCHDEV_ATTR_UNDEFINED,
28};
29
30struct switchdev_attr {
31 enum switchdev_attr_id id;
32 enum switchdev_trans trans;
33 u32 flags;
34};
35
17struct fib_info; 36struct fib_info;
18 37
19/** 38/**
@@ -23,6 +42,10 @@ struct fib_info;
23 * is part of. If driver implements this, it indicates that it 42 * is part of. If driver implements this, it indicates that it
24 * represents a port of a switch chip. 43 * represents a port of a switch chip.
25 * 44 *
45 * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
46 *
47 * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
48 *
26 * @switchdev_port_stp_update: Called to notify switch device port of bridge 49 * @switchdev_port_stp_update: Called to notify switch device port of bridge
27 * port STP state change. 50 * port STP state change.
28 * 51 *
@@ -33,6 +56,10 @@ struct fib_info;
33struct switchdev_ops { 56struct switchdev_ops {
34 int (*switchdev_parent_id_get)(struct net_device *dev, 57 int (*switchdev_parent_id_get)(struct net_device *dev,
35 struct netdev_phys_item_id *psid); 58 struct netdev_phys_item_id *psid);
59 int (*switchdev_port_attr_get)(struct net_device *dev,
60 struct switchdev_attr *attr);
61 int (*switchdev_port_attr_set)(struct net_device *dev,
62 struct switchdev_attr *attr);
36 int (*switchdev_port_stp_update)(struct net_device *dev, u8 state); 63 int (*switchdev_port_stp_update)(struct net_device *dev, u8 state);
37 int (*switchdev_fib_ipv4_add)(struct net_device *dev, __be32 dst, 64 int (*switchdev_fib_ipv4_add)(struct net_device *dev, __be32 dst,
38 int dst_len, struct fib_info *fi, 65 int dst_len, struct fib_info *fi,
@@ -68,6 +95,10 @@ switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
68 95
69int switchdev_parent_id_get(struct net_device *dev, 96int switchdev_parent_id_get(struct net_device *dev,
70 struct netdev_phys_item_id *psid); 97 struct netdev_phys_item_id *psid);
98int switchdev_port_attr_get(struct net_device *dev,
99 struct switchdev_attr *attr);
100int switchdev_port_attr_set(struct net_device *dev,
101 struct switchdev_attr *attr);
71int switchdev_port_stp_update(struct net_device *dev, u8 state); 102int switchdev_port_stp_update(struct net_device *dev, u8 state);
72int register_switchdev_notifier(struct notifier_block *nb); 103int register_switchdev_notifier(struct notifier_block *nb);
73int unregister_switchdev_notifier(struct notifier_block *nb); 104int unregister_switchdev_notifier(struct notifier_block *nb);
@@ -95,6 +126,18 @@ static inline int switchdev_parent_id_get(struct net_device *dev,
95 return -EOPNOTSUPP; 126 return -EOPNOTSUPP;
96} 127}
97 128
129static inline int switchdev_port_attr_get(struct net_device *dev,
130 struct switchdev_attr *attr)
131{
132 return -EOPNOTSUPP;
133}
134
135static inline int switchdev_port_attr_set(struct net_device *dev,
136 struct switchdev_attr *attr)
137{
138 return -EOPNOTSUPP;
139}
140
98static inline int switchdev_port_stp_update(struct net_device *dev, 141static inline int switchdev_port_stp_update(struct net_device *dev,
99 u8 state) 142 u8 state)
100{ 143{