net: dsa: reference count the MDB entries at the cross-chip notifier level
[linux-2.6-microblaze.git] / net / dsa / switch.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Handling of a single switch chip, part of a switch fabric
4  *
5  * Copyright (c) 2017 Savoir-faire Linux Inc.
6  *      Vivien Didelot <vivien.didelot@savoirfairelinux.com>
7  */
8
9 #include <linux/if_bridge.h>
10 #include <linux/netdevice.h>
11 #include <linux/notifier.h>
12 #include <linux/if_vlan.h>
13 #include <net/switchdev.h>
14
15 #include "dsa_priv.h"
16
17 static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds,
18                                                    unsigned int ageing_time)
19 {
20         int i;
21
22         for (i = 0; i < ds->num_ports; ++i) {
23                 struct dsa_port *dp = dsa_to_port(ds, i);
24
25                 if (dp->ageing_time && dp->ageing_time < ageing_time)
26                         ageing_time = dp->ageing_time;
27         }
28
29         return ageing_time;
30 }
31
32 static int dsa_switch_ageing_time(struct dsa_switch *ds,
33                                   struct dsa_notifier_ageing_time_info *info)
34 {
35         unsigned int ageing_time = info->ageing_time;
36
37         if (ds->ageing_time_min && ageing_time < ds->ageing_time_min)
38                 return -ERANGE;
39
40         if (ds->ageing_time_max && ageing_time > ds->ageing_time_max)
41                 return -ERANGE;
42
43         /* Program the fastest ageing time in case of multiple bridges */
44         ageing_time = dsa_switch_fastest_ageing_time(ds, ageing_time);
45
46         if (ds->ops->set_ageing_time)
47                 return ds->ops->set_ageing_time(ds, ageing_time);
48
49         return 0;
50 }
51
52 static bool dsa_switch_mtu_match(struct dsa_switch *ds, int port,
53                                  struct dsa_notifier_mtu_info *info)
54 {
55         if (ds->index == info->sw_index && port == info->port)
56                 return true;
57
58         /* Do not propagate to other switches in the tree if the notifier was
59          * targeted for a single switch.
60          */
61         if (info->targeted_match)
62                 return false;
63
64         if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
65                 return true;
66
67         return false;
68 }
69
70 static int dsa_switch_mtu(struct dsa_switch *ds,
71                           struct dsa_notifier_mtu_info *info)
72 {
73         int port, ret;
74
75         if (!ds->ops->port_change_mtu)
76                 return -EOPNOTSUPP;
77
78         for (port = 0; port < ds->num_ports; port++) {
79                 if (dsa_switch_mtu_match(ds, port, info)) {
80                         ret = ds->ops->port_change_mtu(ds, port, info->mtu);
81                         if (ret)
82                                 return ret;
83                 }
84         }
85
86         return 0;
87 }
88
89 static int dsa_switch_bridge_join(struct dsa_switch *ds,
90                                   struct dsa_notifier_bridge_info *info)
91 {
92         struct dsa_switch_tree *dst = ds->dst;
93
94         if (dst->index == info->tree_index && ds->index == info->sw_index &&
95             ds->ops->port_bridge_join)
96                 return ds->ops->port_bridge_join(ds, info->port, info->br);
97
98         if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
99             ds->ops->crosschip_bridge_join)
100                 return ds->ops->crosschip_bridge_join(ds, info->tree_index,
101                                                       info->sw_index,
102                                                       info->port, info->br);
103
104         return 0;
105 }
106
107 static int dsa_switch_bridge_leave(struct dsa_switch *ds,
108                                    struct dsa_notifier_bridge_info *info)
109 {
110         bool unset_vlan_filtering = br_vlan_enabled(info->br);
111         struct dsa_switch_tree *dst = ds->dst;
112         struct netlink_ext_ack extack = {0};
113         int err, port;
114
115         if (dst->index == info->tree_index && ds->index == info->sw_index &&
116             ds->ops->port_bridge_join)
117                 ds->ops->port_bridge_leave(ds, info->port, info->br);
118
119         if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
120             ds->ops->crosschip_bridge_join)
121                 ds->ops->crosschip_bridge_leave(ds, info->tree_index,
122                                                 info->sw_index, info->port,
123                                                 info->br);
124
125         /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
126          * event for changing vlan_filtering setting upon slave ports leaving
127          * it. That is a good thing, because that lets us handle it and also
128          * handle the case where the switch's vlan_filtering setting is global
129          * (not per port). When that happens, the correct moment to trigger the
130          * vlan_filtering callback is only when the last port leaves the last
131          * VLAN-aware bridge.
132          */
133         if (unset_vlan_filtering && ds->vlan_filtering_is_global) {
134                 for (port = 0; port < ds->num_ports; port++) {
135                         struct net_device *bridge_dev;
136
137                         bridge_dev = dsa_to_port(ds, port)->bridge_dev;
138
139                         if (bridge_dev && br_vlan_enabled(bridge_dev)) {
140                                 unset_vlan_filtering = false;
141                                 break;
142                         }
143                 }
144         }
145         if (unset_vlan_filtering) {
146                 err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
147                                               false, &extack);
148                 if (extack._msg)
149                         dev_err(ds->dev, "port %d: %s\n", info->port,
150                                 extack._msg);
151                 if (err && err != EOPNOTSUPP)
152                         return err;
153         }
154         return 0;
155 }
156
157 /* Matches for all upstream-facing ports (the CPU port and all upstream-facing
158  * DSA links) that sit between the targeted port on which the notifier was
159  * emitted and its dedicated CPU port.
160  */
161 static bool dsa_switch_host_address_match(struct dsa_switch *ds, int port,
162                                           int info_sw_index, int info_port)
163 {
164         struct dsa_port *targeted_dp, *cpu_dp;
165         struct dsa_switch *targeted_ds;
166
167         targeted_ds = dsa_switch_find(ds->dst->index, info_sw_index);
168         targeted_dp = dsa_to_port(targeted_ds, info_port);
169         cpu_dp = targeted_dp->cpu_dp;
170
171         if (dsa_switch_is_upstream_of(ds, targeted_ds))
172                 return port == dsa_towards_port(ds, cpu_dp->ds->index,
173                                                 cpu_dp->index);
174
175         return false;
176 }
177
178 static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
179                                               const unsigned char *addr,
180                                               u16 vid)
181 {
182         struct dsa_mac_addr *a;
183
184         list_for_each_entry(a, addr_list, list)
185                 if (ether_addr_equal(a->addr, addr) && a->vid == vid)
186                         return a;
187
188         return NULL;
189 }
190
191 static int dsa_switch_do_mdb_add(struct dsa_switch *ds, int port,
192                                  const struct switchdev_obj_port_mdb *mdb)
193 {
194         struct dsa_port *dp = dsa_to_port(ds, port);
195         struct dsa_mac_addr *a;
196         int err;
197
198         /* No need to bother with refcounting for user ports */
199         if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
200                 return ds->ops->port_mdb_add(ds, port, mdb);
201
202         a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
203         if (a) {
204                 refcount_inc(&a->refcount);
205                 return 0;
206         }
207
208         a = kzalloc(sizeof(*a), GFP_KERNEL);
209         if (!a)
210                 return -ENOMEM;
211
212         err = ds->ops->port_mdb_add(ds, port, mdb);
213         if (err) {
214                 kfree(a);
215                 return err;
216         }
217
218         ether_addr_copy(a->addr, mdb->addr);
219         a->vid = mdb->vid;
220         refcount_set(&a->refcount, 1);
221         list_add_tail(&a->list, &dp->mdbs);
222
223         return 0;
224 }
225
226 static int dsa_switch_do_mdb_del(struct dsa_switch *ds, int port,
227                                  const struct switchdev_obj_port_mdb *mdb)
228 {
229         struct dsa_port *dp = dsa_to_port(ds, port);
230         struct dsa_mac_addr *a;
231         int err;
232
233         /* No need to bother with refcounting for user ports */
234         if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
235                 return ds->ops->port_mdb_del(ds, port, mdb);
236
237         a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
238         if (!a)
239                 return -ENOENT;
240
241         if (!refcount_dec_and_test(&a->refcount))
242                 return 0;
243
244         err = ds->ops->port_mdb_del(ds, port, mdb);
245         if (err) {
246                 refcount_inc(&a->refcount);
247                 return err;
248         }
249
250         list_del(&a->list);
251         kfree(a);
252
253         return 0;
254 }
255
256 static int dsa_switch_fdb_add(struct dsa_switch *ds,
257                               struct dsa_notifier_fdb_info *info)
258 {
259         int port = dsa_towards_port(ds, info->sw_index, info->port);
260
261         if (!ds->ops->port_fdb_add)
262                 return -EOPNOTSUPP;
263
264         return ds->ops->port_fdb_add(ds, port, info->addr, info->vid);
265 }
266
267 static int dsa_switch_fdb_del(struct dsa_switch *ds,
268                               struct dsa_notifier_fdb_info *info)
269 {
270         int port = dsa_towards_port(ds, info->sw_index, info->port);
271
272         if (!ds->ops->port_fdb_del)
273                 return -EOPNOTSUPP;
274
275         return ds->ops->port_fdb_del(ds, port, info->addr, info->vid);
276 }
277
278 static int dsa_switch_hsr_join(struct dsa_switch *ds,
279                                struct dsa_notifier_hsr_info *info)
280 {
281         if (ds->index == info->sw_index && ds->ops->port_hsr_join)
282                 return ds->ops->port_hsr_join(ds, info->port, info->hsr);
283
284         return -EOPNOTSUPP;
285 }
286
287 static int dsa_switch_hsr_leave(struct dsa_switch *ds,
288                                 struct dsa_notifier_hsr_info *info)
289 {
290         if (ds->index == info->sw_index && ds->ops->port_hsr_leave)
291                 return ds->ops->port_hsr_leave(ds, info->port, info->hsr);
292
293         return -EOPNOTSUPP;
294 }
295
296 static int dsa_switch_lag_change(struct dsa_switch *ds,
297                                  struct dsa_notifier_lag_info *info)
298 {
299         if (ds->index == info->sw_index && ds->ops->port_lag_change)
300                 return ds->ops->port_lag_change(ds, info->port);
301
302         if (ds->index != info->sw_index && ds->ops->crosschip_lag_change)
303                 return ds->ops->crosschip_lag_change(ds, info->sw_index,
304                                                      info->port);
305
306         return 0;
307 }
308
309 static int dsa_switch_lag_join(struct dsa_switch *ds,
310                                struct dsa_notifier_lag_info *info)
311 {
312         if (ds->index == info->sw_index && ds->ops->port_lag_join)
313                 return ds->ops->port_lag_join(ds, info->port, info->lag,
314                                               info->info);
315
316         if (ds->index != info->sw_index && ds->ops->crosschip_lag_join)
317                 return ds->ops->crosschip_lag_join(ds, info->sw_index,
318                                                    info->port, info->lag,
319                                                    info->info);
320
321         return 0;
322 }
323
324 static int dsa_switch_lag_leave(struct dsa_switch *ds,
325                                 struct dsa_notifier_lag_info *info)
326 {
327         if (ds->index == info->sw_index && ds->ops->port_lag_leave)
328                 return ds->ops->port_lag_leave(ds, info->port, info->lag);
329
330         if (ds->index != info->sw_index && ds->ops->crosschip_lag_leave)
331                 return ds->ops->crosschip_lag_leave(ds, info->sw_index,
332                                                     info->port, info->lag);
333
334         return 0;
335 }
336
337 static int dsa_switch_mdb_add(struct dsa_switch *ds,
338                               struct dsa_notifier_mdb_info *info)
339 {
340         int port = dsa_towards_port(ds, info->sw_index, info->port);
341
342         if (!ds->ops->port_mdb_add)
343                 return -EOPNOTSUPP;
344
345         return dsa_switch_do_mdb_add(ds, port, info->mdb);
346 }
347
348 static int dsa_switch_mdb_del(struct dsa_switch *ds,
349                               struct dsa_notifier_mdb_info *info)
350 {
351         int port = dsa_towards_port(ds, info->sw_index, info->port);
352
353         if (!ds->ops->port_mdb_del)
354                 return -EOPNOTSUPP;
355
356         return dsa_switch_do_mdb_del(ds, port, info->mdb);
357 }
358
359 static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
360                                    struct dsa_notifier_mdb_info *info)
361 {
362         int err = 0;
363         int port;
364
365         if (!ds->ops->port_mdb_add)
366                 return -EOPNOTSUPP;
367
368         for (port = 0; port < ds->num_ports; port++) {
369                 if (dsa_switch_host_address_match(ds, port, info->sw_index,
370                                                   info->port)) {
371                         err = dsa_switch_do_mdb_add(ds, port, info->mdb);
372                         if (err)
373                                 break;
374                 }
375         }
376
377         return err;
378 }
379
380 static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
381                                    struct dsa_notifier_mdb_info *info)
382 {
383         int err = 0;
384         int port;
385
386         if (!ds->ops->port_mdb_del)
387                 return -EOPNOTSUPP;
388
389         for (port = 0; port < ds->num_ports; port++) {
390                 if (dsa_switch_host_address_match(ds, port, info->sw_index,
391                                                   info->port)) {
392                         err = dsa_switch_do_mdb_del(ds, port, info->mdb);
393                         if (err)
394                                 break;
395                 }
396         }
397
398         return err;
399 }
400
401 static bool dsa_switch_vlan_match(struct dsa_switch *ds, int port,
402                                   struct dsa_notifier_vlan_info *info)
403 {
404         if (ds->index == info->sw_index && port == info->port)
405                 return true;
406
407         if (dsa_is_dsa_port(ds, port))
408                 return true;
409
410         return false;
411 }
412
413 static int dsa_switch_vlan_add(struct dsa_switch *ds,
414                                struct dsa_notifier_vlan_info *info)
415 {
416         int port, err;
417
418         if (!ds->ops->port_vlan_add)
419                 return -EOPNOTSUPP;
420
421         for (port = 0; port < ds->num_ports; port++) {
422                 if (dsa_switch_vlan_match(ds, port, info)) {
423                         err = ds->ops->port_vlan_add(ds, port, info->vlan,
424                                                      info->extack);
425                         if (err)
426                                 return err;
427                 }
428         }
429
430         return 0;
431 }
432
433 static int dsa_switch_vlan_del(struct dsa_switch *ds,
434                                struct dsa_notifier_vlan_info *info)
435 {
436         if (!ds->ops->port_vlan_del)
437                 return -EOPNOTSUPP;
438
439         if (ds->index == info->sw_index)
440                 return ds->ops->port_vlan_del(ds, info->port, info->vlan);
441
442         /* Do not deprogram the DSA links as they may be used as conduit
443          * for other VLAN members in the fabric.
444          */
445         return 0;
446 }
447
448 static int dsa_switch_change_tag_proto(struct dsa_switch *ds,
449                                        struct dsa_notifier_tag_proto_info *info)
450 {
451         const struct dsa_device_ops *tag_ops = info->tag_ops;
452         int port, err;
453
454         if (!ds->ops->change_tag_protocol)
455                 return -EOPNOTSUPP;
456
457         ASSERT_RTNL();
458
459         for (port = 0; port < ds->num_ports; port++) {
460                 if (!dsa_is_cpu_port(ds, port))
461                         continue;
462
463                 err = ds->ops->change_tag_protocol(ds, port, tag_ops->proto);
464                 if (err)
465                         return err;
466
467                 dsa_port_set_tag_protocol(dsa_to_port(ds, port), tag_ops);
468         }
469
470         /* Now that changing the tag protocol can no longer fail, let's update
471          * the remaining bits which are "duplicated for faster access", and the
472          * bits that depend on the tagger, such as the MTU.
473          */
474         for (port = 0; port < ds->num_ports; port++) {
475                 if (dsa_is_user_port(ds, port)) {
476                         struct net_device *slave;
477
478                         slave = dsa_to_port(ds, port)->slave;
479                         dsa_slave_setup_tagger(slave);
480
481                         /* rtnl_mutex is held in dsa_tree_change_tag_proto */
482                         dsa_slave_change_mtu(slave, slave->mtu);
483                 }
484         }
485
486         return 0;
487 }
488
489 static int dsa_switch_mrp_add(struct dsa_switch *ds,
490                               struct dsa_notifier_mrp_info *info)
491 {
492         if (!ds->ops->port_mrp_add)
493                 return -EOPNOTSUPP;
494
495         if (ds->index == info->sw_index)
496                 return ds->ops->port_mrp_add(ds, info->port, info->mrp);
497
498         return 0;
499 }
500
501 static int dsa_switch_mrp_del(struct dsa_switch *ds,
502                               struct dsa_notifier_mrp_info *info)
503 {
504         if (!ds->ops->port_mrp_del)
505                 return -EOPNOTSUPP;
506
507         if (ds->index == info->sw_index)
508                 return ds->ops->port_mrp_del(ds, info->port, info->mrp);
509
510         return 0;
511 }
512
513 static int
514 dsa_switch_mrp_add_ring_role(struct dsa_switch *ds,
515                              struct dsa_notifier_mrp_ring_role_info *info)
516 {
517         if (!ds->ops->port_mrp_add)
518                 return -EOPNOTSUPP;
519
520         if (ds->index == info->sw_index)
521                 return ds->ops->port_mrp_add_ring_role(ds, info->port,
522                                                        info->mrp);
523
524         return 0;
525 }
526
527 static int
528 dsa_switch_mrp_del_ring_role(struct dsa_switch *ds,
529                              struct dsa_notifier_mrp_ring_role_info *info)
530 {
531         if (!ds->ops->port_mrp_del)
532                 return -EOPNOTSUPP;
533
534         if (ds->index == info->sw_index)
535                 return ds->ops->port_mrp_del_ring_role(ds, info->port,
536                                                        info->mrp);
537
538         return 0;
539 }
540
541 static int dsa_switch_event(struct notifier_block *nb,
542                             unsigned long event, void *info)
543 {
544         struct dsa_switch *ds = container_of(nb, struct dsa_switch, nb);
545         int err;
546
547         switch (event) {
548         case DSA_NOTIFIER_AGEING_TIME:
549                 err = dsa_switch_ageing_time(ds, info);
550                 break;
551         case DSA_NOTIFIER_BRIDGE_JOIN:
552                 err = dsa_switch_bridge_join(ds, info);
553                 break;
554         case DSA_NOTIFIER_BRIDGE_LEAVE:
555                 err = dsa_switch_bridge_leave(ds, info);
556                 break;
557         case DSA_NOTIFIER_FDB_ADD:
558                 err = dsa_switch_fdb_add(ds, info);
559                 break;
560         case DSA_NOTIFIER_FDB_DEL:
561                 err = dsa_switch_fdb_del(ds, info);
562                 break;
563         case DSA_NOTIFIER_HSR_JOIN:
564                 err = dsa_switch_hsr_join(ds, info);
565                 break;
566         case DSA_NOTIFIER_HSR_LEAVE:
567                 err = dsa_switch_hsr_leave(ds, info);
568                 break;
569         case DSA_NOTIFIER_LAG_CHANGE:
570                 err = dsa_switch_lag_change(ds, info);
571                 break;
572         case DSA_NOTIFIER_LAG_JOIN:
573                 err = dsa_switch_lag_join(ds, info);
574                 break;
575         case DSA_NOTIFIER_LAG_LEAVE:
576                 err = dsa_switch_lag_leave(ds, info);
577                 break;
578         case DSA_NOTIFIER_MDB_ADD:
579                 err = dsa_switch_mdb_add(ds, info);
580                 break;
581         case DSA_NOTIFIER_MDB_DEL:
582                 err = dsa_switch_mdb_del(ds, info);
583                 break;
584         case DSA_NOTIFIER_HOST_MDB_ADD:
585                 err = dsa_switch_host_mdb_add(ds, info);
586                 break;
587         case DSA_NOTIFIER_HOST_MDB_DEL:
588                 err = dsa_switch_host_mdb_del(ds, info);
589                 break;
590         case DSA_NOTIFIER_VLAN_ADD:
591                 err = dsa_switch_vlan_add(ds, info);
592                 break;
593         case DSA_NOTIFIER_VLAN_DEL:
594                 err = dsa_switch_vlan_del(ds, info);
595                 break;
596         case DSA_NOTIFIER_MTU:
597                 err = dsa_switch_mtu(ds, info);
598                 break;
599         case DSA_NOTIFIER_TAG_PROTO:
600                 err = dsa_switch_change_tag_proto(ds, info);
601                 break;
602         case DSA_NOTIFIER_MRP_ADD:
603                 err = dsa_switch_mrp_add(ds, info);
604                 break;
605         case DSA_NOTIFIER_MRP_DEL:
606                 err = dsa_switch_mrp_del(ds, info);
607                 break;
608         case DSA_NOTIFIER_MRP_ADD_RING_ROLE:
609                 err = dsa_switch_mrp_add_ring_role(ds, info);
610                 break;
611         case DSA_NOTIFIER_MRP_DEL_RING_ROLE:
612                 err = dsa_switch_mrp_del_ring_role(ds, info);
613                 break;
614         default:
615                 err = -EOPNOTSUPP;
616                 break;
617         }
618
619         if (err)
620                 dev_dbg(ds->dev, "breaking chain for DSA event %lu (%d)\n",
621                         event, err);
622
623         return notifier_from_errno(err);
624 }
625
626 int dsa_switch_register_notifier(struct dsa_switch *ds)
627 {
628         ds->nb.notifier_call = dsa_switch_event;
629
630         return raw_notifier_chain_register(&ds->dst->nh, &ds->nb);
631 }
632
633 void dsa_switch_unregister_notifier(struct dsa_switch *ds)
634 {
635         int err;
636
637         err = raw_notifier_chain_unregister(&ds->dst->nh, &ds->nb);
638         if (err)
639                 dev_err(ds->dev, "failed to unregister notifier (%d)\n", err);
640 }