diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-05-19 17:00:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-22 19:37:32 -0400 |
commit | 685fb6a40ddace10a0bc8a680ab6ba65c6cdfdaf (patch) | |
tree | 258dc0f599d0e3ae686ce59ba7c5b84655328a7b /net/dsa | |
parent | 1faabf7440f17999f41973e91878c13ad9f080b2 (diff) |
net: dsa: add FDB notifier
Add two new DSA_NOTIFIER_FDB_ADD and DSA_NOTIFIER_FDB_DEL events to
notify not only a single switch, but all switches of a the fabric when
an FDB entry is added or removed.
For the moment, keep the current behavior and ignore other switches.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r-- | net/dsa/dsa_priv.h | 10 | ||||
-rw-r--r-- | net/dsa/port.c | 29 | ||||
-rw-r--r-- | net/dsa/switch.c | 43 |
3 files changed, 66 insertions, 16 deletions
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index becaf8a61b13..6a7d0d7d0489 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h | |||
@@ -20,6 +20,8 @@ enum { | |||
20 | DSA_NOTIFIER_AGEING_TIME, | 20 | DSA_NOTIFIER_AGEING_TIME, |
21 | DSA_NOTIFIER_BRIDGE_JOIN, | 21 | DSA_NOTIFIER_BRIDGE_JOIN, |
22 | DSA_NOTIFIER_BRIDGE_LEAVE, | 22 | DSA_NOTIFIER_BRIDGE_LEAVE, |
23 | DSA_NOTIFIER_FDB_ADD, | ||
24 | DSA_NOTIFIER_FDB_DEL, | ||
23 | }; | 25 | }; |
24 | 26 | ||
25 | /* DSA_NOTIFIER_AGEING_TIME */ | 27 | /* DSA_NOTIFIER_AGEING_TIME */ |
@@ -36,6 +38,14 @@ struct dsa_notifier_bridge_info { | |||
36 | int port; | 38 | int port; |
37 | }; | 39 | }; |
38 | 40 | ||
41 | /* DSA_NOTIFIER_FDB_* */ | ||
42 | struct dsa_notifier_fdb_info { | ||
43 | const struct switchdev_obj_port_fdb *fdb; | ||
44 | struct switchdev_trans *trans; | ||
45 | int sw_index; | ||
46 | int port; | ||
47 | }; | ||
48 | |||
39 | struct dsa_device_ops { | 49 | struct dsa_device_ops { |
40 | struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); | 50 | struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); |
41 | struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, | 51 | struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, |
diff --git a/net/dsa/port.c b/net/dsa/port.c index 59328a35394d..ed88d8381642 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c | |||
@@ -151,29 +151,26 @@ int dsa_port_fdb_add(struct dsa_port *dp, | |||
151 | const struct switchdev_obj_port_fdb *fdb, | 151 | const struct switchdev_obj_port_fdb *fdb, |
152 | struct switchdev_trans *trans) | 152 | struct switchdev_trans *trans) |
153 | { | 153 | { |
154 | struct dsa_switch *ds = dp->ds; | 154 | struct dsa_notifier_fdb_info info = { |
155 | 155 | .sw_index = dp->ds->index, | |
156 | if (switchdev_trans_ph_prepare(trans)) { | 156 | .port = dp->index, |
157 | if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add) | 157 | .trans = trans, |
158 | return -EOPNOTSUPP; | 158 | .fdb = fdb, |
159 | 159 | }; | |
160 | return ds->ops->port_fdb_prepare(ds, dp->index, fdb, trans); | ||
161 | } | ||
162 | |||
163 | ds->ops->port_fdb_add(ds, dp->index, fdb, trans); | ||
164 | 160 | ||
165 | return 0; | 161 | return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info); |
166 | } | 162 | } |
167 | 163 | ||
168 | int dsa_port_fdb_del(struct dsa_port *dp, | 164 | int dsa_port_fdb_del(struct dsa_port *dp, |
169 | const struct switchdev_obj_port_fdb *fdb) | 165 | const struct switchdev_obj_port_fdb *fdb) |
170 | { | 166 | { |
171 | struct dsa_switch *ds = dp->ds; | 167 | struct dsa_notifier_fdb_info info = { |
172 | 168 | .sw_index = dp->ds->index, | |
173 | if (ds->ops->port_fdb_del) | 169 | .port = dp->index, |
174 | return -EOPNOTSUPP; | 170 | .fdb = fdb, |
171 | }; | ||
175 | 172 | ||
176 | return ds->ops->port_fdb_del(ds, dp->index, fdb); | 173 | return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info); |
177 | } | 174 | } |
178 | 175 | ||
179 | int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb, | 176 | int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb, |
diff --git a/net/dsa/switch.c b/net/dsa/switch.c index 540770ecc8b0..e71cc860d32c 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c | |||
@@ -84,6 +84,43 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds, | |||
84 | return 0; | 84 | return 0; |
85 | } | 85 | } |
86 | 86 | ||
87 | static int dsa_switch_fdb_add(struct dsa_switch *ds, | ||
88 | struct dsa_notifier_fdb_info *info) | ||
89 | { | ||
90 | const struct switchdev_obj_port_fdb *fdb = info->fdb; | ||
91 | struct switchdev_trans *trans = info->trans; | ||
92 | |||
93 | /* Do not care yet about other switch chips of the fabric */ | ||
94 | if (ds->index != info->sw_index) | ||
95 | return 0; | ||
96 | |||
97 | if (switchdev_trans_ph_prepare(trans)) { | ||
98 | if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add) | ||
99 | return -EOPNOTSUPP; | ||
100 | |||
101 | return ds->ops->port_fdb_prepare(ds, info->port, fdb, trans); | ||
102 | } | ||
103 | |||
104 | ds->ops->port_fdb_add(ds, info->port, fdb, trans); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int dsa_switch_fdb_del(struct dsa_switch *ds, | ||
110 | struct dsa_notifier_fdb_info *info) | ||
111 | { | ||
112 | const struct switchdev_obj_port_fdb *fdb = info->fdb; | ||
113 | |||
114 | /* Do not care yet about other switch chips of the fabric */ | ||
115 | if (ds->index != info->sw_index) | ||
116 | return 0; | ||
117 | |||
118 | if (!ds->ops->port_fdb_del) | ||
119 | return -EOPNOTSUPP; | ||
120 | |||
121 | return ds->ops->port_fdb_del(ds, info->port, fdb); | ||
122 | } | ||
123 | |||
87 | static int dsa_switch_event(struct notifier_block *nb, | 124 | static int dsa_switch_event(struct notifier_block *nb, |
88 | unsigned long event, void *info) | 125 | unsigned long event, void *info) |
89 | { | 126 | { |
@@ -100,6 +137,12 @@ static int dsa_switch_event(struct notifier_block *nb, | |||
100 | case DSA_NOTIFIER_BRIDGE_LEAVE: | 137 | case DSA_NOTIFIER_BRIDGE_LEAVE: |
101 | err = dsa_switch_bridge_leave(ds, info); | 138 | err = dsa_switch_bridge_leave(ds, info); |
102 | break; | 139 | break; |
140 | case DSA_NOTIFIER_FDB_ADD: | ||
141 | err = dsa_switch_fdb_add(ds, info); | ||
142 | break; | ||
143 | case DSA_NOTIFIER_FDB_DEL: | ||
144 | err = dsa_switch_fdb_del(ds, info); | ||
145 | break; | ||
103 | default: | 146 | default: |
104 | err = -EOPNOTSUPP; | 147 | err = -EOPNOTSUPP; |
105 | break; | 148 | break; |