arp: filter NOARP neighbours for SIOCGARP
[linux-2.6-block.git] / net / switchdev / switchdev.c
CommitLineData
007f790c
JP
1/*
2 * net/switchdev/switchdev.c - Switch device API
3 * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
f8f21471 4 * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
007f790c
JP
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/init.h>
03bf0c28
JP
15#include <linux/mutex.h>
16#include <linux/notifier.h>
007f790c 17#include <linux/netdevice.h>
47f8328b 18#include <linux/if_bridge.h>
5e8d9049 19#include <net/ip_fib.h>
007f790c
JP
20#include <net/switchdev.h>
21
3094333d
SF
22/**
23 * switchdev_port_attr_get - Get port attribute
24 *
25 * @dev: port device
26 * @attr: attribute to get
27 */
28int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
29{
30 const struct switchdev_ops *ops = dev->switchdev_ops;
31 struct net_device *lower_dev;
32 struct list_head *iter;
33 struct switchdev_attr first = {
34 .id = SWITCHDEV_ATTR_UNDEFINED
35 };
36 int err = -EOPNOTSUPP;
37
38 if (ops && ops->switchdev_port_attr_get)
39 return ops->switchdev_port_attr_get(dev, attr);
40
41 if (attr->flags & SWITCHDEV_F_NO_RECURSE)
42 return err;
43
44 /* Switch device port(s) may be stacked under
45 * bond/team/vlan dev, so recurse down to get attr on
46 * each port. Return -ENODATA if attr values don't
47 * compare across ports.
48 */
49
50 netdev_for_each_lower_dev(dev, lower_dev, iter) {
51 err = switchdev_port_attr_get(lower_dev, attr);
52 if (err)
53 break;
54 if (first.id == SWITCHDEV_ATTR_UNDEFINED)
55 first = *attr;
56 else if (memcmp(&first, attr, sizeof(*attr)))
57 return -ENODATA;
58 }
59
60 return err;
61}
62EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
63
64static int __switchdev_port_attr_set(struct net_device *dev,
65 struct switchdev_attr *attr)
66{
67 const struct switchdev_ops *ops = dev->switchdev_ops;
68 struct net_device *lower_dev;
69 struct list_head *iter;
70 int err = -EOPNOTSUPP;
71
72 if (ops && ops->switchdev_port_attr_set)
73 return ops->switchdev_port_attr_set(dev, attr);
74
75 if (attr->flags & SWITCHDEV_F_NO_RECURSE)
76 return err;
77
78 /* Switch device port(s) may be stacked under
79 * bond/team/vlan dev, so recurse down to set attr on
80 * each port.
81 */
82
83 netdev_for_each_lower_dev(dev, lower_dev, iter) {
84 err = __switchdev_port_attr_set(lower_dev, attr);
85 if (err)
86 break;
87 }
88
89 return err;
90}
91
92struct switchdev_attr_set_work {
93 struct work_struct work;
94 struct net_device *dev;
95 struct switchdev_attr attr;
96};
97
98static void switchdev_port_attr_set_work(struct work_struct *work)
99{
100 struct switchdev_attr_set_work *asw =
101 container_of(work, struct switchdev_attr_set_work, work);
102 int err;
103
104 rtnl_lock();
105 err = switchdev_port_attr_set(asw->dev, &asw->attr);
57225e77
SF
106 if (err && err != -EOPNOTSUPP)
107 netdev_err(asw->dev, "failed (err=%d) to set attribute (id=%d)\n",
108 err, asw->attr.id);
3094333d
SF
109 rtnl_unlock();
110
111 dev_put(asw->dev);
112 kfree(work);
113}
114
115static int switchdev_port_attr_set_defer(struct net_device *dev,
116 struct switchdev_attr *attr)
117{
118 struct switchdev_attr_set_work *asw;
119
120 asw = kmalloc(sizeof(*asw), GFP_ATOMIC);
121 if (!asw)
122 return -ENOMEM;
123
124 INIT_WORK(&asw->work, switchdev_port_attr_set_work);
125
126 dev_hold(dev);
127 asw->dev = dev;
128 memcpy(&asw->attr, attr, sizeof(asw->attr));
129
130 schedule_work(&asw->work);
131
132 return 0;
133}
134
135/**
136 * switchdev_port_attr_set - Set port attribute
137 *
138 * @dev: port device
139 * @attr: attribute to set
140 *
141 * Use a 2-phase prepare-commit transaction model to ensure
142 * system is not left in a partially updated state due to
143 * failure from driver/device.
144 */
145int switchdev_port_attr_set(struct net_device *dev, struct switchdev_attr *attr)
146{
147 int err;
148
149 if (!rtnl_is_locked()) {
150 /* Running prepare-commit transaction across stacked
151 * devices requires nothing moves, so if rtnl_lock is
152 * not held, schedule a worker thread to hold rtnl_lock
153 * while setting attr.
154 */
155
156 return switchdev_port_attr_set_defer(dev, attr);
157 }
158
159 /* Phase I: prepare for attr set. Driver/device should fail
160 * here if there are going to be issues in the commit phase,
161 * such as lack of resources or support. The driver/device
162 * should reserve resources needed for the commit phase here,
163 * but should not commit the attr.
164 */
165
166 attr->trans = SWITCHDEV_TRANS_PREPARE;
167 err = __switchdev_port_attr_set(dev, attr);
168 if (err) {
169 /* Prepare phase failed: abort the transaction. Any
170 * resources reserved in the prepare phase are
171 * released.
172 */
173
2ee94014
VD
174 if (err != -EOPNOTSUPP) {
175 attr->trans = SWITCHDEV_TRANS_ABORT;
176 __switchdev_port_attr_set(dev, attr);
177 }
3094333d
SF
178
179 return err;
180 }
181
182 /* Phase II: commit attr set. This cannot fail as a fault
183 * of driver/device. If it does, it's a bug in the driver/device
184 * because the driver said everythings was OK in phase I.
185 */
186
187 attr->trans = SWITCHDEV_TRANS_COMMIT;
188 err = __switchdev_port_attr_set(dev, attr);
e9fdaec0
SF
189 WARN(err, "%s: Commit of attribute (id=%d) failed.\n",
190 dev->name, attr->id);
3094333d
SF
191
192 return err;
193}
194EXPORT_SYMBOL_GPL(switchdev_port_attr_set);
195
22c1f67e
SF
196static int __switchdev_port_obj_add(struct net_device *dev,
197 struct switchdev_obj *obj)
491d0f15
SF
198{
199 const struct switchdev_ops *ops = dev->switchdev_ops;
200 struct net_device *lower_dev;
201 struct list_head *iter;
202 int err = -EOPNOTSUPP;
203
204 if (ops && ops->switchdev_port_obj_add)
205 return ops->switchdev_port_obj_add(dev, obj);
206
207 /* Switch device port(s) may be stacked under
208 * bond/team/vlan dev, so recurse down to add object on
209 * each port.
210 */
211
212 netdev_for_each_lower_dev(dev, lower_dev, iter) {
213 err = __switchdev_port_obj_add(lower_dev, obj);
214 if (err)
215 break;
216 }
217
218 return err;
219}
220
221/**
222 * switchdev_port_obj_add - Add port object
223 *
224 * @dev: port device
225 * @obj: object to add
226 *
227 * Use a 2-phase prepare-commit transaction model to ensure
228 * system is not left in a partially updated state due to
229 * failure from driver/device.
230 *
231 * rtnl_lock must be held.
232 */
233int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj)
234{
235 int err;
236
237 ASSERT_RTNL();
238
239 /* Phase I: prepare for obj add. Driver/device should fail
240 * here if there are going to be issues in the commit phase,
241 * such as lack of resources or support. The driver/device
242 * should reserve resources needed for the commit phase here,
243 * but should not commit the obj.
244 */
245
246 obj->trans = SWITCHDEV_TRANS_PREPARE;
247 err = __switchdev_port_obj_add(dev, obj);
248 if (err) {
249 /* Prepare phase failed: abort the transaction. Any
250 * resources reserved in the prepare phase are
251 * released.
252 */
253
2ee94014
VD
254 if (err != -EOPNOTSUPP) {
255 obj->trans = SWITCHDEV_TRANS_ABORT;
256 __switchdev_port_obj_add(dev, obj);
257 }
491d0f15
SF
258
259 return err;
260 }
261
262 /* Phase II: commit obj add. This cannot fail as a fault
263 * of driver/device. If it does, it's a bug in the driver/device
264 * because the driver said everythings was OK in phase I.
265 */
266
267 obj->trans = SWITCHDEV_TRANS_COMMIT;
268 err = __switchdev_port_obj_add(dev, obj);
269 WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
270
271 return err;
272}
273EXPORT_SYMBOL_GPL(switchdev_port_obj_add);
274
275/**
276 * switchdev_port_obj_del - Delete port object
277 *
278 * @dev: port device
279 * @obj: object to delete
280 */
281int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj)
282{
283 const struct switchdev_ops *ops = dev->switchdev_ops;
284 struct net_device *lower_dev;
285 struct list_head *iter;
286 int err = -EOPNOTSUPP;
287
288 if (ops && ops->switchdev_port_obj_del)
289 return ops->switchdev_port_obj_del(dev, obj);
290
291 /* Switch device port(s) may be stacked under
292 * bond/team/vlan dev, so recurse down to delete object on
293 * each port.
294 */
295
296 netdev_for_each_lower_dev(dev, lower_dev, iter) {
297 err = switchdev_port_obj_del(lower_dev, obj);
298 if (err)
299 break;
300 }
301
302 return err;
303}
304EXPORT_SYMBOL_GPL(switchdev_port_obj_del);
305
45d4122c
SS
306/**
307 * switchdev_port_obj_dump - Dump port objects
308 *
309 * @dev: port device
310 * @obj: object to dump
311 */
312int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj)
313{
314 const struct switchdev_ops *ops = dev->switchdev_ops;
315 struct net_device *lower_dev;
316 struct list_head *iter;
317 int err = -EOPNOTSUPP;
318
319 if (ops && ops->switchdev_port_obj_dump)
320 return ops->switchdev_port_obj_dump(dev, obj);
321
322 /* Switch device port(s) may be stacked under
323 * bond/team/vlan dev, so recurse down to dump objects on
324 * first port at bottom of stack.
325 */
326
327 netdev_for_each_lower_dev(dev, lower_dev, iter) {
328 err = switchdev_port_obj_dump(lower_dev, obj);
329 break;
330 }
331
332 return err;
333}
334EXPORT_SYMBOL_GPL(switchdev_port_obj_dump);
335
ebb9a03a
JP
336static DEFINE_MUTEX(switchdev_mutex);
337static RAW_NOTIFIER_HEAD(switchdev_notif_chain);
03bf0c28
JP
338
339/**
ebb9a03a 340 * register_switchdev_notifier - Register notifier
03bf0c28
JP
341 * @nb: notifier_block
342 *
343 * Register switch device notifier. This should be used by code
344 * which needs to monitor events happening in particular device.
345 * Return values are same as for atomic_notifier_chain_register().
346 */
ebb9a03a 347int register_switchdev_notifier(struct notifier_block *nb)
03bf0c28
JP
348{
349 int err;
350
ebb9a03a
JP
351 mutex_lock(&switchdev_mutex);
352 err = raw_notifier_chain_register(&switchdev_notif_chain, nb);
353 mutex_unlock(&switchdev_mutex);
03bf0c28
JP
354 return err;
355}
ebb9a03a 356EXPORT_SYMBOL_GPL(register_switchdev_notifier);
03bf0c28
JP
357
358/**
ebb9a03a 359 * unregister_switchdev_notifier - Unregister notifier
03bf0c28
JP
360 * @nb: notifier_block
361 *
362 * Unregister switch device notifier.
363 * Return values are same as for atomic_notifier_chain_unregister().
364 */
ebb9a03a 365int unregister_switchdev_notifier(struct notifier_block *nb)
03bf0c28
JP
366{
367 int err;
368
ebb9a03a
JP
369 mutex_lock(&switchdev_mutex);
370 err = raw_notifier_chain_unregister(&switchdev_notif_chain, nb);
371 mutex_unlock(&switchdev_mutex);
03bf0c28
JP
372 return err;
373}
ebb9a03a 374EXPORT_SYMBOL_GPL(unregister_switchdev_notifier);
03bf0c28
JP
375
376/**
ebb9a03a 377 * call_switchdev_notifiers - Call notifiers
03bf0c28
JP
378 * @val: value passed unmodified to notifier function
379 * @dev: port device
380 * @info: notifier information data
381 *
382 * Call all network notifier blocks. This should be called by driver
383 * when it needs to propagate hardware event.
384 * Return values are same as for atomic_notifier_call_chain().
385 */
ebb9a03a
JP
386int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
387 struct switchdev_notifier_info *info)
03bf0c28
JP
388{
389 int err;
390
391 info->dev = dev;
ebb9a03a
JP
392 mutex_lock(&switchdev_mutex);
393 err = raw_notifier_call_chain(&switchdev_notif_chain, val, info);
394 mutex_unlock(&switchdev_mutex);
03bf0c28
JP
395 return err;
396}
ebb9a03a 397EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
8a44dbb2 398
7d4f8d87
SF
399struct switchdev_vlan_dump {
400 struct switchdev_obj obj;
401 struct sk_buff *skb;
402 u32 filter_mask;
403 u16 flags;
404 u16 begin;
405 u16 end;
406};
407
408static int switchdev_port_vlan_dump_put(struct net_device *dev,
409 struct switchdev_vlan_dump *dump)
410{
411 struct bridge_vlan_info vinfo;
412
413 vinfo.flags = dump->flags;
414
415 if (dump->begin == 0 && dump->end == 0) {
416 return 0;
417 } else if (dump->begin == dump->end) {
418 vinfo.vid = dump->begin;
419 if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
420 sizeof(vinfo), &vinfo))
421 return -EMSGSIZE;
422 } else {
423 vinfo.vid = dump->begin;
424 vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN;
425 if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
426 sizeof(vinfo), &vinfo))
427 return -EMSGSIZE;
428 vinfo.vid = dump->end;
429 vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
430 vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
431 if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
432 sizeof(vinfo), &vinfo))
433 return -EMSGSIZE;
434 }
435
436 return 0;
437}
438
439static int switchdev_port_vlan_dump_cb(struct net_device *dev,
440 struct switchdev_obj *obj)
441{
442 struct switchdev_vlan_dump *dump =
443 container_of(obj, struct switchdev_vlan_dump, obj);
444 struct switchdev_obj_vlan *vlan = &dump->obj.u.vlan;
445 int err = 0;
446
447 if (vlan->vid_begin > vlan->vid_end)
448 return -EINVAL;
449
450 if (dump->filter_mask & RTEXT_FILTER_BRVLAN) {
451 dump->flags = vlan->flags;
452 for (dump->begin = dump->end = vlan->vid_begin;
453 dump->begin <= vlan->vid_end;
454 dump->begin++, dump->end++) {
455 err = switchdev_port_vlan_dump_put(dev, dump);
456 if (err)
457 return err;
458 }
459 } else if (dump->filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) {
460 if (dump->begin > vlan->vid_begin &&
461 dump->begin >= vlan->vid_end) {
462 if ((dump->begin - 1) == vlan->vid_end &&
463 dump->flags == vlan->flags) {
464 /* prepend */
465 dump->begin = vlan->vid_begin;
466 } else {
467 err = switchdev_port_vlan_dump_put(dev, dump);
468 dump->flags = vlan->flags;
469 dump->begin = vlan->vid_begin;
470 dump->end = vlan->vid_end;
471 }
472 } else if (dump->end <= vlan->vid_begin &&
473 dump->end < vlan->vid_end) {
474 if ((dump->end + 1) == vlan->vid_begin &&
475 dump->flags == vlan->flags) {
476 /* append */
477 dump->end = vlan->vid_end;
478 } else {
479 err = switchdev_port_vlan_dump_put(dev, dump);
480 dump->flags = vlan->flags;
481 dump->begin = vlan->vid_begin;
482 dump->end = vlan->vid_end;
483 }
484 } else {
485 err = -EINVAL;
486 }
487 }
488
489 return err;
490}
491
492static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev,
493 u32 filter_mask)
494{
495 struct switchdev_vlan_dump dump = {
496 .obj = {
497 .id = SWITCHDEV_OBJ_PORT_VLAN,
498 .cb = switchdev_port_vlan_dump_cb,
499 },
500 .skb = skb,
501 .filter_mask = filter_mask,
502 };
503 int err = 0;
504
505 if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
506 (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
507 err = switchdev_port_obj_dump(dev, &dump.obj);
508 if (err)
509 goto err_out;
510 if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
511 /* last one */
512 err = switchdev_port_vlan_dump_put(dev, &dump);
513 }
514
515err_out:
516 return err == -EOPNOTSUPP ? 0 : err;
517}
518
8793d0a6
SF
519/**
520 * switchdev_port_bridge_getlink - Get bridge port attributes
521 *
522 * @dev: port device
523 *
524 * Called for SELF on rtnl_bridge_getlink to get bridge port
525 * attributes.
526 */
527int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
528 struct net_device *dev, u32 filter_mask,
529 int nlflags)
530{
531 struct switchdev_attr attr = {
532 .id = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS,
533 };
534 u16 mode = BRIDGE_MODE_UNDEF;
535 u32 mask = BR_LEARNING | BR_LEARNING_SYNC;
536 int err;
537
538 err = switchdev_port_attr_get(dev, &attr);
5c8079d0 539 if (err && err != -EOPNOTSUPP)
8793d0a6
SF
540 return err;
541
542 return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode,
7d4f8d87
SF
543 attr.u.brport_flags, mask, nlflags,
544 filter_mask, switchdev_port_vlan_fill);
8793d0a6
SF
545}
546EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink);
547
47f8328b
SF
548static int switchdev_port_br_setflag(struct net_device *dev,
549 struct nlattr *nlattr,
550 unsigned long brport_flag)
551{
552 struct switchdev_attr attr = {
553 .id = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS,
554 };
555 u8 flag = nla_get_u8(nlattr);
556 int err;
557
558 err = switchdev_port_attr_get(dev, &attr);
559 if (err)
560 return err;
561
562 if (flag)
42275bd8 563 attr.u.brport_flags |= brport_flag;
47f8328b 564 else
42275bd8 565 attr.u.brport_flags &= ~brport_flag;
47f8328b
SF
566
567 return switchdev_port_attr_set(dev, &attr);
568}
569
570static const struct nla_policy
571switchdev_port_bridge_policy[IFLA_BRPORT_MAX + 1] = {
572 [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
573 [IFLA_BRPORT_COST] = { .type = NLA_U32 },
574 [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
575 [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
576 [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
577 [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
578 [IFLA_BRPORT_FAST_LEAVE] = { .type = NLA_U8 },
579 [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
580 [IFLA_BRPORT_LEARNING_SYNC] = { .type = NLA_U8 },
581 [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
582};
583
584static int switchdev_port_br_setlink_protinfo(struct net_device *dev,
585 struct nlattr *protinfo)
586{
587 struct nlattr *attr;
588 int rem;
589 int err;
590
591 err = nla_validate_nested(protinfo, IFLA_BRPORT_MAX,
592 switchdev_port_bridge_policy);
593 if (err)
594 return err;
595
596 nla_for_each_nested(attr, protinfo, rem) {
597 switch (nla_type(attr)) {
598 case IFLA_BRPORT_LEARNING:
599 err = switchdev_port_br_setflag(dev, attr,
600 BR_LEARNING);
601 break;
602 case IFLA_BRPORT_LEARNING_SYNC:
603 err = switchdev_port_br_setflag(dev, attr,
604 BR_LEARNING_SYNC);
605 break;
606 default:
607 err = -EOPNOTSUPP;
608 break;
609 }
610 if (err)
611 return err;
612 }
613
614 return 0;
615}
616
617static int switchdev_port_br_afspec(struct net_device *dev,
618 struct nlattr *afspec,
619 int (*f)(struct net_device *dev,
620 struct switchdev_obj *obj))
621{
622 struct nlattr *attr;
623 struct bridge_vlan_info *vinfo;
624 struct switchdev_obj obj = {
625 .id = SWITCHDEV_OBJ_PORT_VLAN,
626 };
42275bd8 627 struct switchdev_obj_vlan *vlan = &obj.u.vlan;
47f8328b
SF
628 int rem;
629 int err;
630
631 nla_for_each_nested(attr, afspec, rem) {
632 if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO)
633 continue;
634 if (nla_len(attr) != sizeof(struct bridge_vlan_info))
635 return -EINVAL;
636 vinfo = nla_data(attr);
42275bd8 637 vlan->flags = vinfo->flags;
47f8328b 638 if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
3e3a78b4 639 if (vlan->vid_begin)
47f8328b 640 return -EINVAL;
3e3a78b4 641 vlan->vid_begin = vinfo->vid;
47f8328b 642 } else if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) {
3e3a78b4 643 if (!vlan->vid_begin)
47f8328b 644 return -EINVAL;
42275bd8 645 vlan->vid_end = vinfo->vid;
3e3a78b4 646 if (vlan->vid_end <= vlan->vid_begin)
47f8328b
SF
647 return -EINVAL;
648 err = f(dev, &obj);
649 if (err)
650 return err;
42275bd8 651 memset(vlan, 0, sizeof(*vlan));
47f8328b 652 } else {
3e3a78b4 653 if (vlan->vid_begin)
47f8328b 654 return -EINVAL;
3e3a78b4 655 vlan->vid_begin = vinfo->vid;
42275bd8 656 vlan->vid_end = vinfo->vid;
47f8328b
SF
657 err = f(dev, &obj);
658 if (err)
659 return err;
42275bd8 660 memset(vlan, 0, sizeof(*vlan));
47f8328b
SF
661 }
662 }
663
664 return 0;
665}
666
8a44dbb2 667/**
47f8328b 668 * switchdev_port_bridge_setlink - Set bridge port attributes
8a44dbb2
RP
669 *
670 * @dev: port device
47f8328b
SF
671 * @nlh: netlink header
672 * @flags: netlink flags
8a44dbb2 673 *
47f8328b
SF
674 * Called for SELF on rtnl_bridge_setlink to set bridge port
675 * attributes.
8a44dbb2 676 */
ebb9a03a
JP
677int switchdev_port_bridge_setlink(struct net_device *dev,
678 struct nlmsghdr *nlh, u16 flags)
8a44dbb2 679{
47f8328b
SF
680 struct nlattr *protinfo;
681 struct nlattr *afspec;
682 int err = 0;
683
684 protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
685 IFLA_PROTINFO);
686 if (protinfo) {
687 err = switchdev_port_br_setlink_protinfo(dev, protinfo);
688 if (err)
689 return err;
690 }
8a44dbb2 691
47f8328b
SF
692 afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
693 IFLA_AF_SPEC);
694 if (afspec)
695 err = switchdev_port_br_afspec(dev, afspec,
696 switchdev_port_obj_add);
8a44dbb2 697
47f8328b 698 return err;
8a44dbb2 699}
ebb9a03a 700EXPORT_SYMBOL_GPL(switchdev_port_bridge_setlink);
8a44dbb2
RP
701
702/**
5c34e022 703 * switchdev_port_bridge_dellink - Set bridge port attributes
8a44dbb2
RP
704 *
705 * @dev: port device
5c34e022
SF
706 * @nlh: netlink header
707 * @flags: netlink flags
8a44dbb2 708 *
5c34e022
SF
709 * Called for SELF on rtnl_bridge_dellink to set bridge port
710 * attributes.
8a44dbb2 711 */
ebb9a03a
JP
712int switchdev_port_bridge_dellink(struct net_device *dev,
713 struct nlmsghdr *nlh, u16 flags)
8a44dbb2 714{
5c34e022 715 struct nlattr *afspec;
8a44dbb2 716
5c34e022
SF
717 afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
718 IFLA_AF_SPEC);
719 if (afspec)
720 return switchdev_port_br_afspec(dev, afspec,
721 switchdev_port_obj_del);
8a44dbb2 722
5c34e022 723 return 0;
8a44dbb2 724}
ebb9a03a 725EXPORT_SYMBOL_GPL(switchdev_port_bridge_dellink);
8a44dbb2 726
45d4122c
SS
727/**
728 * switchdev_port_fdb_add - Add FDB (MAC/VLAN) entry to port
729 *
730 * @ndmsg: netlink hdr
731 * @nlattr: netlink attributes
732 * @dev: port device
733 * @addr: MAC address to add
734 * @vid: VLAN to add
735 *
736 * Add FDB entry to switch device.
737 */
738int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
739 struct net_device *dev, const unsigned char *addr,
740 u16 vid, u16 nlm_flags)
741{
742 struct switchdev_obj obj = {
743 .id = SWITCHDEV_OBJ_PORT_FDB,
744 .u.fdb = {
745 .addr = addr,
746 .vid = vid,
747 },
748 };
749
750 return switchdev_port_obj_add(dev, &obj);
751}
752EXPORT_SYMBOL_GPL(switchdev_port_fdb_add);
753
754/**
755 * switchdev_port_fdb_del - Delete FDB (MAC/VLAN) entry from port
756 *
757 * @ndmsg: netlink hdr
758 * @nlattr: netlink attributes
759 * @dev: port device
760 * @addr: MAC address to delete
761 * @vid: VLAN to delete
762 *
763 * Delete FDB entry from switch device.
764 */
765int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
766 struct net_device *dev, const unsigned char *addr,
767 u16 vid)
768{
769 struct switchdev_obj obj = {
770 .id = SWITCHDEV_OBJ_PORT_FDB,
771 .u.fdb = {
772 .addr = addr,
773 .vid = vid,
774 },
775 };
776
777 return switchdev_port_obj_del(dev, &obj);
778}
779EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
780
781struct switchdev_fdb_dump {
782 struct switchdev_obj obj;
783 struct sk_buff *skb;
784 struct netlink_callback *cb;
45d4122c
SS
785 int idx;
786};
787
788static int switchdev_port_fdb_dump_cb(struct net_device *dev,
789 struct switchdev_obj *obj)
790{
791 struct switchdev_fdb_dump *dump =
792 container_of(obj, struct switchdev_fdb_dump, obj);
793 u32 portid = NETLINK_CB(dump->cb->skb).portid;
794 u32 seq = dump->cb->nlh->nlmsg_seq;
795 struct nlmsghdr *nlh;
796 struct ndmsg *ndm;
45d4122c
SS
797
798 if (dump->idx < dump->cb->args[0])
799 goto skip;
800
45d4122c
SS
801 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
802 sizeof(*ndm), NLM_F_MULTI);
803 if (!nlh)
804 return -EMSGSIZE;
805
806 ndm = nlmsg_data(nlh);
807 ndm->ndm_family = AF_BRIDGE;
808 ndm->ndm_pad1 = 0;
809 ndm->ndm_pad2 = 0;
810 ndm->ndm_flags = NTF_SELF;
811 ndm->ndm_type = 0;
812 ndm->ndm_ifindex = dev->ifindex;
813 ndm->ndm_state = NUD_REACHABLE;
814
815 if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr))
816 goto nla_put_failure;
817
818 if (obj->u.fdb.vid && nla_put_u16(dump->skb, NDA_VLAN, obj->u.fdb.vid))
819 goto nla_put_failure;
820
821 nlmsg_end(dump->skb, nlh);
822
823skip:
824 dump->idx++;
825 return 0;
826
827nla_put_failure:
828 nlmsg_cancel(dump->skb, nlh);
829 return -EMSGSIZE;
830}
831
832/**
833 * switchdev_port_fdb_dump - Dump port FDB (MAC/VLAN) entries
834 *
835 * @skb: netlink skb
836 * @cb: netlink callback
837 * @dev: port device
838 * @filter_dev: filter device
839 * @idx:
840 *
841 * Delete FDB entry from switch device.
842 */
843int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
844 struct net_device *dev,
845 struct net_device *filter_dev, int idx)
846{
847 struct switchdev_fdb_dump dump = {
848 .obj = {
849 .id = SWITCHDEV_OBJ_PORT_FDB,
850 .cb = switchdev_port_fdb_dump_cb,
851 },
852 .skb = skb,
853 .cb = cb,
45d4122c
SS
854 .idx = idx,
855 };
856 int err;
857
858 err = switchdev_port_obj_dump(dev, &dump.obj);
859 if (err)
860 return err;
861
862 return dump.idx;
863}
864EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump);
865
ebb9a03a 866static struct net_device *switchdev_get_lowest_dev(struct net_device *dev)
b5d6fbde 867{
9d47c0a2 868 const struct switchdev_ops *ops = dev->switchdev_ops;
b5d6fbde
SF
869 struct net_device *lower_dev;
870 struct net_device *port_dev;
871 struct list_head *iter;
872
873 /* Recusively search down until we find a sw port dev.
f8e20a9f 874 * (A sw port dev supports switchdev_port_attr_get).
b5d6fbde
SF
875 */
876
f8e20a9f 877 if (ops && ops->switchdev_port_attr_get)
b5d6fbde
SF
878 return dev;
879
880 netdev_for_each_lower_dev(dev, lower_dev, iter) {
ebb9a03a 881 port_dev = switchdev_get_lowest_dev(lower_dev);
b5d6fbde
SF
882 if (port_dev)
883 return port_dev;
884 }
885
886 return NULL;
887}
888
ebb9a03a 889static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
b5d6fbde 890{
f8e20a9f
SF
891 struct switchdev_attr attr = {
892 .id = SWITCHDEV_ATTR_PORT_PARENT_ID,
893 };
894 struct switchdev_attr prev_attr;
b5d6fbde
SF
895 struct net_device *dev = NULL;
896 int nhsel;
897
898 /* For this route, all nexthop devs must be on the same switch. */
899
900 for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
901 const struct fib_nh *nh = &fi->fib_nh[nhsel];
902
903 if (!nh->nh_dev)
904 return NULL;
905
ebb9a03a 906 dev = switchdev_get_lowest_dev(nh->nh_dev);
b5d6fbde
SF
907 if (!dev)
908 return NULL;
909
f8e20a9f 910 if (switchdev_port_attr_get(dev, &attr))
b5d6fbde
SF
911 return NULL;
912
913 if (nhsel > 0) {
42275bd8 914 if (prev_attr.u.ppid.id_len != attr.u.ppid.id_len)
b5d6fbde 915 return NULL;
42275bd8
SF
916 if (memcmp(prev_attr.u.ppid.id, attr.u.ppid.id,
917 attr.u.ppid.id_len))
b5d6fbde
SF
918 return NULL;
919 }
920
f8e20a9f 921 prev_attr = attr;
b5d6fbde
SF
922 }
923
924 return dev;
925}
926
5e8d9049 927/**
7616dcbb 928 * switchdev_fib_ipv4_add - Add/modify switch IPv4 route entry
5e8d9049
SF
929 *
930 * @dst: route's IPv4 destination address
931 * @dst_len: destination address length (prefix length)
932 * @fi: route FIB info structure
933 * @tos: route TOS
934 * @type: route type
f8f21471 935 * @nlflags: netlink flags passed in (NLM_F_*)
5e8d9049
SF
936 * @tb_id: route table ID
937 *
7616dcbb 938 * Add/modify switch IPv4 route entry.
5e8d9049 939 */
ebb9a03a
JP
940int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
941 u8 tos, u8 type, u32 nlflags, u32 tb_id)
5e8d9049 942{
58c2cb16
SF
943 struct switchdev_obj fib_obj = {
944 .id = SWITCHDEV_OBJ_IPV4_FIB,
42275bd8 945 .u.ipv4_fib = {
7a7ee531 946 .dst = dst,
58c2cb16
SF
947 .dst_len = dst_len,
948 .fi = fi,
949 .tos = tos,
950 .type = type,
951 .nlflags = nlflags,
952 .tb_id = tb_id,
953 },
954 };
b5d6fbde 955 struct net_device *dev;
b5d6fbde
SF
956 int err = 0;
957
8e05fd71
SF
958 /* Don't offload route if using custom ip rules or if
959 * IPv4 FIB offloading has been disabled completely.
960 */
961
e1315db1
SF
962#ifdef CONFIG_IP_MULTIPLE_TABLES
963 if (fi->fib_net->ipv4.fib_has_custom_rules)
964 return 0;
965#endif
966
967 if (fi->fib_net->ipv4.fib_offload_disabled)
104616e7
SF
968 return 0;
969
ebb9a03a 970 dev = switchdev_get_dev_by_nhs(fi);
b5d6fbde
SF
971 if (!dev)
972 return 0;
58c2cb16
SF
973
974 err = switchdev_port_obj_add(dev, &fib_obj);
975 if (!err)
36583eb5 976 fi->fib_flags |= RTNH_F_OFFLOAD;
b5d6fbde 977
af201f72 978 return err == -EOPNOTSUPP ? 0 : err;
5e8d9049 979}
ebb9a03a 980EXPORT_SYMBOL_GPL(switchdev_fib_ipv4_add);
5e8d9049
SF
981
982/**
ebb9a03a 983 * switchdev_fib_ipv4_del - Delete IPv4 route entry from switch
5e8d9049
SF
984 *
985 * @dst: route's IPv4 destination address
986 * @dst_len: destination address length (prefix length)
987 * @fi: route FIB info structure
988 * @tos: route TOS
989 * @type: route type
990 * @tb_id: route table ID
991 *
992 * Delete IPv4 route entry from switch device.
993 */
ebb9a03a
JP
994int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
995 u8 tos, u8 type, u32 tb_id)
5e8d9049 996{
58c2cb16
SF
997 struct switchdev_obj fib_obj = {
998 .id = SWITCHDEV_OBJ_IPV4_FIB,
42275bd8 999 .u.ipv4_fib = {
7a7ee531 1000 .dst = dst,
58c2cb16
SF
1001 .dst_len = dst_len,
1002 .fi = fi,
1003 .tos = tos,
1004 .type = type,
1005 .nlflags = 0,
1006 .tb_id = tb_id,
1007 },
1008 };
b5d6fbde 1009 struct net_device *dev;
b5d6fbde
SF
1010 int err = 0;
1011
eea39946 1012 if (!(fi->fib_flags & RTNH_F_OFFLOAD))
b5d6fbde
SF
1013 return 0;
1014
ebb9a03a 1015 dev = switchdev_get_dev_by_nhs(fi);
b5d6fbde
SF
1016 if (!dev)
1017 return 0;
b5d6fbde 1018
58c2cb16
SF
1019 err = switchdev_port_obj_del(dev, &fib_obj);
1020 if (!err)
36583eb5 1021 fi->fib_flags &= ~RTNH_F_OFFLOAD;
b5d6fbde 1022
af201f72 1023 return err == -EOPNOTSUPP ? 0 : err;
5e8d9049 1024}
ebb9a03a 1025EXPORT_SYMBOL_GPL(switchdev_fib_ipv4_del);
8e05fd71
SF
1026
1027/**
ebb9a03a 1028 * switchdev_fib_ipv4_abort - Abort an IPv4 FIB operation
8e05fd71
SF
1029 *
1030 * @fi: route FIB info structure
1031 */
ebb9a03a 1032void switchdev_fib_ipv4_abort(struct fib_info *fi)
8e05fd71
SF
1033{
1034 /* There was a problem installing this route to the offload
1035 * device. For now, until we come up with more refined
1036 * policy handling, abruptly end IPv4 fib offloading for
1037 * for entire net by flushing offload device(s) of all
1038 * IPv4 routes, and mark IPv4 fib offloading broken from
1039 * this point forward.
1040 */
1041
1042 fib_flush_external(fi->fib_net);
1043 fi->fib_net->ipv4.fib_offload_disabled = true;
1044}
ebb9a03a 1045EXPORT_SYMBOL_GPL(switchdev_fib_ipv4_abort);