4d5fbacef496fdb63ad6cca61bc21ab8617560a4
[linux-block.git] / net / switchdev / switchdev.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * net/switchdev/switchdev.c - Switch device API
4  * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
5  * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/types.h>
10 #include <linux/init.h>
11 #include <linux/mutex.h>
12 #include <linux/notifier.h>
13 #include <linux/netdevice.h>
14 #include <linux/etherdevice.h>
15 #include <linux/if_bridge.h>
16 #include <linux/list.h>
17 #include <linux/workqueue.h>
18 #include <linux/if_vlan.h>
19 #include <linux/rtnetlink.h>
20 #include <net/switchdev.h>
21
22 static bool switchdev_obj_eq(const struct switchdev_obj *a,
23                              const struct switchdev_obj *b)
24 {
25         const struct switchdev_obj_port_vlan *va, *vb;
26         const struct switchdev_obj_port_mdb *ma, *mb;
27
28         if (a->id != b->id || a->orig_dev != b->orig_dev)
29                 return false;
30
31         switch (a->id) {
32         case SWITCHDEV_OBJ_ID_PORT_VLAN:
33                 va = SWITCHDEV_OBJ_PORT_VLAN(a);
34                 vb = SWITCHDEV_OBJ_PORT_VLAN(b);
35                 return va->flags == vb->flags &&
36                         va->vid == vb->vid &&
37                         va->changed == vb->changed;
38         case SWITCHDEV_OBJ_ID_PORT_MDB:
39         case SWITCHDEV_OBJ_ID_HOST_MDB:
40                 ma = SWITCHDEV_OBJ_PORT_MDB(a);
41                 mb = SWITCHDEV_OBJ_PORT_MDB(b);
42                 return ma->vid == mb->vid &&
43                         ether_addr_equal(ma->addr, mb->addr);
44         default:
45                 break;
46         }
47
48         BUG();
49 }
50
51 static LIST_HEAD(deferred);
52 static DEFINE_SPINLOCK(deferred_lock);
53
54 typedef void switchdev_deferred_func_t(struct net_device *dev,
55                                        const void *data);
56
57 struct switchdev_deferred_item {
58         struct list_head list;
59         struct net_device *dev;
60         netdevice_tracker dev_tracker;
61         switchdev_deferred_func_t *func;
62         unsigned long data[];
63 };
64
65 static struct switchdev_deferred_item *switchdev_deferred_dequeue(void)
66 {
67         struct switchdev_deferred_item *dfitem;
68
69         spin_lock_bh(&deferred_lock);
70         if (list_empty(&deferred)) {
71                 dfitem = NULL;
72                 goto unlock;
73         }
74         dfitem = list_first_entry(&deferred,
75                                   struct switchdev_deferred_item, list);
76         list_del(&dfitem->list);
77 unlock:
78         spin_unlock_bh(&deferred_lock);
79         return dfitem;
80 }
81
82 /**
83  *      switchdev_deferred_process - Process ops in deferred queue
84  *
85  *      Called to flush the ops currently queued in deferred ops queue.
86  *      rtnl_lock must be held.
87  */
88 void switchdev_deferred_process(void)
89 {
90         struct switchdev_deferred_item *dfitem;
91
92         ASSERT_RTNL();
93
94         while ((dfitem = switchdev_deferred_dequeue())) {
95                 dfitem->func(dfitem->dev, dfitem->data);
96                 netdev_put(dfitem->dev, &dfitem->dev_tracker);
97                 kfree(dfitem);
98         }
99 }
100 EXPORT_SYMBOL_GPL(switchdev_deferred_process);
101
102 static void switchdev_deferred_process_work(struct work_struct *work)
103 {
104         rtnl_lock();
105         switchdev_deferred_process();
106         rtnl_unlock();
107 }
108
109 static DECLARE_WORK(deferred_process_work, switchdev_deferred_process_work);
110
111 static int switchdev_deferred_enqueue(struct net_device *dev,
112                                       const void *data, size_t data_len,
113                                       switchdev_deferred_func_t *func)
114 {
115         struct switchdev_deferred_item *dfitem;
116
117         dfitem = kmalloc(struct_size(dfitem, data, data_len), GFP_ATOMIC);
118         if (!dfitem)
119                 return -ENOMEM;
120         dfitem->dev = dev;
121         dfitem->func = func;
122         memcpy(dfitem->data, data, data_len);
123         netdev_hold(dev, &dfitem->dev_tracker, GFP_ATOMIC);
124         spin_lock_bh(&deferred_lock);
125         list_add_tail(&dfitem->list, &deferred);
126         spin_unlock_bh(&deferred_lock);
127         schedule_work(&deferred_process_work);
128         return 0;
129 }
130
131 static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
132                                       struct net_device *dev,
133                                       const struct switchdev_attr *attr,
134                                       struct netlink_ext_ack *extack)
135 {
136         int err;
137         int rc;
138
139         struct switchdev_notifier_port_attr_info attr_info = {
140                 .attr = attr,
141                 .handled = false,
142         };
143
144         rc = call_switchdev_blocking_notifiers(nt, dev,
145                                                &attr_info.info, extack);
146         err = notifier_to_errno(rc);
147         if (err) {
148                 WARN_ON(!attr_info.handled);
149                 return err;
150         }
151
152         if (!attr_info.handled)
153                 return -EOPNOTSUPP;
154
155         return 0;
156 }
157
158 static int switchdev_port_attr_set_now(struct net_device *dev,
159                                        const struct switchdev_attr *attr,
160                                        struct netlink_ext_ack *extack)
161 {
162         return switchdev_port_attr_notify(SWITCHDEV_PORT_ATTR_SET, dev, attr,
163                                           extack);
164 }
165
166 static void switchdev_port_attr_set_deferred(struct net_device *dev,
167                                              const void *data)
168 {
169         const struct switchdev_attr *attr = data;
170         int err;
171
172         err = switchdev_port_attr_set_now(dev, attr, NULL);
173         if (err && err != -EOPNOTSUPP)
174                 netdev_err(dev, "failed (err=%d) to set attribute (id=%d)\n",
175                            err, attr->id);
176         if (attr->complete)
177                 attr->complete(dev, err, attr->complete_priv);
178 }
179
180 static int switchdev_port_attr_set_defer(struct net_device *dev,
181                                          const struct switchdev_attr *attr)
182 {
183         return switchdev_deferred_enqueue(dev, attr, sizeof(*attr),
184                                           switchdev_port_attr_set_deferred);
185 }
186
187 /**
188  *      switchdev_port_attr_set - Set port attribute
189  *
190  *      @dev: port device
191  *      @attr: attribute to set
192  *      @extack: netlink extended ack, for error message propagation
193  *
194  *      rtnl_lock must be held and must not be in atomic section,
195  *      in case SWITCHDEV_F_DEFER flag is not set.
196  */
197 int switchdev_port_attr_set(struct net_device *dev,
198                             const struct switchdev_attr *attr,
199                             struct netlink_ext_ack *extack)
200 {
201         if (attr->flags & SWITCHDEV_F_DEFER)
202                 return switchdev_port_attr_set_defer(dev, attr);
203         ASSERT_RTNL();
204         return switchdev_port_attr_set_now(dev, attr, extack);
205 }
206 EXPORT_SYMBOL_GPL(switchdev_port_attr_set);
207
208 static size_t switchdev_obj_size(const struct switchdev_obj *obj)
209 {
210         switch (obj->id) {
211         case SWITCHDEV_OBJ_ID_PORT_VLAN:
212                 return sizeof(struct switchdev_obj_port_vlan);
213         case SWITCHDEV_OBJ_ID_PORT_MDB:
214                 return sizeof(struct switchdev_obj_port_mdb);
215         case SWITCHDEV_OBJ_ID_HOST_MDB:
216                 return sizeof(struct switchdev_obj_port_mdb);
217         default:
218                 BUG();
219         }
220         return 0;
221 }
222
223 static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
224                                      struct net_device *dev,
225                                      const struct switchdev_obj *obj,
226                                      struct netlink_ext_ack *extack)
227 {
228         int rc;
229         int err;
230
231         struct switchdev_notifier_port_obj_info obj_info = {
232                 .obj = obj,
233                 .handled = false,
234         };
235
236         rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info, extack);
237         err = notifier_to_errno(rc);
238         if (err) {
239                 WARN_ON(!obj_info.handled);
240                 return err;
241         }
242         if (!obj_info.handled)
243                 return -EOPNOTSUPP;
244         return 0;
245 }
246
247 static void switchdev_obj_id_to_helpful_msg(struct net_device *dev,
248                                             enum switchdev_obj_id obj_id,
249                                             int err, bool add)
250 {
251         const char *action = add ? "add" : "del";
252         const char *reason = "";
253         const char *problem;
254         const char *obj_str;
255
256         switch (obj_id) {
257         case SWITCHDEV_OBJ_ID_UNDEFINED:
258                 obj_str = "Undefined object";
259                 problem = "Attempted operation is undefined, indicating a possible programming\n"
260                           "error.\n";
261                 break;
262         case SWITCHDEV_OBJ_ID_PORT_VLAN:
263                 obj_str = "VLAN entry";
264                 problem = "Failure in VLAN settings on this port might disrupt network\n"
265                           "segmentation or traffic isolation, affecting network partitioning.\n";
266                 break;
267         case SWITCHDEV_OBJ_ID_PORT_MDB:
268                 obj_str = "Port Multicast Database entry";
269                 problem = "Failure in updating the port's Multicast Database could lead to\n"
270                           "multicast forwarding issues.\n";
271                 break;
272         case SWITCHDEV_OBJ_ID_HOST_MDB:
273                 obj_str = "Host Multicast Database entry";
274                 problem = "Failure in updating the host's Multicast Database may impact multicast\n"
275                           "group memberships or traffic delivery, affecting multicast\n"
276                           "communication.\n";
277                 break;
278         case SWITCHDEV_OBJ_ID_MRP:
279                 obj_str = "Media Redundancy Protocol configuration for port";
280                 problem = "Failure to set MRP ring ID on this port prevents communication with\n"
281                           "the specified redundancy ring, resulting in an inability to engage\n"
282                           "in MRP-based network operations.\n";
283                 break;
284         case SWITCHDEV_OBJ_ID_RING_TEST_MRP:
285                 obj_str = "MRP Test Frame Operations for port";
286                 problem = "Failure to generate/monitor MRP test frames may lead to inability to\n"
287                           "assess the ring's operational integrity and fault response, hindering\n"
288                           "proactive network management.\n";
289                 break;
290         case SWITCHDEV_OBJ_ID_RING_ROLE_MRP:
291                 obj_str = "MRP Ring Role Configuration";
292                 problem = "Improper MRP ring role configuration may create conflicts in the ring,\n"
293                           "disrupting communication for all participants, or isolate the local\n"
294                           "system from the ring, hindering its ability to communicate with other\n"
295                           "participants.\n";
296                 break;
297         case SWITCHDEV_OBJ_ID_RING_STATE_MRP:
298                 obj_str = "MRP Ring State Configuration";
299                 problem = "Failure to correctly set the MRP ring state can result in network\n"
300                           "loops or leave segments without communication. In a Closed state,\n"
301                           "it maintains loop prevention by blocking one MRM port, while an Open\n"
302                           "state activates in response to failures, changing port states to\n"
303                           "preserve network connectivity.\n";
304                 break;
305         case SWITCHDEV_OBJ_ID_IN_TEST_MRP:
306                 obj_str = "MRP_InTest Frame Generation Configuration";
307                 problem = "Failure in managing MRP_InTest frame generation can misjudge the\n"
308                           "interconnection ring's state, leading to incorrect blocking or\n"
309                           "unblocking of the I/C port. This misconfiguration might result\n"
310                           "in unintended network loops or isolate critical network segments,\n"
311                           "compromising network integrity and reliability.\n";
312                 break;
313         case SWITCHDEV_OBJ_ID_IN_ROLE_MRP:
314                 obj_str = "Interconnection Ring Role Configuration";
315                 problem = "Failure in incorrect assignment of interconnection ring roles\n"
316                           "(MIM/MIC) can impair the formation of the interconnection rings.\n";
317                 break;
318         case SWITCHDEV_OBJ_ID_IN_STATE_MRP:
319                 obj_str = "Interconnection Ring State Configuration";
320                 problem = "Failure in updating the interconnection ring state can lead in\n"
321                           "case of Open state to incorrect blocking or unblocking of the\n"
322                           "I/C port, resulting in unintended network loops or isolation\n"
323                           "of critical network\n";
324                 break;
325         default:
326                 obj_str = "Unknown object";
327                 problem = "Indicating a possible programming error.\n";
328         }
329
330         switch (err) {
331         case -ENOSPC:
332                 reason = "Current HW/SW setup lacks sufficient resources.\n";
333                 break;
334         }
335
336         netdev_err(dev, "Failed to %s %s (object id=%d) with error: %pe (%d).\n%s%s\n",
337                    action, obj_str, obj_id, ERR_PTR(err), err, problem, reason);
338 }
339
340 static void switchdev_port_obj_add_deferred(struct net_device *dev,
341                                             const void *data)
342 {
343         const struct switchdev_obj *obj = data;
344         int err;
345
346         ASSERT_RTNL();
347         err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
348                                         dev, obj, NULL);
349         if (err && err != -EOPNOTSUPP)
350                 switchdev_obj_id_to_helpful_msg(dev, obj->id, err, true);
351         if (obj->complete)
352                 obj->complete(dev, err, obj->complete_priv);
353 }
354
355 static int switchdev_port_obj_add_defer(struct net_device *dev,
356                                         const struct switchdev_obj *obj)
357 {
358         return switchdev_deferred_enqueue(dev, obj, switchdev_obj_size(obj),
359                                           switchdev_port_obj_add_deferred);
360 }
361
362 /**
363  *      switchdev_port_obj_add - Add port object
364  *
365  *      @dev: port device
366  *      @obj: object to add
367  *      @extack: netlink extended ack
368  *
369  *      rtnl_lock must be held and must not be in atomic section,
370  *      in case SWITCHDEV_F_DEFER flag is not set.
371  */
372 int switchdev_port_obj_add(struct net_device *dev,
373                            const struct switchdev_obj *obj,
374                            struct netlink_ext_ack *extack)
375 {
376         if (obj->flags & SWITCHDEV_F_DEFER)
377                 return switchdev_port_obj_add_defer(dev, obj);
378         ASSERT_RTNL();
379         return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
380                                          dev, obj, extack);
381 }
382 EXPORT_SYMBOL_GPL(switchdev_port_obj_add);
383
384 static int switchdev_port_obj_del_now(struct net_device *dev,
385                                       const struct switchdev_obj *obj)
386 {
387         return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL,
388                                          dev, obj, NULL);
389 }
390
391 static void switchdev_port_obj_del_deferred(struct net_device *dev,
392                                             const void *data)
393 {
394         const struct switchdev_obj *obj = data;
395         int err;
396
397         err = switchdev_port_obj_del_now(dev, obj);
398         if (err && err != -EOPNOTSUPP)
399                 switchdev_obj_id_to_helpful_msg(dev, obj->id, err, false);
400         if (obj->complete)
401                 obj->complete(dev, err, obj->complete_priv);
402 }
403
404 static int switchdev_port_obj_del_defer(struct net_device *dev,
405                                         const struct switchdev_obj *obj)
406 {
407         return switchdev_deferred_enqueue(dev, obj, switchdev_obj_size(obj),
408                                           switchdev_port_obj_del_deferred);
409 }
410
411 /**
412  *      switchdev_port_obj_del - Delete port object
413  *
414  *      @dev: port device
415  *      @obj: object to delete
416  *
417  *      rtnl_lock must be held and must not be in atomic section,
418  *      in case SWITCHDEV_F_DEFER flag is not set.
419  */
420 int switchdev_port_obj_del(struct net_device *dev,
421                            const struct switchdev_obj *obj)
422 {
423         if (obj->flags & SWITCHDEV_F_DEFER)
424                 return switchdev_port_obj_del_defer(dev, obj);
425         ASSERT_RTNL();
426         return switchdev_port_obj_del_now(dev, obj);
427 }
428 EXPORT_SYMBOL_GPL(switchdev_port_obj_del);
429
430 /**
431  *      switchdev_port_obj_act_is_deferred - Is object action pending?
432  *
433  *      @dev: port device
434  *      @nt: type of action; add or delete
435  *      @obj: object to test
436  *
437  *      Returns true if a deferred item is pending, which is
438  *      equivalent to the action @nt on an object @obj.
439  *
440  *      rtnl_lock must be held.
441  */
442 bool switchdev_port_obj_act_is_deferred(struct net_device *dev,
443                                         enum switchdev_notifier_type nt,
444                                         const struct switchdev_obj *obj)
445 {
446         struct switchdev_deferred_item *dfitem;
447         bool found = false;
448
449         ASSERT_RTNL();
450
451         spin_lock_bh(&deferred_lock);
452
453         list_for_each_entry(dfitem, &deferred, list) {
454                 if (dfitem->dev != dev)
455                         continue;
456
457                 if ((dfitem->func == switchdev_port_obj_add_deferred &&
458                      nt == SWITCHDEV_PORT_OBJ_ADD) ||
459                     (dfitem->func == switchdev_port_obj_del_deferred &&
460                      nt == SWITCHDEV_PORT_OBJ_DEL)) {
461                         if (switchdev_obj_eq((const void *)dfitem->data, obj)) {
462                                 found = true;
463                                 break;
464                         }
465                 }
466         }
467
468         spin_unlock_bh(&deferred_lock);
469
470         return found;
471 }
472 EXPORT_SYMBOL_GPL(switchdev_port_obj_act_is_deferred);
473
474 static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain);
475 static RAW_NOTIFIER_HEAD(switchdev_blocking_notif_chain);
476
477 /**
478  *      register_switchdev_notifier - Register notifier
479  *      @nb: notifier_block
480  *
481  *      Register switch device notifier.
482  */
483 int register_switchdev_notifier(struct notifier_block *nb)
484 {
485         return atomic_notifier_chain_register(&switchdev_notif_chain, nb);
486 }
487 EXPORT_SYMBOL_GPL(register_switchdev_notifier);
488
489 /**
490  *      unregister_switchdev_notifier - Unregister notifier
491  *      @nb: notifier_block
492  *
493  *      Unregister switch device notifier.
494  */
495 int unregister_switchdev_notifier(struct notifier_block *nb)
496 {
497         return atomic_notifier_chain_unregister(&switchdev_notif_chain, nb);
498 }
499 EXPORT_SYMBOL_GPL(unregister_switchdev_notifier);
500
501 /**
502  *      call_switchdev_notifiers - Call notifiers
503  *      @val: value passed unmodified to notifier function
504  *      @dev: port device
505  *      @info: notifier information data
506  *      @extack: netlink extended ack
507  *      Call all network notifier blocks.
508  */
509 int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
510                              struct switchdev_notifier_info *info,
511                              struct netlink_ext_ack *extack)
512 {
513         info->dev = dev;
514         info->extack = extack;
515         return atomic_notifier_call_chain(&switchdev_notif_chain, val, info);
516 }
517 EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
518
519 int register_switchdev_blocking_notifier(struct notifier_block *nb)
520 {
521         struct raw_notifier_head *chain = &switchdev_blocking_notif_chain;
522         int err;
523
524         rtnl_lock();
525         err = raw_notifier_chain_register(chain, nb);
526         rtnl_unlock();
527
528         return err;
529 }
530 EXPORT_SYMBOL_GPL(register_switchdev_blocking_notifier);
531
532 int unregister_switchdev_blocking_notifier(struct notifier_block *nb)
533 {
534         struct raw_notifier_head *chain = &switchdev_blocking_notif_chain;
535         int err;
536
537         rtnl_lock();
538         err = raw_notifier_chain_unregister(chain, nb);
539         rtnl_unlock();
540
541         return err;
542 }
543 EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier);
544
545 int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
546                                       struct switchdev_notifier_info *info,
547                                       struct netlink_ext_ack *extack)
548 {
549         ASSERT_RTNL();
550         info->dev = dev;
551         info->extack = extack;
552         return raw_notifier_call_chain(&switchdev_blocking_notif_chain,
553                                        val, info);
554 }
555 EXPORT_SYMBOL_GPL(call_switchdev_blocking_notifiers);
556
557 struct switchdev_nested_priv {
558         bool (*check_cb)(const struct net_device *dev);
559         bool (*foreign_dev_check_cb)(const struct net_device *dev,
560                                      const struct net_device *foreign_dev);
561         const struct net_device *dev;
562         struct net_device *lower_dev;
563 };
564
565 static int switchdev_lower_dev_walk(struct net_device *lower_dev,
566                                     struct netdev_nested_priv *priv)
567 {
568         struct switchdev_nested_priv *switchdev_priv = priv->data;
569         bool (*foreign_dev_check_cb)(const struct net_device *dev,
570                                      const struct net_device *foreign_dev);
571         bool (*check_cb)(const struct net_device *dev);
572         const struct net_device *dev;
573
574         check_cb = switchdev_priv->check_cb;
575         foreign_dev_check_cb = switchdev_priv->foreign_dev_check_cb;
576         dev = switchdev_priv->dev;
577
578         if (check_cb(lower_dev) && !foreign_dev_check_cb(lower_dev, dev)) {
579                 switchdev_priv->lower_dev = lower_dev;
580                 return 1;
581         }
582
583         return 0;
584 }
585
586 static struct net_device *
587 switchdev_lower_dev_find_rcu(struct net_device *dev,
588                              bool (*check_cb)(const struct net_device *dev),
589                              bool (*foreign_dev_check_cb)(const struct net_device *dev,
590                                                           const struct net_device *foreign_dev))
591 {
592         struct switchdev_nested_priv switchdev_priv = {
593                 .check_cb = check_cb,
594                 .foreign_dev_check_cb = foreign_dev_check_cb,
595                 .dev = dev,
596                 .lower_dev = NULL,
597         };
598         struct netdev_nested_priv priv = {
599                 .data = &switchdev_priv,
600         };
601
602         netdev_walk_all_lower_dev_rcu(dev, switchdev_lower_dev_walk, &priv);
603
604         return switchdev_priv.lower_dev;
605 }
606
607 static struct net_device *
608 switchdev_lower_dev_find(struct net_device *dev,
609                          bool (*check_cb)(const struct net_device *dev),
610                          bool (*foreign_dev_check_cb)(const struct net_device *dev,
611                                                       const struct net_device *foreign_dev))
612 {
613         struct switchdev_nested_priv switchdev_priv = {
614                 .check_cb = check_cb,
615                 .foreign_dev_check_cb = foreign_dev_check_cb,
616                 .dev = dev,
617                 .lower_dev = NULL,
618         };
619         struct netdev_nested_priv priv = {
620                 .data = &switchdev_priv,
621         };
622
623         netdev_walk_all_lower_dev(dev, switchdev_lower_dev_walk, &priv);
624
625         return switchdev_priv.lower_dev;
626 }
627
628 static int __switchdev_handle_fdb_event_to_device(struct net_device *dev,
629                 struct net_device *orig_dev, unsigned long event,
630                 const struct switchdev_notifier_fdb_info *fdb_info,
631                 bool (*check_cb)(const struct net_device *dev),
632                 bool (*foreign_dev_check_cb)(const struct net_device *dev,
633                                              const struct net_device *foreign_dev),
634                 int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
635                               unsigned long event, const void *ctx,
636                               const struct switchdev_notifier_fdb_info *fdb_info))
637 {
638         const struct switchdev_notifier_info *info = &fdb_info->info;
639         struct net_device *br, *lower_dev, *switchdev;
640         struct list_head *iter;
641         int err = -EOPNOTSUPP;
642
643         if (check_cb(dev))
644                 return mod_cb(dev, orig_dev, event, info->ctx, fdb_info);
645
646         /* Recurse through lower interfaces in case the FDB entry is pointing
647          * towards a bridge or a LAG device.
648          */
649         netdev_for_each_lower_dev(dev, lower_dev, iter) {
650                 /* Do not propagate FDB entries across bridges */
651                 if (netif_is_bridge_master(lower_dev))
652                         continue;
653
654                 /* Bridge ports might be either us, or LAG interfaces
655                  * that we offload.
656                  */
657                 if (!check_cb(lower_dev) &&
658                     !switchdev_lower_dev_find_rcu(lower_dev, check_cb,
659                                                   foreign_dev_check_cb))
660                         continue;
661
662                 err = __switchdev_handle_fdb_event_to_device(lower_dev, orig_dev,
663                                                              event, fdb_info, check_cb,
664                                                              foreign_dev_check_cb,
665                                                              mod_cb);
666                 if (err && err != -EOPNOTSUPP)
667                         return err;
668         }
669
670         /* Event is neither on a bridge nor a LAG. Check whether it is on an
671          * interface that is in a bridge with us.
672          */
673         br = netdev_master_upper_dev_get_rcu(dev);
674         if (!br || !netif_is_bridge_master(br))
675                 return 0;
676
677         switchdev = switchdev_lower_dev_find_rcu(br, check_cb, foreign_dev_check_cb);
678         if (!switchdev)
679                 return 0;
680
681         if (!foreign_dev_check_cb(switchdev, dev))
682                 return err;
683
684         return __switchdev_handle_fdb_event_to_device(br, orig_dev, event, fdb_info,
685                                                       check_cb, foreign_dev_check_cb,
686                                                       mod_cb);
687 }
688
689 int switchdev_handle_fdb_event_to_device(struct net_device *dev, unsigned long event,
690                 const struct switchdev_notifier_fdb_info *fdb_info,
691                 bool (*check_cb)(const struct net_device *dev),
692                 bool (*foreign_dev_check_cb)(const struct net_device *dev,
693                                              const struct net_device *foreign_dev),
694                 int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
695                               unsigned long event, const void *ctx,
696                               const struct switchdev_notifier_fdb_info *fdb_info))
697 {
698         int err;
699
700         err = __switchdev_handle_fdb_event_to_device(dev, dev, event, fdb_info,
701                                                      check_cb, foreign_dev_check_cb,
702                                                      mod_cb);
703         if (err == -EOPNOTSUPP)
704                 err = 0;
705
706         return err;
707 }
708 EXPORT_SYMBOL_GPL(switchdev_handle_fdb_event_to_device);
709
710 static int __switchdev_handle_port_obj_add(struct net_device *dev,
711                         struct switchdev_notifier_port_obj_info *port_obj_info,
712                         bool (*check_cb)(const struct net_device *dev),
713                         bool (*foreign_dev_check_cb)(const struct net_device *dev,
714                                                      const struct net_device *foreign_dev),
715                         int (*add_cb)(struct net_device *dev, const void *ctx,
716                                       const struct switchdev_obj *obj,
717                                       struct netlink_ext_ack *extack))
718 {
719         struct switchdev_notifier_info *info = &port_obj_info->info;
720         struct net_device *br, *lower_dev, *switchdev;
721         struct netlink_ext_ack *extack;
722         struct list_head *iter;
723         int err = -EOPNOTSUPP;
724
725         extack = switchdev_notifier_info_to_extack(info);
726
727         if (check_cb(dev)) {
728                 err = add_cb(dev, info->ctx, port_obj_info->obj, extack);
729                 if (err != -EOPNOTSUPP)
730                         port_obj_info->handled = true;
731                 return err;
732         }
733
734         /* Switch ports might be stacked under e.g. a LAG. Ignore the
735          * unsupported devices, another driver might be able to handle them. But
736          * propagate to the callers any hard errors.
737          *
738          * If the driver does its own bookkeeping of stacked ports, it's not
739          * necessary to go through this helper.
740          */
741         netdev_for_each_lower_dev(dev, lower_dev, iter) {
742                 if (netif_is_bridge_master(lower_dev))
743                         continue;
744
745                 /* When searching for switchdev interfaces that are neighbors
746                  * of foreign ones, and @dev is a bridge, do not recurse on the
747                  * foreign interface again, it was already visited.
748                  */
749                 if (foreign_dev_check_cb && !check_cb(lower_dev) &&
750                     !switchdev_lower_dev_find(lower_dev, check_cb, foreign_dev_check_cb))
751                         continue;
752
753                 err = __switchdev_handle_port_obj_add(lower_dev, port_obj_info,
754                                                       check_cb, foreign_dev_check_cb,
755                                                       add_cb);
756                 if (err && err != -EOPNOTSUPP)
757                         return err;
758         }
759
760         /* Event is neither on a bridge nor a LAG. Check whether it is on an
761          * interface that is in a bridge with us.
762          */
763         if (!foreign_dev_check_cb)
764                 return err;
765
766         br = netdev_master_upper_dev_get(dev);
767         if (!br || !netif_is_bridge_master(br))
768                 return err;
769
770         switchdev = switchdev_lower_dev_find(br, check_cb, foreign_dev_check_cb);
771         if (!switchdev)
772                 return err;
773
774         if (!foreign_dev_check_cb(switchdev, dev))
775                 return err;
776
777         return __switchdev_handle_port_obj_add(br, port_obj_info, check_cb,
778                                                foreign_dev_check_cb, add_cb);
779 }
780
781 /* Pass through a port object addition, if @dev passes @check_cb, or replicate
782  * it towards all lower interfaces of @dev that pass @check_cb, if @dev is a
783  * bridge or a LAG.
784  */
785 int switchdev_handle_port_obj_add(struct net_device *dev,
786                         struct switchdev_notifier_port_obj_info *port_obj_info,
787                         bool (*check_cb)(const struct net_device *dev),
788                         int (*add_cb)(struct net_device *dev, const void *ctx,
789                                       const struct switchdev_obj *obj,
790                                       struct netlink_ext_ack *extack))
791 {
792         int err;
793
794         err = __switchdev_handle_port_obj_add(dev, port_obj_info, check_cb,
795                                               NULL, add_cb);
796         if (err == -EOPNOTSUPP)
797                 err = 0;
798         return err;
799 }
800 EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_add);
801
802 /* Same as switchdev_handle_port_obj_add(), except if object is notified on a
803  * @dev that passes @foreign_dev_check_cb, it is replicated towards all devices
804  * that pass @check_cb and are in the same bridge as @dev.
805  */
806 int switchdev_handle_port_obj_add_foreign(struct net_device *dev,
807                         struct switchdev_notifier_port_obj_info *port_obj_info,
808                         bool (*check_cb)(const struct net_device *dev),
809                         bool (*foreign_dev_check_cb)(const struct net_device *dev,
810                                                      const struct net_device *foreign_dev),
811                         int (*add_cb)(struct net_device *dev, const void *ctx,
812                                       const struct switchdev_obj *obj,
813                                       struct netlink_ext_ack *extack))
814 {
815         int err;
816
817         err = __switchdev_handle_port_obj_add(dev, port_obj_info, check_cb,
818                                               foreign_dev_check_cb, add_cb);
819         if (err == -EOPNOTSUPP)
820                 err = 0;
821         return err;
822 }
823 EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_add_foreign);
824
825 static int __switchdev_handle_port_obj_del(struct net_device *dev,
826                         struct switchdev_notifier_port_obj_info *port_obj_info,
827                         bool (*check_cb)(const struct net_device *dev),
828                         bool (*foreign_dev_check_cb)(const struct net_device *dev,
829                                                      const struct net_device *foreign_dev),
830                         int (*del_cb)(struct net_device *dev, const void *ctx,
831                                       const struct switchdev_obj *obj))
832 {
833         struct switchdev_notifier_info *info = &port_obj_info->info;
834         struct net_device *br, *lower_dev, *switchdev;
835         struct list_head *iter;
836         int err = -EOPNOTSUPP;
837
838         if (check_cb(dev)) {
839                 err = del_cb(dev, info->ctx, port_obj_info->obj);
840                 if (err != -EOPNOTSUPP)
841                         port_obj_info->handled = true;
842                 return err;
843         }
844
845         /* Switch ports might be stacked under e.g. a LAG. Ignore the
846          * unsupported devices, another driver might be able to handle them. But
847          * propagate to the callers any hard errors.
848          *
849          * If the driver does its own bookkeeping of stacked ports, it's not
850          * necessary to go through this helper.
851          */
852         netdev_for_each_lower_dev(dev, lower_dev, iter) {
853                 if (netif_is_bridge_master(lower_dev))
854                         continue;
855
856                 /* When searching for switchdev interfaces that are neighbors
857                  * of foreign ones, and @dev is a bridge, do not recurse on the
858                  * foreign interface again, it was already visited.
859                  */
860                 if (foreign_dev_check_cb && !check_cb(lower_dev) &&
861                     !switchdev_lower_dev_find(lower_dev, check_cb, foreign_dev_check_cb))
862                         continue;
863
864                 err = __switchdev_handle_port_obj_del(lower_dev, port_obj_info,
865                                                       check_cb, foreign_dev_check_cb,
866                                                       del_cb);
867                 if (err && err != -EOPNOTSUPP)
868                         return err;
869         }
870
871         /* Event is neither on a bridge nor a LAG. Check whether it is on an
872          * interface that is in a bridge with us.
873          */
874         if (!foreign_dev_check_cb)
875                 return err;
876
877         br = netdev_master_upper_dev_get(dev);
878         if (!br || !netif_is_bridge_master(br))
879                 return err;
880
881         switchdev = switchdev_lower_dev_find(br, check_cb, foreign_dev_check_cb);
882         if (!switchdev)
883                 return err;
884
885         if (!foreign_dev_check_cb(switchdev, dev))
886                 return err;
887
888         return __switchdev_handle_port_obj_del(br, port_obj_info, check_cb,
889                                                foreign_dev_check_cb, del_cb);
890 }
891
892 /* Pass through a port object deletion, if @dev passes @check_cb, or replicate
893  * it towards all lower interfaces of @dev that pass @check_cb, if @dev is a
894  * bridge or a LAG.
895  */
896 int switchdev_handle_port_obj_del(struct net_device *dev,
897                         struct switchdev_notifier_port_obj_info *port_obj_info,
898                         bool (*check_cb)(const struct net_device *dev),
899                         int (*del_cb)(struct net_device *dev, const void *ctx,
900                                       const struct switchdev_obj *obj))
901 {
902         int err;
903
904         err = __switchdev_handle_port_obj_del(dev, port_obj_info, check_cb,
905                                               NULL, del_cb);
906         if (err == -EOPNOTSUPP)
907                 err = 0;
908         return err;
909 }
910 EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del);
911
912 /* Same as switchdev_handle_port_obj_del(), except if object is notified on a
913  * @dev that passes @foreign_dev_check_cb, it is replicated towards all devices
914  * that pass @check_cb and are in the same bridge as @dev.
915  */
916 int switchdev_handle_port_obj_del_foreign(struct net_device *dev,
917                         struct switchdev_notifier_port_obj_info *port_obj_info,
918                         bool (*check_cb)(const struct net_device *dev),
919                         bool (*foreign_dev_check_cb)(const struct net_device *dev,
920                                                      const struct net_device *foreign_dev),
921                         int (*del_cb)(struct net_device *dev, const void *ctx,
922                                       const struct switchdev_obj *obj))
923 {
924         int err;
925
926         err = __switchdev_handle_port_obj_del(dev, port_obj_info, check_cb,
927                                               foreign_dev_check_cb, del_cb);
928         if (err == -EOPNOTSUPP)
929                 err = 0;
930         return err;
931 }
932 EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del_foreign);
933
934 static int __switchdev_handle_port_attr_set(struct net_device *dev,
935                         struct switchdev_notifier_port_attr_info *port_attr_info,
936                         bool (*check_cb)(const struct net_device *dev),
937                         int (*set_cb)(struct net_device *dev, const void *ctx,
938                                       const struct switchdev_attr *attr,
939                                       struct netlink_ext_ack *extack))
940 {
941         struct switchdev_notifier_info *info = &port_attr_info->info;
942         struct netlink_ext_ack *extack;
943         struct net_device *lower_dev;
944         struct list_head *iter;
945         int err = -EOPNOTSUPP;
946
947         extack = switchdev_notifier_info_to_extack(info);
948
949         if (check_cb(dev)) {
950                 err = set_cb(dev, info->ctx, port_attr_info->attr, extack);
951                 if (err != -EOPNOTSUPP)
952                         port_attr_info->handled = true;
953                 return err;
954         }
955
956         /* Switch ports might be stacked under e.g. a LAG. Ignore the
957          * unsupported devices, another driver might be able to handle them. But
958          * propagate to the callers any hard errors.
959          *
960          * If the driver does its own bookkeeping of stacked ports, it's not
961          * necessary to go through this helper.
962          */
963         netdev_for_each_lower_dev(dev, lower_dev, iter) {
964                 if (netif_is_bridge_master(lower_dev))
965                         continue;
966
967                 err = __switchdev_handle_port_attr_set(lower_dev, port_attr_info,
968                                                        check_cb, set_cb);
969                 if (err && err != -EOPNOTSUPP)
970                         return err;
971         }
972
973         return err;
974 }
975
976 int switchdev_handle_port_attr_set(struct net_device *dev,
977                         struct switchdev_notifier_port_attr_info *port_attr_info,
978                         bool (*check_cb)(const struct net_device *dev),
979                         int (*set_cb)(struct net_device *dev, const void *ctx,
980                                       const struct switchdev_attr *attr,
981                                       struct netlink_ext_ack *extack))
982 {
983         int err;
984
985         err = __switchdev_handle_port_attr_set(dev, port_attr_info, check_cb,
986                                                set_cb);
987         if (err == -EOPNOTSUPP)
988                 err = 0;
989         return err;
990 }
991 EXPORT_SYMBOL_GPL(switchdev_handle_port_attr_set);
992
993 int switchdev_bridge_port_offload(struct net_device *brport_dev,
994                                   struct net_device *dev, const void *ctx,
995                                   struct notifier_block *atomic_nb,
996                                   struct notifier_block *blocking_nb,
997                                   bool tx_fwd_offload,
998                                   struct netlink_ext_ack *extack)
999 {
1000         struct switchdev_notifier_brport_info brport_info = {
1001                 .brport = {
1002                         .dev = dev,
1003                         .ctx = ctx,
1004                         .atomic_nb = atomic_nb,
1005                         .blocking_nb = blocking_nb,
1006                         .tx_fwd_offload = tx_fwd_offload,
1007                 },
1008         };
1009         int err;
1010
1011         ASSERT_RTNL();
1012
1013         err = call_switchdev_blocking_notifiers(SWITCHDEV_BRPORT_OFFLOADED,
1014                                                 brport_dev, &brport_info.info,
1015                                                 extack);
1016         return notifier_to_errno(err);
1017 }
1018 EXPORT_SYMBOL_GPL(switchdev_bridge_port_offload);
1019
1020 void switchdev_bridge_port_unoffload(struct net_device *brport_dev,
1021                                      const void *ctx,
1022                                      struct notifier_block *atomic_nb,
1023                                      struct notifier_block *blocking_nb)
1024 {
1025         struct switchdev_notifier_brport_info brport_info = {
1026                 .brport = {
1027                         .ctx = ctx,
1028                         .atomic_nb = atomic_nb,
1029                         .blocking_nb = blocking_nb,
1030                 },
1031         };
1032
1033         ASSERT_RTNL();
1034
1035         call_switchdev_blocking_notifiers(SWITCHDEV_BRPORT_UNOFFLOADED,
1036                                           brport_dev, &brport_info.info,
1037                                           NULL);
1038 }
1039 EXPORT_SYMBOL_GPL(switchdev_bridge_port_unoffload);
1040
1041 int switchdev_bridge_port_replay(struct net_device *brport_dev,
1042                                  struct net_device *dev, const void *ctx,
1043                                  struct notifier_block *atomic_nb,
1044                                  struct notifier_block *blocking_nb,
1045                                  struct netlink_ext_ack *extack)
1046 {
1047         struct switchdev_notifier_brport_info brport_info = {
1048                 .brport = {
1049                         .dev = dev,
1050                         .ctx = ctx,
1051                         .atomic_nb = atomic_nb,
1052                         .blocking_nb = blocking_nb,
1053                 },
1054         };
1055         int err;
1056
1057         ASSERT_RTNL();
1058
1059         err = call_switchdev_blocking_notifiers(SWITCHDEV_BRPORT_REPLAY,
1060                                                 brport_dev, &brport_info.info,
1061                                                 extack);
1062         return notifier_to_errno(err);
1063 }
1064 EXPORT_SYMBOL_GPL(switchdev_bridge_port_replay);