Merge ~bodong-wang/ubuntu/+source/linux-bluefield:nvidia-devlink into ~canonical-kernel/ubuntu/+source/linux-bluefield/+git/focal:master-next

Proposed by Bodong Wang
Status: Superseded
Proposed branch: ~bodong-wang/ubuntu/+source/linux-bluefield:nvidia-devlink
Merge into: ~canonical-kernel/ubuntu/+source/linux-bluefield/+git/focal:master-next
Diff against target: 10740 lines (+6115/-1162)
35 files modified
Documentation/networking/devlink/devlink-trap.rst (+595/-0)
Documentation/networking/devlink/index.rst (+14/-0)
Documentation/networking/index.rst (+2/-3)
MAINTAINERS (+1/-0)
debian.bluefield/config/config.common.ubuntu (+8/-23)
dev/null (+0/-33)
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c (+15/-17)
drivers/net/ethernet/mellanox/mlx4/crdump.c (+27/-9)
drivers/net/ethernet/mellanox/mlx4/main.c (+11/-2)
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c (+5/-3)
drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c (+5/-3)
drivers/net/ethernet/mellanox/mlx5/core/health.c (+10/-6)
drivers/net/ethernet/mellanox/mlxsw/core.c (+18/-4)
drivers/net/ethernet/mellanox/mlxsw/core.h (+5/-0)
drivers/net/ethernet/mellanox/mlxsw/spectrum.h (+1/-1)
drivers/net/ethernet/netronome/nfp/nfp_devlink.c (+10/-4)
drivers/net/ethernet/pensando/ionic/ionic_devlink.c (+3/-2)
drivers/net/netdevsim/dev.c (+24/-9)
include/net/devlink.h (+871/-57)
include/net/genetlink.h (+23/-7)
include/net/netlink.h (+47/-28)
include/net/pkt_cls.h (+1/-0)
include/net/red.h (+38/-0)
include/trace/events/devlink.h (+37/-0)
include/uapi/linux/devlink.h (+152/-0)
include/uapi/linux/pkt_sched.h (+17/-0)
lib/nlattr.c (+10/-10)
net/Kconfig (+0/-1)
net/core/devlink.c (+3855/-777)
net/core/drop_monitor.c (+46/-16)
net/dsa/dsa2.c (+11/-6)
net/netlink/genetlink.c (+183/-121)
net/sched/act_api.c (+7/-12)
net/sched/sch_red.c (+60/-8)
tools/testing/selftests/drivers/net/netdevsim/devlink.sh (+3/-0)
Reviewer Review Type Date Requested Status
Canonical Kernel Pending
Review via email: mp+416171@code.launchpad.net

This proposal has been superseded by a proposal from 2022-03-01.

Commit message

Managing TX rate of VFs becomes non-trivial task when a big number of VFs are
used. This issue can be handled with some grouping mechanism.

Currently driver provide two ways to limit TX rate of the VF: TC police action
and NDO API callback. Implementation of grouping within this two infrastructures
problematic, due to the following:

NDO API rate limiting is legacy feature, even though it's available in switchdev
mode, and extending it with new abstraction is not good anyway;

TC police action is flow based and requires net device with Qdisc on it and
implementing this will bring unwanted complications.

According to aforesaid devlink is the most appropriate place.

In order to cherry pick the devlink patch for VF group rate limit, devlink API
patches before are needed to maintain a clear history.

To post a comment you must log in.

Unmerged commits

e1f2032... by Moshe Shemesh <email address hidden>

devlink: Fix reload stats structure

BugLink: https://bugs.launchpad.net/bugs/1962490

Fix reload stats structure exposed to the user. Change stats structure
hierarchy to have the reload action as a parent of the stat entry and
then stat entry includes value per limit. This will also help to avoid
string concatenation on iproute2 output.

Reload stats structure before this fix:
"stats": {
    "reload": {
        "driver_reinit": 2,
        "fw_activate": 1,
        "fw_activate_no_reset": 0
     }
}

After this fix:
"stats": {
    "reload": {
        "driver_reinit": {
            "unspecified": 2
        },
        "fw_activate": {
            "unspecified": 1,
            "no_reset": 0
        }
}

Fixes: a254c264267e ("devlink: Add reload stats")
Signed-off-by: Moshe Shemesh <email address hidden>
Reviewed-by: Jiri Pirko <email address hidden>
Link: https://<email address hidden>
Signed-off-by: Jakub Kicinski <email address hidden>
(cherry picked from commit 5204bb683c1633e550c2124ccc2358dd645a80db)
Signed-off-by: Bodong Wang <email address hidden>

c8269a0... by Vladyslav Tarasiuk <email address hidden>

devlink: Rework devlink health reporter destructor

BugLink: https://bugs.launchpad.net/bugs/1962490

Devlink keeps its own reference to every reporter in a list and inits
refcount to 1 upon reporter's creation. Existing destructor waits to
free the memory indefinitely using msleep() until all references except
devlink's own are put.

Rework this mechanism by moving memory free routine to a separate
function, which is called when the last reporter reference is put.

Besides, it allows to call __devlink_health_reporter_destroy() while
locked on a reporters list mutex in symmetry to
__devlink_health_reporter_create(), which is required in follow-up
patch.

Signed-off-by: Vladyslav Tarasiuk <email address hidden>
Reviewed-by: Moshe Shemesh <email address hidden>
Reviewed-by: Jiri Pirko <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(cherry picked from commit 3c5584bf0a0493e8d232ade65f4b9c5e995f3a0c)
Signed-off-by: Bodong Wang <email address hidden>

7c1c03e... by Ido Schimmel <email address hidden>

drop_monitor: Convert to using devlink tracepoint

BugLink: https://bugs.launchpad.net/bugs/1962490

Convert drop monitor to use the recently introduced
'devlink_trap_report' tracepoint instead of having devlink call into
drop monitor.

This is both consistent with software originated drops ('kfree_skb'
tracepoint) and also allows drop monitor to be built as a module and
still report hardware originated drops.

Signed-off-by: Ido Schimmel <email address hidden>
Reviewed-by: Jiri Pirko <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(backported from commit 8ee2267ad33e0ba021e9dd9b437f773906cd99d6)
Signed-off-by: Bodong Wang <email address hidden>
[bodong: ignore doc and drop monitor]

Conflicts:
 MAINTAINERS
 include/net/drop_monitor.h

86e7116... by Ido Schimmel <email address hidden>

devlink: Add 'control' trap type

BugLink: https://bugs.launchpad.net/bugs/1962490

This type is used for traps that trap control packets such as ARP
request and IGMP query to the CPU.

Do not report such packets to the kernel's drop monitor as they were not
dropped by the device no encountered an exception during forwarding.

Signed-off-by: Ido Schimmel <email address hidden>
Reviewed-by: Jiri Pirko <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(cherry picked from commit 30a4e9a29ab9aadfe6c5386ae4aa396b1d2556c2)
Signed-off-by: Bodong Wang <email address hidden>

2cf5515... by Leon Romanovsky <email address hidden>

devlink: Remove check of always valid devlink pointer

BugLink: https://bugs.launchpad.net/bugs/1962490

Devlink objects are accessible only after they were registered and
have valid devlink_*->devlink pointers.

Remove that check and simplify respective fill functions as an outcome
of such change.

Signed-off-by: Leon Romanovsky <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(backported from commit 7ca973dc9fe589dc0ab2650641f4c7a19cc49ecd)
Signed-off-by: Bodong Wang <email address hidden>
[bodong: fix conflict due to api change]

Conflicts:
 net/core/devlink.c

777e34d... by Jakub Kicinski <email address hidden>

devlink: factor out building a snapshot notification

BugLink: https://bugs.launchpad.net/bugs/1962490

We'll need to send snapshot info back on the socket
which requested a snapshot to be created. Factor out
constructing a snapshot description from the broadcast
notification code.

v3: new patch

Signed-off-by: Jakub Kicinski <email address hidden>
Reviewed-by: Jiri Pirko <email address hidden>
Reviewed-by: Jacob Keller <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(cherry picked from commit dd86fec7e06ab792fe470c66a67ff42bf5d72b91)
Signed-off-by: Bodong Wang <email address hidden>

24d0d78... by Leon Romanovsky <email address hidden>

devlink: Allocate devlink directly in requested net namespace

BugLink: https://bugs.launchpad.net/bugs/1962490

There is no need in extra call indirection and check from impossible
flow where someone tries to set namespace without prior call
to devlink_alloc().

Instead of this extra logic and additional EXPORT_SYMBOL, use specialized
devlink allocation function that receives net namespace as an argument.

Such specialized API allows clear view when devlink initialized in wrong
net namespace and/or kernel users don't try to change devlink namespace
under the hood.

Reviewed-by: Jiri Pirko <email address hidden>
Signed-off-by: Leon Romanovsky <email address hidden>
Signed-off-by: Jakub Kicinski <email address hidden>
(backported from commit 26713455048eb19122b1561b471d30710177ef97)
Signed-off-by: Bodong Wang <email address hidden>
[bodong: ignore netdevsim]

Conflicts:
 drivers/net/netdevsim/dev.c

19bb413... by Leon Romanovsky <email address hidden>

devlink: Break parameter notification sequence to be before/after unload/load driver

BugLink: https://bugs.launchpad.net/bugs/1962490

The change of namespaces during devlink reload calls to driver unload
before it accesses devlink parameters. The commands below causes to
use-after-free bug when trying to get flow steering mode.

 * ip netns add n1
 * devlink dev reload pci/0000:00:09.0 netns n1

 ==================================================================
 BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x96/0xa0 [mlx5_core]
 Read of size 4 at addr ffff888009d04308 by task devlink/275

 CPU: 6 PID: 275 Comm: devlink Not tainted 5.12.0-rc2+ #2853
 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
 Call Trace:
  dump_stack+0x93/0xc2
  print_address_description.constprop.0+0x18/0x140
  ? mlx5_devlink_fs_mode_get+0x96/0xa0 [mlx5_core]
  ? mlx5_devlink_fs_mode_get+0x96/0xa0 [mlx5_core]
  kasan_report.cold+0x7c/0xd8
  ? mlx5_devlink_fs_mode_get+0x96/0xa0 [mlx5_core]
  mlx5_devlink_fs_mode_get+0x96/0xa0 [mlx5_core]
  devlink_nl_param_fill+0x1c8/0xe80
  ? __free_pages_ok+0x37a/0x8a0
  ? devlink_flash_update_timeout_notify+0xd0/0xd0
  ? lock_acquire+0x1a9/0x6d0
  ? fs_reclaim_acquire+0xb7/0x160
  ? lock_is_held_type+0x98/0x110
  ? 0xffffffff81000000
  ? lock_release+0x1f9/0x6c0
  ? fs_reclaim_release+0xa1/0xf0
  ? lock_downgrade+0x6d0/0x6d0
  ? lock_is_held_type+0x98/0x110
  ? lock_is_held_type+0x98/0x110
  ? memset+0x20/0x40
  ? __build_skb_around+0x1f8/0x2b0
  devlink_param_notify+0x6d/0x180
  devlink_reload+0x1c3/0x520
  ? devlink_remote_reload_actions_performed+0x30/0x30
  ? mutex_trylock+0x24b/0x2d0
  ? devlink_nl_cmd_reload+0x62b/0x1070
  devlink_nl_cmd_reload+0x66d/0x1070
  ? devlink_reload+0x520/0x520
  ? devlink_get_from_attrs+0x1bc/0x260
  ? devlink_nl_pre_doit+0x64/0x4d0
  genl_family_rcv_msg_doit+0x1e9/0x2f0
  ? mutex_lock_io_nested+0x1130/0x1130
  ? genl_family_rcv_msg_attrs_parse.constprop.0+0x240/0x240
  ? security_capable+0x51/0x90
  genl_rcv_msg+0x27f/0x4a0
  ? genl_get_cmd+0x3c0/0x3c0
  ? lock_acquire+0x1a9/0x6d0
  ? devlink_reload+0x520/0x520
  ? lock_release+0x6c0/0x6c0
  netlink_rcv_skb+0x11d/0x340
  ? genl_get_cmd+0x3c0/0x3c0
  ? netlink_ack+0x9f0/0x9f0
  ? lock_release+0x1f9/0x6c0
  genl_rcv+0x24/0x40
  netlink_unicast+0x433/0x700
  ? netlink_attachskb+0x730/0x730
  ? _copy_from_iter_full+0x178/0x650
  ? __alloc_skb+0x113/0x2b0
  netlink_sendmsg+0x6f1/0xbd0
  ? netlink_unicast+0x700/0x700
  ? lock_is_held_type+0x98/0x110
  ? netlink_unicast+0x700/0x700
  sock_sendmsg+0xb0/0xe0
  __sys_sendto+0x193/0x240
  ? __x64_sys_getpeername+0xb0/0xb0
  ? do_sys_openat2+0x10b/0x370
  ? __up_read+0x1a1/0x7b0
  ? do_user_addr_fault+0x219/0xdc0
  ? __x64_sys_openat+0x120/0x1d0
  ? __x64_sys_open+0x1a0/0x1a0
  __x64_sys_sendto+0xdd/0x1b0
  ? syscall_enter_from_user_mode+0x1d/0x50
  do_syscall_64+0x2d/0x40
  entry_SYSCALL_64_after_hwframe+0x44/0xae
 RIP: 0033:0x7fc69d0af14a
 Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 76 c3 0f 1f 44 00 00 55 48 83 ec 30 44 89 4c
 RSP: 002b:00007ffc1d8292f8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007fc69d0af14a
 RDX: 0000000000000038 RSI: 0000555f57c56440 RDI: 0000000000000003
 RBP: 0000555f57c56410 R08: 00007fc69d17b200 R09: 000000000000000c
 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000

 Allocated by task 146:
  kasan_save_stack+0x1b/0x40
  __kasan_kmalloc+0x99/0xc0
  mlx5_init_fs+0xf0/0x1c50 [mlx5_core]
  mlx5_load+0xd2/0x180 [mlx5_core]
  mlx5_init_one+0x2f6/0x450 [mlx5_core]
  probe_one+0x47d/0x6e0 [mlx5_core]
  pci_device_probe+0x2a0/0x4a0
  really_probe+0x20a/0xc90
  driver_probe_device+0xd8/0x380
  device_driver_attach+0x1df/0x250
  __driver_attach+0xff/0x240
  bus_for_each_dev+0x11e/0x1a0
  bus_add_driver+0x309/0x570
  driver_register+0x1ee/0x380
  0xffffffffa06b8062
  do_one_initcall+0xd5/0x410
  do_init_module+0x1c8/0x760
  load_module+0x6d8b/0x9650
  __do_sys_finit_module+0x118/0x1b0
  do_syscall_64+0x2d/0x40
  entry_SYSCALL_64_after_hwframe+0x44/0xae

 Freed by task 275:
  kasan_save_stack+0x1b/0x40
  kasan_set_track+0x1c/0x30
  kasan_set_free_info+0x20/0x30
  __kasan_slab_free+0x102/0x140
  slab_free_freelist_hook+0x74/0x1b0
  kfree+0xd7/0x2a0
  mlx5_unload+0x16/0xb0 [mlx5_core]
  mlx5_unload_one+0xae/0x120 [mlx5_core]
  mlx5_devlink_reload_down+0x1bc/0x380 [mlx5_core]
  devlink_reload+0x141/0x520
  devlink_nl_cmd_reload+0x66d/0x1070
  genl_family_rcv_msg_doit+0x1e9/0x2f0
  genl_rcv_msg+0x27f/0x4a0
  netlink_rcv_skb+0x11d/0x340
  genl_rcv+0x24/0x40
  netlink_unicast+0x433/0x700
  netlink_sendmsg+0x6f1/0xbd0
  sock_sendmsg+0xb0/0xe0
  __sys_sendto+0x193/0x240
  __x64_sys_sendto+0xdd/0x1b0
  do_syscall_64+0x2d/0x40
  entry_SYSCALL_64_after_hwframe+0x44/0xae

 The buggy address belongs to the object at ffff888009d04300
  which belongs to the cache kmalloc-128 of size 128
 The buggy address is located 8 bytes inside of
  128-byte region [ffff888009d04300, ffff888009d04380)
 The buggy address belongs to the page:
 page:0000000086a64ecc refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888009d04000 pfn:0x9d04
 head:0000000086a64ecc order:1 compound_mapcount:0
 flags: 0x4000000000010200(slab|head)
 raw: 4000000000010200 ffffea0000203980 0000000200000002 ffff8880050428c0
 raw: ffff888009d04000 000000008020001d 00000001ffffffff 0000000000000000
 page dumped because: kasan: bad access detected

 Memory state around the buggy address:
  ffff888009d04200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
  ffff888009d04280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 >ffff888009d04300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                       ^
  ffff888009d04380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  ffff888009d04400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ==================================================================

The right solution to devlink reload is to notify about deletion of
parameters, unload driver, change net namespaces, load driver and notify
about addition of parameters.

Fixes: 070c63f20f6c ("net: devlink: allow to change namespaces during reload")
Reviewed-by: Parav Pandit <email address hidden>
Signed-off-by: Leon Romanovsky <email address hidden>
Signed-off-by: Jakub Kicinski <email address hidden>
(cherry picked from commit 05a7f4a8dff19999ca8a83a35ff4782689de7bfc)
Signed-off-by: Bodong Wang <email address hidden>

9468571... by Leon Romanovsky <email address hidden>

devlink: Remove duplicated registration check

BugLink: https://bugs.launchpad.net/bugs/1962490

Both registered flag and devlink pointer are set at the same time
and indicate the same thing - devlink/devlink_port are ready. Instead
of checking ->registered use devlink pointer as an indication.

Signed-off-by: Leon Romanovsky <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(backported from commit d7907a2b1a3b89bea136025f885035a083525e41)
Signed-off-by: Bodong Wang <email address hidden>
[bodong: resolve conflict due to new line]

Conflicts:
 net/core/devlink.c

61af07b... by Oleksandr Mazur <email address hidden>

net: core: devlink: add dropped stats traps field

BugLink: https://bugs.launchpad.net/bugs/1962490

Whenever query statistics is issued for trap, devlink subsystem
would also fill-in statistics 'dropped' field. This field indicates
the number of packets HW dropped and failed to report to the device driver,
and thus - to the devlink subsystem itself.
In case if device driver didn't register callback for hard drop
statistics querying, 'dropped' field will be omitted and not filled.

Signed-off-by: Oleksandr Mazur <email address hidden>
Signed-off-by: David S. Miller <email address hidden>
(cherry picked from commit ddee9dbc3d7aec1cd9fdcc671db2dd0016fd0f3d)
Signed-off-by: Bodong Wang <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/Documentation/networking/devlink-trap.rst b/Documentation/networking/devlink-trap.rst
0deleted file mode 1006440deleted file mode 100644
index 8e90a85..0000000
--- a/Documentation/networking/devlink-trap.rst
+++ /dev/null
@@ -1,209 +0,0 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3============
4Devlink Trap
5============
6
7Background
8==========
9
10Devices capable of offloading the kernel's datapath and perform functions such
11as bridging and routing must also be able to send specific packets to the
12kernel (i.e., the CPU) for processing.
13
14For example, a device acting as a multicast-aware bridge must be able to send
15IGMP membership reports to the kernel for processing by the bridge module.
16Without processing such packets, the bridge module could never populate its
17MDB.
18
19As another example, consider a device acting as router which has received an IP
20packet with a TTL of 1. Upon routing the packet the device must send it to the
21kernel so that it will route it as well and generate an ICMP Time Exceeded
22error datagram. Without letting the kernel route such packets itself, utilities
23such as ``traceroute`` could never work.
24
25The fundamental ability of sending certain packets to the kernel for processing
26is called "packet trapping".
27
28Overview
29========
30
31The ``devlink-trap`` mechanism allows capable device drivers to register their
32supported packet traps with ``devlink`` and report trapped packets to
33``devlink`` for further analysis.
34
35Upon receiving trapped packets, ``devlink`` will perform a per-trap packets and
36bytes accounting and potentially report the packet to user space via a netlink
37event along with all the provided metadata (e.g., trap reason, timestamp, input
38port). This is especially useful for drop traps (see :ref:`Trap-Types`)
39as it allows users to obtain further visibility into packet drops that would
40otherwise be invisible.
41
42The following diagram provides a general overview of ``devlink-trap``::
43
44 Netlink event: Packet w/ metadata
45 Or a summary of recent drops
46 ^
47 |
48 Userspace |
49 +---------------------------------------------------+
50 Kernel |
51 |
52 +-------+--------+
53 | |
54 | drop_monitor |
55 | |
56 +-------^--------+
57 |
58 |
59 |
60 +----+----+
61 | | Kernel's Rx path
62 | devlink | (non-drop traps)
63 | |
64 +----^----+ ^
65 | |
66 +-----------+
67 |
68 +-------+-------+
69 | |
70 | Device driver |
71 | |
72 +-------^-------+
73 Kernel |
74 +---------------------------------------------------+
75 Hardware |
76 | Trapped packet
77 |
78 +--+---+
79 | |
80 | ASIC |
81 | |
82 +------+
83
84.. _Trap-Types:
85
86Trap Types
87==========
88
89The ``devlink-trap`` mechanism supports the following packet trap types:
90
91 * ``drop``: Trapped packets were dropped by the underlying device. Packets
92 are only processed by ``devlink`` and not injected to the kernel's Rx path.
93 The trap action (see :ref:`Trap-Actions`) can be changed.
94 * ``exception``: Trapped packets were not forwarded as intended by the
95 underlying device due to an exception (e.g., TTL error, missing neighbour
96 entry) and trapped to the control plane for resolution. Packets are
97 processed by ``devlink`` and injected to the kernel's Rx path. Changing the
98 action of such traps is not allowed, as it can easily break the control
99 plane.
100
101.. _Trap-Actions:
102
103Trap Actions
104============
105
106The ``devlink-trap`` mechanism supports the following packet trap actions:
107
108 * ``trap``: The sole copy of the packet is sent to the CPU.
109 * ``drop``: The packet is dropped by the underlying device and a copy is not
110 sent to the CPU.
111
112Generic Packet Traps
113====================
114
115Generic packet traps are used to describe traps that trap well-defined packets
116or packets that are trapped due to well-defined conditions (e.g., TTL error).
117Such traps can be shared by multiple device drivers and their description must
118be added to the following table:
119
120.. list-table:: List of Generic Packet Traps
121 :widths: 5 5 90
122
123 * - Name
124 - Type
125 - Description
126 * - ``source_mac_is_multicast``
127 - ``drop``
128 - Traps incoming packets that the device decided to drop because of a
129 multicast source MAC
130 * - ``vlan_tag_mismatch``
131 - ``drop``
132 - Traps incoming packets that the device decided to drop in case of VLAN
133 tag mismatch: The ingress bridge port is not configured with a PVID and
134 the packet is untagged or prio-tagged
135 * - ``ingress_vlan_filter``
136 - ``drop``
137 - Traps incoming packets that the device decided to drop in case they are
138 tagged with a VLAN that is not configured on the ingress bridge port
139 * - ``ingress_spanning_tree_filter``
140 - ``drop``
141 - Traps incoming packets that the device decided to drop in case the STP
142 state of the ingress bridge port is not "forwarding"
143 * - ``port_list_is_empty``
144 - ``drop``
145 - Traps packets that the device decided to drop in case they need to be
146 flooded (e.g., unknown unicast, unregistered multicast) and there are
147 no ports the packets should be flooded to
148 * - ``port_loopback_filter``
149 - ``drop``
150 - Traps packets that the device decided to drop in case after layer 2
151 forwarding the only port from which they should be transmitted through
152 is the port from which they were received
153 * - ``blackhole_route``
154 - ``drop``
155 - Traps packets that the device decided to drop in case they hit a
156 blackhole route
157 * - ``ttl_value_is_too_small``
158 - ``exception``
159 - Traps unicast packets that should be forwarded by the device whose TTL
160 was decremented to 0 or less
161 * - ``tail_drop``
162 - ``drop``
163 - Traps packets that the device decided to drop because they could not be
164 enqueued to a transmission queue which is full
165
166Driver-specific Packet Traps
167============================
168
169Device drivers can register driver-specific packet traps, but these must be
170clearly documented. Such traps can correspond to device-specific exceptions and
171help debug packet drops caused by these exceptions. The following list includes
172links to the description of driver-specific traps registered by various device
173drivers:
174
175 * :doc:`/devlink-trap-netdevsim`
176
177Generic Packet Trap Groups
178==========================
179
180Generic packet trap groups are used to aggregate logically related packet
181traps. These groups allow the user to batch operations such as setting the trap
182action of all member traps. In addition, ``devlink-trap`` can report aggregated
183per-group packets and bytes statistics, in case per-trap statistics are too
184narrow. The description of these groups must be added to the following table:
185
186.. list-table:: List of Generic Packet Trap Groups
187 :widths: 10 90
188
189 * - Name
190 - Description
191 * - ``l2_drops``
192 - Contains packet traps for packets that were dropped by the device during
193 layer 2 forwarding (i.e., bridge)
194 * - ``l3_drops``
195 - Contains packet traps for packets that were dropped by the device or hit
196 an exception (e.g., TTL error) during layer 3 forwarding
197 * - ``buffer_drops``
198 - Contains packet traps for packets that were dropped by the device due to
199 an enqueue decision
200
201Testing
202=======
203
204See ``tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh`` for a
205test covering the core infrastructure. Test cases should be added for any new
206functionality.
207
208Device drivers should focus their tests on device-specific functionality, such
209as the triggering of supported packet traps.
diff --git a/Documentation/networking/devlink-health.txt b/Documentation/networking/devlink/devlink-health.txt
210similarity index 100%0similarity index 100%
211rename from Documentation/networking/devlink-health.txt1rename from Documentation/networking/devlink-health.txt
212rename to Documentation/networking/devlink/devlink-health.txt2rename to Documentation/networking/devlink/devlink-health.txt
diff --git a/Documentation/networking/devlink-info-versions.rst b/Documentation/networking/devlink/devlink-info-versions.rst
213similarity index 100%3similarity index 100%
214rename from Documentation/networking/devlink-info-versions.rst4rename from Documentation/networking/devlink-info-versions.rst
215rename to Documentation/networking/devlink/devlink-info-versions.rst5rename to Documentation/networking/devlink/devlink-info-versions.rst
diff --git a/Documentation/networking/devlink-params-bnxt.txt b/Documentation/networking/devlink/devlink-params-bnxt.txt
216similarity index 100%6similarity index 100%
217rename from Documentation/networking/devlink-params-bnxt.txt7rename from Documentation/networking/devlink-params-bnxt.txt
218rename to Documentation/networking/devlink/devlink-params-bnxt.txt8rename to Documentation/networking/devlink/devlink-params-bnxt.txt
diff --git a/Documentation/networking/devlink-params-mlx5.txt b/Documentation/networking/devlink/devlink-params-mlx5.txt
219similarity index 100%9similarity index 100%
220rename from Documentation/networking/devlink-params-mlx5.txt10rename from Documentation/networking/devlink-params-mlx5.txt
221rename to Documentation/networking/devlink/devlink-params-mlx5.txt11rename to Documentation/networking/devlink/devlink-params-mlx5.txt
diff --git a/Documentation/networking/devlink-params-mlxsw.txt b/Documentation/networking/devlink/devlink-params-mlxsw.txt
222similarity index 100%12similarity index 100%
223rename from Documentation/networking/devlink-params-mlxsw.txt13rename from Documentation/networking/devlink-params-mlxsw.txt
224rename to Documentation/networking/devlink/devlink-params-mlxsw.txt14rename to Documentation/networking/devlink/devlink-params-mlxsw.txt
diff --git a/Documentation/networking/devlink-params-nfp.txt b/Documentation/networking/devlink/devlink-params-nfp.txt
225similarity index 100%15similarity index 100%
226rename from Documentation/networking/devlink-params-nfp.txt16rename from Documentation/networking/devlink-params-nfp.txt
227rename to Documentation/networking/devlink/devlink-params-nfp.txt17rename to Documentation/networking/devlink/devlink-params-nfp.txt
diff --git a/Documentation/networking/devlink-params.txt b/Documentation/networking/devlink/devlink-params.txt
228similarity index 100%18similarity index 100%
229rename from Documentation/networking/devlink-params.txt19rename from Documentation/networking/devlink-params.txt
230rename to Documentation/networking/devlink/devlink-params.txt20rename to Documentation/networking/devlink/devlink-params.txt
diff --git a/Documentation/networking/devlink-trap-netdevsim.rst b/Documentation/networking/devlink/devlink-trap-netdevsim.rst
231similarity index 100%21similarity index 100%
232rename from Documentation/networking/devlink-trap-netdevsim.rst22rename from Documentation/networking/devlink-trap-netdevsim.rst
233rename to Documentation/networking/devlink/devlink-trap-netdevsim.rst23rename to Documentation/networking/devlink/devlink-trap-netdevsim.rst
diff --git a/Documentation/networking/devlink/devlink-trap.rst b/Documentation/networking/devlink/devlink-trap.rst
234new file mode 10064424new file mode 100644
index 0000000..3ccdbbe
--- /dev/null
+++ b/Documentation/networking/devlink/devlink-trap.rst
@@ -0,0 +1,595 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3============
4Devlink Trap
5============
6
7Background
8==========
9
10Devices capable of offloading the kernel's datapath and perform functions such
11as bridging and routing must also be able to send specific packets to the
12kernel (i.e., the CPU) for processing.
13
14For example, a device acting as a multicast-aware bridge must be able to send
15IGMP membership reports to the kernel for processing by the bridge module.
16Without processing such packets, the bridge module could never populate its
17MDB.
18
19As another example, consider a device acting as router which has received an IP
20packet with a TTL of 1. Upon routing the packet the device must send it to the
21kernel so that it will route it as well and generate an ICMP Time Exceeded
22error datagram. Without letting the kernel route such packets itself, utilities
23such as ``traceroute`` could never work.
24
25The fundamental ability of sending certain packets to the kernel for processing
26is called "packet trapping".
27
28Overview
29========
30
31The ``devlink-trap`` mechanism allows capable device drivers to register their
32supported packet traps with ``devlink`` and report trapped packets to
33``devlink`` for further analysis.
34
35Upon receiving trapped packets, ``devlink`` will perform a per-trap packets and
36bytes accounting and potentially report the packet to user space via a netlink
37event along with all the provided metadata (e.g., trap reason, timestamp, input
38port). This is especially useful for drop traps (see :ref:`Trap-Types`)
39as it allows users to obtain further visibility into packet drops that would
40otherwise be invisible.
41
42The following diagram provides a general overview of ``devlink-trap``::
43
44 Netlink event: Packet w/ metadata
45 Or a summary of recent drops
46 ^
47 |
48 Userspace |
49 +---------------------------------------------------+
50 Kernel |
51 |
52 +-------+--------+
53 | |
54 | drop_monitor |
55 | |
56 +-------^--------+
57 |
58 | Non-control traps
59 |
60 +----+----+
61 | | Kernel's Rx path
62 | devlink | (non-drop traps)
63 | |
64 +----^----+ ^
65 | |
66 +-----------+
67 |
68 +-------+-------+
69 | |
70 | Device driver |
71 | |
72 +-------^-------+
73 Kernel |
74 +---------------------------------------------------+
75 Hardware |
76 | Trapped packet
77 |
78 +--+---+
79 | |
80 | ASIC |
81 | |
82 +------+
83
84.. _Trap-Types:
85
86Trap Types
87==========
88
89The ``devlink-trap`` mechanism supports the following packet trap types:
90
91 * ``drop``: Trapped packets were dropped by the underlying device. Packets
92 are only processed by ``devlink`` and not injected to the kernel's Rx path.
93 The trap action (see :ref:`Trap-Actions`) can be changed.
94 * ``exception``: Trapped packets were not forwarded as intended by the
95 underlying device due to an exception (e.g., TTL error, missing neighbour
96 entry) and trapped to the control plane for resolution. Packets are
97 processed by ``devlink`` and injected to the kernel's Rx path. Changing the
98 action of such traps is not allowed, as it can easily break the control
99 plane.
100 * ``control``: Trapped packets were trapped by the device because these are
101 control packets required for the correct functioning of the control plane.
102 For example, ARP request and IGMP query packets. Packets are injected to
103 the kernel's Rx path, but not reported to the kernel's drop monitor.
104 Changing the action of such traps is not allowed, as it can easily break
105 the control plane.
106
107.. _Trap-Actions:
108
109Trap Actions
110============
111
112The ``devlink-trap`` mechanism supports the following packet trap actions:
113
114 * ``trap``: The sole copy of the packet is sent to the CPU.
115 * ``drop``: The packet is dropped by the underlying device and a copy is not
116 sent to the CPU.
117
118Generic Packet Traps
119====================
120
121Generic packet traps are used to describe traps that trap well-defined packets
122or packets that are trapped due to well-defined conditions (e.g., TTL error).
123Such traps can be shared by multiple device drivers and their description must
124be added to the following table:
125
126.. list-table:: List of Generic Packet Traps
127 :widths: 5 5 90
128
129 * - Name
130 - Type
131 - Description
132 * - ``source_mac_is_multicast``
133 - ``drop``
134 - Traps incoming packets that the device decided to drop because of a
135 multicast source MAC
136 * - ``vlan_tag_mismatch``
137 - ``drop``
138 - Traps incoming packets that the device decided to drop in case of VLAN
139 tag mismatch: The ingress bridge port is not configured with a PVID and
140 the packet is untagged or prio-tagged
141 * - ``ingress_vlan_filter``
142 - ``drop``
143 - Traps incoming packets that the device decided to drop in case they are
144 tagged with a VLAN that is not configured on the ingress bridge port
145 * - ``ingress_spanning_tree_filter``
146 - ``drop``
147 - Traps incoming packets that the device decided to drop in case the STP
148 state of the ingress bridge port is not "forwarding"
149 * - ``port_list_is_empty``
150 - ``drop``
151 - Traps packets that the device decided to drop in case they need to be
152 flooded (e.g., unknown unicast, unregistered multicast) and there are
153 no ports the packets should be flooded to
154 * - ``port_loopback_filter``
155 - ``drop``
156 - Traps packets that the device decided to drop in case after layer 2
157 forwarding the only port from which they should be transmitted through
158 is the port from which they were received
159 * - ``blackhole_route``
160 - ``drop``
161 - Traps packets that the device decided to drop in case they hit a
162 blackhole route
163 * - ``ttl_value_is_too_small``
164 - ``exception``
165 - Traps unicast packets that should be forwarded by the device whose TTL
166 was decremented to 0 or less
167 * - ``tail_drop``
168 - ``drop``
169 - Traps packets that the device decided to drop because they could not be
170 enqueued to a transmission queue which is full
171 * - ``non_ip``
172 - ``drop``
173 - Traps packets that the device decided to drop because they need to
174 undergo a layer 3 lookup, but are not IP or MPLS packets
175 * - ``uc_dip_over_mc_dmac``
176 - ``drop``
177 - Traps packets that the device decided to drop because they need to be
178 routed and they have a unicast destination IP and a multicast destination
179 MAC
180 * - ``dip_is_loopback_address``
181 - ``drop``
182 - Traps packets that the device decided to drop because they need to be
183 routed and their destination IP is the loopback address (i.e., 127.0.0.0/8
184 and ::1/128)
185 * - ``sip_is_mc``
186 - ``drop``
187 - Traps packets that the device decided to drop because they need to be
188 routed and their source IP is multicast (i.e., 224.0.0.0/8 and ff::/8)
189 * - ``sip_is_loopback_address``
190 - ``drop``
191 - Traps packets that the device decided to drop because they need to be
192 routed and their source IP is the loopback address (i.e., 127.0.0.0/8 and ::1/128)
193 * - ``ip_header_corrupted``
194 - ``drop``
195 - Traps packets that the device decided to drop because they need to be
196 routed and their IP header is corrupted: wrong checksum, wrong IP version
197 or too short Internet Header Length (IHL)
198 * - ``ipv4_sip_is_limited_bc``
199 - ``drop``
200 - Traps packets that the device decided to drop because they need to be
201 routed and their source IP is limited broadcast (i.e., 255.255.255.255/32)
202 * - ``ipv6_mc_dip_reserved_scope``
203 - ``drop``
204 - Traps IPv6 packets that the device decided to drop because they need to
205 be routed and their IPv6 multicast destination IP has a reserved scope
206 (i.e., ffx0::/16)
207 * - ``ipv6_mc_dip_interface_local_scope``
208 - ``drop``
209 - Traps IPv6 packets that the device decided to drop because they need to
210 be routed and their IPv6 multicast destination IP has an interface-local scope
211 (i.e., ffx1::/16)
212 * - ``mtu_value_is_too_small``
213 - ``exception``
214 - Traps packets that should have been routed by the device, but were bigger
215 than the MTU of the egress interface
216 * - ``unresolved_neigh``
217 - ``exception``
218 - Traps packets that did not have a matching IP neighbour after routing
219 * - ``mc_reverse_path_forwarding``
220 - ``exception``
221 - Traps multicast IP packets that failed reverse-path forwarding (RPF)
222 check during multicast routing
223 * - ``reject_route``
224 - ``exception``
225 - Traps packets that hit reject routes (i.e., "unreachable", "prohibit")
226 * - ``ipv4_lpm_miss``
227 - ``exception``
228 - Traps unicast IPv4 packets that did not match any route
229 * - ``ipv6_lpm_miss``
230 - ``exception``
231 - Traps unicast IPv6 packets that did not match any route
232 * - ``non_routable_packet``
233 - ``drop``
234 - Traps packets that the device decided to drop because they are not
235 supposed to be routed. For example, IGMP queries can be flooded by the
236 device in layer 2 and reach the router. Such packets should not be
237 routed and instead dropped
238 * - ``decap_error``
239 - ``exception``
240 - Traps NVE and IPinIP packets that the device decided to drop because of
241 failure during decapsulation (e.g., packet being too short, reserved
242 bits set in VXLAN header)
243 * - ``overlay_smac_is_mc``
244 - ``drop``
245 - Traps NVE packets that the device decided to drop because their overlay
246 source MAC is multicast
247 * - ``ingress_flow_action_drop``
248 - ``drop``
249 - Traps packets dropped during processing of ingress flow action drop
250 * - ``egress_flow_action_drop``
251 - ``drop``
252 - Traps packets dropped during processing of egress flow action drop
253 * - ``stp``
254 - ``control``
255 - Traps STP packets
256 * - ``lacp``
257 - ``control``
258 - Traps LACP packets
259 * - ``lldp``
260 - ``control``
261 - Traps LLDP packets
262 * - ``igmp_query``
263 - ``control``
264 - Traps IGMP Membership Query packets
265 * - ``igmp_v1_report``
266 - ``control``
267 - Traps IGMP Version 1 Membership Report packets
268 * - ``igmp_v2_report``
269 - ``control``
270 - Traps IGMP Version 2 Membership Report packets
271 * - ``igmp_v3_report``
272 - ``control``
273 - Traps IGMP Version 3 Membership Report packets
274 * - ``igmp_v2_leave``
275 - ``control``
276 - Traps IGMP Version 2 Leave Group packets
277 * - ``mld_query``
278 - ``control``
279 - Traps MLD Multicast Listener Query packets
280 * - ``mld_v1_report``
281 - ``control``
282 - Traps MLD Version 1 Multicast Listener Report packets
283 * - ``mld_v2_report``
284 - ``control``
285 - Traps MLD Version 2 Multicast Listener Report packets
286 * - ``mld_v1_done``
287 - ``control``
288 - Traps MLD Version 1 Multicast Listener Done packets
289 * - ``ipv4_dhcp``
290 - ``control``
291 - Traps IPv4 DHCP packets
292 * - ``ipv6_dhcp``
293 - ``control``
294 - Traps IPv6 DHCP packets
295 * - ``arp_request``
296 - ``control``
297 - Traps ARP request packets
298 * - ``arp_response``
299 - ``control``
300 - Traps ARP response packets
301 * - ``arp_overlay``
302 - ``control``
303 - Traps NVE-decapsulated ARP packets that reached the overlay network.
304 This is required, for example, when the address that needs to be
305 resolved is a local address
306 * - ``ipv6_neigh_solicit``
307 - ``control``
308 - Traps IPv6 Neighbour Solicitation packets
309 * - ``ipv6_neigh_advert``
310 - ``control``
311 - Traps IPv6 Neighbour Advertisement packets
312 * - ``ipv4_bfd``
313 - ``control``
314 - Traps IPv4 BFD packets
315 * - ``ipv6_bfd``
316 - ``control``
317 - Traps IPv6 BFD packets
318 * - ``ipv4_ospf``
319 - ``control``
320 - Traps IPv4 OSPF packets
321 * - ``ipv6_ospf``
322 - ``control``
323 - Traps IPv6 OSPF packets
324 * - ``ipv4_bgp``
325 - ``control``
326 - Traps IPv4 BGP packets
327 * - ``ipv6_bgp``
328 - ``control``
329 - Traps IPv6 BGP packets
330 * - ``ipv4_vrrp``
331 - ``control``
332 - Traps IPv4 VRRP packets
333 * - ``ipv6_vrrp``
334 - ``control``
335 - Traps IPv6 VRRP packets
336 * - ``ipv4_pim``
337 - ``control``
338 - Traps IPv4 PIM packets
339 * - ``ipv6_pim``
340 - ``control``
341 - Traps IPv6 PIM packets
342 * - ``uc_loopback``
343 - ``control``
344 - Traps unicast packets that need to be routed through the same layer 3
345 interface from which they were received. Such packets are routed by the
346 kernel, but also cause it to potentially generate ICMP redirect packets
347 * - ``local_route``
348 - ``control``
349 - Traps unicast packets that hit a local route and need to be locally
350 delivered
351 * - ``external_route``
352 - ``control``
353 - Traps packets that should be routed through an external interface (e.g.,
354 management interface) that does not belong to the same device (e.g.,
355 switch ASIC) as the ingress interface
356 * - ``ipv6_uc_dip_link_local_scope``
357 - ``control``
358 - Traps unicast IPv6 packets that need to be routed and have a destination
359 IP address with a link-local scope (i.e., fe80::/10). The trap allows
360 device drivers to avoid programming link-local routes, but still receive
361 packets for local delivery
362 * - ``ipv6_dip_all_nodes``
363 - ``control``
364 - Traps IPv6 packets that their destination IP address is the "All Nodes
365 Address" (i.e., ff02::1)
366 * - ``ipv6_dip_all_routers``
367 - ``control``
368 - Traps IPv6 packets that their destination IP address is the "All Routers
369 Address" (i.e., ff02::2)
370 * - ``ipv6_router_solicit``
371 - ``control``
372 - Traps IPv6 Router Solicitation packets
373 * - ``ipv6_router_advert``
374 - ``control``
375 - Traps IPv6 Router Advertisement packets
376 * - ``ipv6_redirect``
377 - ``control``
378 - Traps IPv6 Redirect Message packets
379 * - ``ipv4_router_alert``
380 - ``control``
381 - Traps IPv4 packets that need to be routed and include the Router Alert
382 option. Such packets need to be locally delivered to raw sockets that
383 have the IP_ROUTER_ALERT socket option set
384 * - ``ipv6_router_alert``
385 - ``control``
386 - Traps IPv6 packets that need to be routed and include the Router Alert
387 option in their Hop-by-Hop extension header. Such packets need to be
388 locally delivered to raw sockets that have the IPV6_ROUTER_ALERT socket
389 option set
390 * - ``ptp_event``
391 - ``control``
392 - Traps PTP time-critical event messages (Sync, Delay_req, Pdelay_Req and
393 Pdelay_Resp)
394 * - ``ptp_general``
395 - ``control``
396 - Traps PTP general messages (Announce, Follow_Up, Delay_Resp,
397 Pdelay_Resp_Follow_Up, management and signaling)
398 * - ``flow_action_sample``
399 - ``control``
400 - Traps packets sampled during processing of flow action sample (e.g., via
401 tc's sample action)
402 * - ``flow_action_trap``
403 - ``control``
404 - Traps packets logged during processing of flow action trap (e.g., via
405 tc's trap action)
406 * - ``early_drop``
407 - ``drop``
408 - Traps packets dropped due to the RED (Random Early Detection) algorithm
409 (i.e., early drops)
410 * - ``vxlan_parsing``
411 - ``drop``
412 - Traps packets dropped due to an error in the VXLAN header parsing which
413 might be because of packet truncation or the I flag is not set.
414 * - ``llc_snap_parsing``
415 - ``drop``
416 - Traps packets dropped due to an error in the LLC+SNAP header parsing
417 * - ``vlan_parsing``
418 - ``drop``
419 - Traps packets dropped due to an error in the VLAN header parsing. Could
420 include unexpected packet truncation.
421 * - ``pppoe_ppp_parsing``
422 - ``drop``
423 - Traps packets dropped due to an error in the PPPoE+PPP header parsing.
424 This could include finding a session ID of 0xFFFF (which is reserved and
425 not for use), a PPPoE length which is larger than the frame received or
426 any common error on this type of header
427 * - ``mpls_parsing``
428 - ``drop``
429 - Traps packets dropped due to an error in the MPLS header parsing which
430 could include unexpected header truncation
431 * - ``arp_parsing``
432 - ``drop``
433 - Traps packets dropped due to an error in the ARP header parsing
434 * - ``ip_1_parsing``
435 - ``drop``
436 - Traps packets dropped due to an error in the first IP header parsing.
437 This packet trap could include packets which do not pass an IP checksum
438 check, a header length check (a minimum of 20 bytes), which might suffer
439 from packet truncation thus the total length field exceeds the received
440 packet length etc
441 * - ``ip_n_parsing``
442 - ``drop``
443 - Traps packets dropped due to an error in the parsing of the last IP
444 header (the inner one in case of an IP over IP tunnel). The same common
445 error checking is performed here as for the ip_1_parsing trap
446 * - ``gre_parsing``
447 - ``drop``
448 - Traps packets dropped due to an error in the GRE header parsing
449 * - ``udp_parsing``
450 - ``drop``
451 - Traps packets dropped due to an error in the UDP header parsing.
452 This packet trap could include checksum errorrs, an improper UDP
453 length detected (smaller than 8 bytes) or detection of header
454 truncation.
455 * - ``tcp_parsing``
456 - ``drop``
457 - Traps packets dropped due to an error in the TCP header parsing.
458 This could include TCP checksum errors, improper combination of SYN, FIN
459 and/or RESET etc.
460 * - ``ipsec_parsing``
461 - ``drop``
462 - Traps packets dropped due to an error in the IPSEC header parsing
463 * - ``sctp_parsing``
464 - ``drop``
465 - Traps packets dropped due to an error in the SCTP header parsing.
466 This would mean that port number 0 was used or that the header is
467 truncated.
468 * - ``dccp_parsing``
469 - ``drop``
470 - Traps packets dropped due to an error in the DCCP header parsing
471 * - ``gtp_parsing``
472 - ``drop``
473 - Traps packets dropped due to an error in the GTP header parsing
474 * - ``esp_parsing``
475 - ``drop``
476 - Traps packets dropped due to an error in the ESP header parsing
477 * - ``blackhole_nexthop``
478 - ``drop``
479 - Traps packets that the device decided to drop in case they hit a
480 blackhole nexthop
481 * - ``dmac_filter``
482 - ``drop``
483 - Traps incoming packets that the device decided to drop because
484 the destination MAC is not configured in the MAC table and
485 the interface is not in promiscuous mode
486
487Driver-specific Packet Traps
488============================
489
490Device drivers can register driver-specific packet traps, but these must be
491clearly documented. Such traps can correspond to device-specific exceptions and
492help debug packet drops caused by these exceptions. The following list includes
493links to the description of driver-specific traps registered by various device
494drivers:
495
496 * :doc:`/devlink-trap-netdevsim`
497
498Generic Packet Trap Groups
499==========================
500
501Generic packet trap groups are used to aggregate logically related packet
502traps. These groups allow the user to batch operations such as setting the trap
503action of all member traps. In addition, ``devlink-trap`` can report aggregated
504per-group packets and bytes statistics, in case per-trap statistics are too
505narrow. The description of these groups must be added to the following table:
506
507.. list-table:: List of Generic Packet Trap Groups
508 :widths: 10 90
509
510 * - Name
511 - Description
512 * - ``l2_drops``
513 - Contains packet traps for packets that were dropped by the device during
514 layer 2 forwarding (i.e., bridge)
515 * - ``l3_drops``
516 - Contains packet traps for packets that were dropped by the device during
517 layer 3 forwarding
518 * - ``l3_exceptions``
519 - Contains packet traps for packets that hit an exception (e.g., TTL
520 error) during layer 3 forwarding
521 * - ``buffer_drops``
522 - Contains packet traps for packets that were dropped by the device due to
523 an enqueue decision
524 * - ``tunnel_drops``
525 - Contains packet traps for packets that were dropped by the device during
526 tunnel encapsulation / decapsulation
527 * - ``acl_drops``
528 - Contains packet traps for packets that were dropped by the device during
529 ACL processing
530 * - ``stp``
531 - Contains packet traps for STP packets
532 * - ``lacp``
533 - Contains packet traps for LACP packets
534 * - ``lldp``
535 - Contains packet traps for LLDP packets
536 * - ``mc_snooping``
537 - Contains packet traps for IGMP and MLD packets required for multicast
538 snooping
539 * - ``dhcp``
540 - Contains packet traps for DHCP packets
541 * - ``neigh_discovery``
542 - Contains packet traps for neighbour discovery packets (e.g., ARP, IPv6
543 ND)
544 * - ``bfd``
545 - Contains packet traps for BFD packets
546 * - ``ospf``
547 - Contains packet traps for OSPF packets
548 * - ``bgp``
549 - Contains packet traps for BGP packets
550 * - ``vrrp``
551 - Contains packet traps for VRRP packets
552 * - ``pim``
553 - Contains packet traps for PIM packets
554 * - ``uc_loopback``
555 - Contains a packet trap for unicast loopback packets (i.e.,
556 ``uc_loopback``). This trap is singled-out because in cases such as
557 one-armed router it will be constantly triggered. To limit the impact on
558 the CPU usage, a packet trap policer with a low rate can be bound to the
559 group without affecting other traps
560 * - ``local_delivery``
561 - Contains packet traps for packets that should be locally delivered after
562 routing, but do not match more specific packet traps (e.g.,
563 ``ipv4_bgp``)
564 * - ``external_delivery``
565 - Contains packet traps for packets that should be routed through an
566 external interface (e.g., management interface) that does not belong to
567 the same device (e.g., switch ASIC) as the ingress interface
568 * - ``ipv6``
569 - Contains packet traps for various IPv6 control packets (e.g., Router
570 Advertisements)
571 * - ``ptp_event``
572 - Contains packet traps for PTP time-critical event messages (Sync,
573 Delay_req, Pdelay_Req and Pdelay_Resp)
574 * - ``ptp_general``
575 - Contains packet traps for PTP general messages (Announce, Follow_Up,
576 Delay_Resp, Pdelay_Resp_Follow_Up, management and signaling)
577 * - ``acl_sample``
578 - Contains packet traps for packets that were sampled by the device during
579 ACL processing
580 * - ``acl_trap``
581 - Contains packet traps for packets that were trapped (logged) by the
582 device during ACL processing
583 * - ``parser_error_drops``
584 - Contains packet traps for packets that were marked by the device during
585 parsing as erroneous
586
587Testing
588=======
589
590See ``tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh`` for a
591test covering the core infrastructure. Test cases should be added for any new
592functionality.
593
594Device drivers should focus their tests on device-specific functionality, such
595as the triggering of supported packet traps.
diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
0new file mode 100644596new file mode 100644
index 0000000..1252c2a
--- /dev/null
+++ b/Documentation/networking/devlink/index.rst
@@ -0,0 +1,14 @@
1Linux Devlink Documentation
2===========================
3
4devlink is an API to expose device information and resources not directly
5related to any device class, such as chip-wide/switch-ASIC-wide configuration.
6
7Contents:
8
9.. toctree::
10 :maxdepth: 1
11
12 devlink-info-versions
13 devlink-trap
14 devlink-trap-netdevsim
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index d4dca42..ad58761 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -13,9 +13,8 @@ Contents:
13 can_ucan_protocol13 can_ucan_protocol
14 device_drivers/index14 device_drivers/index
15 dsa/index15 dsa/index
16 devlink-info-versions16 devlink/index
17 devlink-trap17 ethtool-netlink
18 devlink-trap-netdevsim
19 ieee80215418 ieee802154
20 j193919 j1939
21 kapi20 kapi
diff --git a/MAINTAINERS b/MAINTAINERS
index 349639d..d8fd753 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4836,6 +4836,7 @@ S: Supported
4836F: net/core/devlink.c4836F: net/core/devlink.c
4837F: include/net/devlink.h4837F: include/net/devlink.h
4838F: include/uapi/linux/devlink.h4838F: include/uapi/linux/devlink.h
4839F: Documentation/networking/devlink
48394840
4840DIALOG SEMICONDUCTOR DRIVERS4841DIALOG SEMICONDUCTOR DRIVERS
4841M: Support Opensource <support.opensource@diasemi.com>4842M: Support Opensource <support.opensource@diasemi.com>
diff --git a/debian.bluefield/config/config.common.ubuntu b/debian.bluefield/config/config.common.ubuntu
index f1fcfae..86c5a87 100644
--- a/debian.bluefield/config/config.common.ubuntu
+++ b/debian.bluefield/config/config.common.ubuntu
@@ -2419,26 +2419,7 @@ CONFIG_MISC_FILESYSTEMS=y
2419# CONFIG_MISC_RTSX_USB is not set2419# CONFIG_MISC_RTSX_USB is not set
2420# CONFIG_MLX4_EN is not set2420# CONFIG_MLX4_EN is not set
2421# CONFIG_MLX4_INFINIBAND is not set2421# CONFIG_MLX4_INFINIBAND is not set
2422CONFIG_MLX5_ACCEL=y2422# CONFIG_MLX5_CORE is not set
2423CONFIG_MLX5_CORE=m
2424CONFIG_MLX5_CORE_EN=y
2425CONFIG_MLX5_CORE_EN_DCB=y
2426CONFIG_MLX5_CORE_IPOIB=y
2427CONFIG_MLX5_EN_ARFS=y
2428CONFIG_MLX5_EN_IPSEC=y
2429CONFIG_MLX5_EN_RXNFC=y
2430CONFIG_MLX5_EN_TLS=y
2431CONFIG_MLX5_ESWITCH=y
2432CONFIG_MLX5_FPGA=y
2433CONFIG_MLX5_FPGA_IPSEC=y
2434CONFIG_MLX5_FPGA_TLS=y
2435CONFIG_MLX5_INFINIBAND=m
2436CONFIG_MLX5_IPSEC=y
2437CONFIG_MLX5_MDEV=y
2438CONFIG_MLX5_MPFS=y
2439CONFIG_MLX5_SW_STEERING=y
2440CONFIG_MLX5_TC_CT=y
2441CONFIG_MLX5_TLS=y
2442# CONFIG_MLX90614 is not set2423# CONFIG_MLX90614 is not set
2443# CONFIG_MLX90632 is not set2424# CONFIG_MLX90632 is not set
2444CONFIG_MLXBF_BOOTCTL=m2425CONFIG_MLXBF_BOOTCTL=m
@@ -2448,7 +2429,7 @@ CONFIG_MLXBF_PKA=m
2448CONFIG_MLXBF_PMC=m2429CONFIG_MLXBF_PMC=m
2449CONFIG_MLXBF_TMFIFO=y2430CONFIG_MLXBF_TMFIFO=y
2450CONFIG_MLXBF_TRIO=m2431CONFIG_MLXBF_TRIO=m
2451CONFIG_MLXFW=m2432# CONFIG_MLXFW is not set
2452CONFIG_MLXREG_HOTPLUG=m2433CONFIG_MLXREG_HOTPLUG=m
2453CONFIG_MLXREG_IO=m2434CONFIG_MLXREG_IO=m
2454# CONFIG_MLXSW_CORE is not set2435# CONFIG_MLXSW_CORE is not set
@@ -2776,7 +2757,7 @@ CONFIG_NET_CLS_TCINDEX=m
2776CONFIG_NET_CLS_U32=m2757CONFIG_NET_CLS_U32=m
2777CONFIG_NET_CORE=y2758CONFIG_NET_CORE=y
2778CONFIG_NET_DEVLINK=y2759CONFIG_NET_DEVLINK=y
2779CONFIG_NET_DROP_MONITOR=y2760# CONFIG_NET_DROP_MONITOR is not set
2780# CONFIG_NET_DSA is not set2761# CONFIG_NET_DSA is not set
2781CONFIG_NET_EGRESS=y2762CONFIG_NET_EGRESS=y
2782CONFIG_NET_EMATCH=y2763CONFIG_NET_EMATCH=y
@@ -2867,7 +2848,11 @@ CONFIG_NET_UDP_TUNNEL=m
2867# CONFIG_NET_VENDOR_ARC is not set2848# CONFIG_NET_VENDOR_ARC is not set
2868# CONFIG_NET_VENDOR_ATHEROS is not set2849# CONFIG_NET_VENDOR_ATHEROS is not set
2869# CONFIG_NET_VENDOR_AURORA is not set2850# CONFIG_NET_VENDOR_AURORA is not set
2870# CONFIG_NET_VENDOR_BROADCOM is not set2851CONFIG_BNXT=m
2852# CONFIG_BNXT_SRIOV is not set
2853# CONFIG_BNXT_FLOWER_OFFLOAD is not set
2854# CONFIG_BNXT_DCB is not set
2855# CONFIG_BNXT_HWMON is not set
2871# CONFIG_NET_VENDOR_BROCADE is not set2856# CONFIG_NET_VENDOR_BROCADE is not set
2872# CONFIG_NET_VENDOR_CADENCE is not set2857# CONFIG_NET_VENDOR_CADENCE is not set
2873# CONFIG_NET_VENDOR_CAVIUM is not set2858# CONFIG_NET_VENDOR_CAVIUM is not set
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index 2d817ba..58b69b4 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -16,7 +16,8 @@
16#include "bnxt_devlink.h"16#include "bnxt_devlink.h"
1717
18static int bnxt_fw_reporter_diagnose(struct devlink_health_reporter *reporter,18static int bnxt_fw_reporter_diagnose(struct devlink_health_reporter *reporter,
19 struct devlink_fmsg *fmsg)19 struct devlink_fmsg *fmsg,
20 struct netlink_ext_ack *extack)
20{21{
21 struct bnxt *bp = devlink_health_reporter_priv(reporter);22 struct bnxt *bp = devlink_health_reporter_priv(reporter);
22 u32 val, health_status;23 u32 val, health_status;
@@ -60,7 +61,8 @@ static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = {
60};61};
6162
62static int bnxt_fw_reset_recover(struct devlink_health_reporter *reporter,63static int bnxt_fw_reset_recover(struct devlink_health_reporter *reporter,
63 void *priv_ctx)64 void *priv_ctx,
65 struct netlink_ext_ack *extack)
64{66{
65 struct bnxt *bp = devlink_health_reporter_priv(reporter);67 struct bnxt *bp = devlink_health_reporter_priv(reporter);
6668
@@ -78,7 +80,8 @@ struct devlink_health_reporter_ops bnxt_dl_fw_reset_reporter_ops = {
78};80};
7981
80static int bnxt_fw_fatal_recover(struct devlink_health_reporter *reporter,82static int bnxt_fw_fatal_recover(struct devlink_health_reporter *reporter,
81 void *priv_ctx)83 void *priv_ctx,
84 struct netlink_ext_ack *extack)
82{85{
83 struct bnxt *bp = devlink_health_reporter_priv(reporter);86 struct bnxt *bp = devlink_health_reporter_priv(reporter);
84 struct bnxt_fw_reporter_ctx *fw_reporter_ctx = priv_ctx;87 struct bnxt_fw_reporter_ctx *fw_reporter_ctx = priv_ctx;
@@ -115,7 +118,7 @@ void bnxt_dl_fw_reporters_create(struct bnxt *bp)
115 health->fw_reset_reporter =118 health->fw_reset_reporter =
116 devlink_health_reporter_create(bp->dl,119 devlink_health_reporter_create(bp->dl,
117 &bnxt_dl_fw_reset_reporter_ops,120 &bnxt_dl_fw_reset_reporter_ops,
118 0, true, bp);121 0, bp);
119 if (IS_ERR(health->fw_reset_reporter)) {122 if (IS_ERR(health->fw_reset_reporter)) {
120 netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",123 netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",
121 PTR_ERR(health->fw_reset_reporter));124 PTR_ERR(health->fw_reset_reporter));
@@ -131,7 +134,7 @@ err_recovery:
131 health->fw_reporter =134 health->fw_reporter =
132 devlink_health_reporter_create(bp->dl,135 devlink_health_reporter_create(bp->dl,
133 &bnxt_dl_fw_reporter_ops,136 &bnxt_dl_fw_reporter_ops,
134 0, false, bp);137 0, bp);
135 if (IS_ERR(health->fw_reporter)) {138 if (IS_ERR(health->fw_reporter)) {
136 netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n",139 netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n",
137 PTR_ERR(health->fw_reporter));140 PTR_ERR(health->fw_reporter));
@@ -147,7 +150,7 @@ err_recovery:
147 health->fw_fatal_reporter =150 health->fw_fatal_reporter =
148 devlink_health_reporter_create(bp->dl,151 devlink_health_reporter_create(bp->dl,
149 &bnxt_dl_fw_fatal_reporter_ops,152 &bnxt_dl_fw_fatal_reporter_ops,
150 0, true, bp);153 0, bp);
151 if (IS_ERR(health->fw_fatal_reporter)) {154 if (IS_ERR(health->fw_fatal_reporter)) {
152 netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",155 netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",
153 PTR_ERR(health->fw_fatal_reporter));156 PTR_ERR(health->fw_fatal_reporter));
@@ -433,6 +436,7 @@ static const struct devlink_param bnxt_dl_port_params[] = {
433436
434int bnxt_dl_register(struct bnxt *bp)437int bnxt_dl_register(struct bnxt *bp)
435{438{
439 struct devlink_port_attrs attrs = {};
436 struct devlink *dl;440 struct devlink *dl;
437 int rc;441 int rc;
438442
@@ -466,17 +470,11 @@ int bnxt_dl_register(struct bnxt *bp)
466 if (!BNXT_PF(bp))470 if (!BNXT_PF(bp))
467 return 0;471 return 0;
468472
469 rc = devlink_params_register(dl, bnxt_dl_params,473 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
470 ARRAY_SIZE(bnxt_dl_params));474 attrs.phys.port_number = bp->pf.port_id;
471 if (rc) {475 memcpy(attrs.switch_id.id, bp->switch_id, sizeof(bp->switch_id));
472 netdev_warn(bp->dev, "devlink_params_register failed. rc=%d",476 attrs.switch_id.id_len = sizeof(bp->switch_id);
473 rc);477 devlink_port_attrs_set(&bp->dl_port, &attrs);
474 goto err_dl_unreg;
475 }
476
477 devlink_port_attrs_set(&bp->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
478 bp->pf.port_id, false, 0,
479 bp->switch_id, sizeof(bp->switch_id));
480 rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);478 rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
481 if (rc) {479 if (rc) {
482 netdev_err(bp->dev, "devlink_port_register failed");480 netdev_err(bp->dev, "devlink_port_register failed");
diff --git a/drivers/net/ethernet/mellanox/mlx4/crdump.c b/drivers/net/ethernet/mellanox/mlx4/crdump.c
index eaf08f7..2700628 100644
--- a/drivers/net/ethernet/mellanox/mlx4/crdump.c
+++ b/drivers/net/ethernet/mellanox/mlx4/crdump.c
@@ -38,8 +38,18 @@
38#define CR_ENABLE_BIT_OFFSET 0xF3F0438#define CR_ENABLE_BIT_OFFSET 0xF3F04
39#define MAX_NUM_OF_DUMPS_TO_STORE (8)39#define MAX_NUM_OF_DUMPS_TO_STORE (8)
4040
41static const char *region_cr_space_str = "cr-space";41static const char * const region_cr_space_str = "cr-space";
42static const char *region_fw_health_str = "fw-health";42static const char * const region_fw_health_str = "fw-health";
43
44static const struct devlink_region_ops region_cr_space_ops = {
45 .name = region_cr_space_str,
46 .destructor = &kvfree,
47};
48
49static const struct devlink_region_ops region_fw_health_ops = {
50 .name = region_fw_health_str,
51 .destructor = &kvfree,
52};
4353
44/* Set to true in case cr enable bit was set to true before crdump */54/* Set to true in case cr enable bit was set to true before crdump */
45static bool crdump_enbale_bit_set;55static bool crdump_enbale_bit_set;
@@ -99,7 +109,7 @@ static void mlx4_crdump_collect_crspace(struct mlx4_dev *dev,
99 readl(cr_space + offset);109 readl(cr_space + offset);
100110
101 err = devlink_region_snapshot_create(crdump->region_crspace,111 err = devlink_region_snapshot_create(crdump->region_crspace,
102 crspace_data, id, &kvfree);112 crspace_data, id);
103 if (err) {113 if (err) {
104 kvfree(crspace_data);114 kvfree(crspace_data);
105 mlx4_warn(dev, "crdump: devlink create %s snapshot id %d err %d\n",115 mlx4_warn(dev, "crdump: devlink create %s snapshot id %d err %d\n",
@@ -138,7 +148,7 @@ static void mlx4_crdump_collect_fw_health(struct mlx4_dev *dev,
138 readl(health_buf_start + offset);148 readl(health_buf_start + offset);
139149
140 err = devlink_region_snapshot_create(crdump->region_fw_health,150 err = devlink_region_snapshot_create(crdump->region_fw_health,
141 health_data, id, &kvfree);151 health_data, id);
142 if (err) {152 if (err) {
143 kvfree(health_data);153 kvfree(health_data);
144 mlx4_warn(dev, "crdump: devlink create %s snapshot id %d err %d\n",154 mlx4_warn(dev, "crdump: devlink create %s snapshot id %d err %d\n",
@@ -159,6 +169,7 @@ int mlx4_crdump_collect(struct mlx4_dev *dev)
159 struct pci_dev *pdev = dev->persist->pdev;169 struct pci_dev *pdev = dev->persist->pdev;
160 unsigned long cr_res_size;170 unsigned long cr_res_size;
161 u8 __iomem *cr_space;171 u8 __iomem *cr_space;
172 int err;
162 u32 id;173 u32 id;
163174
164 if (!dev->caps.health_buffer_addrs) {175 if (!dev->caps.health_buffer_addrs) {
@@ -179,15 +190,22 @@ int mlx4_crdump_collect(struct mlx4_dev *dev)
179 return -ENODEV;190 return -ENODEV;
180 }191 }
181192
182 crdump_enable_crspace_access(dev, cr_space);
183
184 /* Get the available snapshot ID for the dumps */193 /* Get the available snapshot ID for the dumps */
185 id = devlink_region_shapshot_id_get(devlink);194 err = devlink_region_snapshot_id_get(devlink, &id);
195 if (err) {
196 mlx4_err(dev, "crdump: devlink get snapshot id err %d\n", err);
197 return err;
198 }
199
200 crdump_enable_crspace_access(dev, cr_space);
186201
187 /* Try to capture dumps */202 /* Try to capture dumps */
188 mlx4_crdump_collect_crspace(dev, cr_space, id);203 mlx4_crdump_collect_crspace(dev, cr_space, id);
189 mlx4_crdump_collect_fw_health(dev, cr_space, id);204 mlx4_crdump_collect_fw_health(dev, cr_space, id);
190205
206 /* Release reference on the snapshot id */
207 devlink_region_snapshot_id_put(devlink, id);
208
191 crdump_disable_crspace_access(dev, cr_space);209 crdump_disable_crspace_access(dev, cr_space);
192210
193 iounmap(cr_space);211 iounmap(cr_space);
@@ -205,7 +223,7 @@ int mlx4_crdump_init(struct mlx4_dev *dev)
205 /* Create cr-space region */223 /* Create cr-space region */
206 crdump->region_crspace =224 crdump->region_crspace =
207 devlink_region_create(devlink,225 devlink_region_create(devlink,
208 region_cr_space_str,226 &region_cr_space_ops,
209 MAX_NUM_OF_DUMPS_TO_STORE,227 MAX_NUM_OF_DUMPS_TO_STORE,
210 pci_resource_len(pdev, 0));228 pci_resource_len(pdev, 0));
211 if (IS_ERR(crdump->region_crspace))229 if (IS_ERR(crdump->region_crspace))
@@ -216,7 +234,7 @@ int mlx4_crdump_init(struct mlx4_dev *dev)
216 /* Create fw-health region */234 /* Create fw-health region */
217 crdump->region_fw_health =235 crdump->region_fw_health =
218 devlink_region_create(devlink,236 devlink_region_create(devlink,
219 region_fw_health_str,237 &region_fw_health_ops,
220 MAX_NUM_OF_DUMPS_TO_STORE,238 MAX_NUM_OF_DUMPS_TO_STORE,
221 HEALTH_BUFFER_SIZE);239 HEALTH_BUFFER_SIZE);
222 if (IS_ERR(crdump->region_fw_health))240 if (IS_ERR(crdump->region_fw_health))
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 35882d6..c079910 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -3943,20 +3943,27 @@ static void mlx4_restart_one_down(struct pci_dev *pdev);
3943static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload,3943static int mlx4_restart_one_up(struct pci_dev *pdev, bool reload,
3944 struct devlink *devlink);3944 struct devlink *devlink);
39453945
3946static int mlx4_devlink_reload_down(struct devlink *devlink,3946static int mlx4_devlink_reload_down(struct devlink *devlink, bool netns_change,
3947 enum devlink_reload_action action,
3948 enum devlink_reload_limit limit,
3947 struct netlink_ext_ack *extack)3949 struct netlink_ext_ack *extack)
3948{3950{
3949 struct mlx4_priv *priv = devlink_priv(devlink);3951 struct mlx4_priv *priv = devlink_priv(devlink);
3950 struct mlx4_dev *dev = &priv->dev;3952 struct mlx4_dev *dev = &priv->dev;
3951 struct mlx4_dev_persistent *persist = dev->persist;3953 struct mlx4_dev_persistent *persist = dev->persist;
39523954
3955 if (netns_change) {
3956 NL_SET_ERR_MSG_MOD(extack, "Namespace change is not supported");
3957 return -EOPNOTSUPP;
3958 }
3953 if (persist->num_vfs)3959 if (persist->num_vfs)
3954 mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n");3960 mlx4_warn(persist->dev, "Reload performed on PF, will cause reset on operating Virtual Functions\n");
3955 mlx4_restart_one_down(persist->pdev);3961 mlx4_restart_one_down(persist->pdev);
3956 return 0;3962 return 0;
3957}3963}
39583964
3959static int mlx4_devlink_reload_up(struct devlink *devlink,3965static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_action action,
3966 enum devlink_reload_limit limit, u32 *actions_performed,
3960 struct netlink_ext_ack *extack)3967 struct netlink_ext_ack *extack)
3961{3968{
3962 struct mlx4_priv *priv = devlink_priv(devlink);3969 struct mlx4_priv *priv = devlink_priv(devlink);
@@ -3964,6 +3971,7 @@ static int mlx4_devlink_reload_up(struct devlink *devlink,
3964 struct mlx4_dev_persistent *persist = dev->persist;3971 struct mlx4_dev_persistent *persist = dev->persist;
3965 int err;3972 int err;
39663973
3974 *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
3967 err = mlx4_restart_one_up(persist->pdev, true, devlink);3975 err = mlx4_restart_one_up(persist->pdev, true, devlink);
3968 if (err)3976 if (err)
3969 mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n",3977 mlx4_err(persist->dev, "mlx4_restart_one_up failed, ret=%d\n",
@@ -3974,6 +3982,7 @@ static int mlx4_devlink_reload_up(struct devlink *devlink,
39743982
3975static const struct devlink_ops mlx4_devlink_ops = {3983static const struct devlink_ops mlx4_devlink_ops = {
3976 .port_type_set = mlx4_devlink_port_type_set,3984 .port_type_set = mlx4_devlink_port_type_set,
3985 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
3977 .reload_down = mlx4_devlink_reload_down,3986 .reload_down = mlx4_devlink_reload_down,
3978 .reload_up = mlx4_devlink_reload_up,3987 .reload_up = mlx4_devlink_reload_up,
3979};3988};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
index 9fa4b98..75afcab 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
@@ -222,7 +222,8 @@ static int mlx5e_rx_reporter_recover_from_ctx(struct mlx5e_err_ctx *err_ctx)
222}222}
223223
224static int mlx5e_rx_reporter_recover(struct devlink_health_reporter *reporter,224static int mlx5e_rx_reporter_recover(struct devlink_health_reporter *reporter,
225 void *context)225 void *context,
226 struct netlink_ext_ack *extack)
226{227{
227 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);228 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);
228 struct mlx5e_err_ctx *err_ctx = context;229 struct mlx5e_err_ctx *err_ctx = context;
@@ -301,7 +302,8 @@ static int mlx5e_rx_reporter_build_diagnose_output(struct mlx5e_rq *rq,
301}302}
302303
303static int mlx5e_rx_reporter_diagnose(struct devlink_health_reporter *reporter,304static int mlx5e_rx_reporter_diagnose(struct devlink_health_reporter *reporter,
304 struct devlink_fmsg *fmsg)305 struct devlink_fmsg *fmsg,
306 struct netlink_ext_ack *extack)
305{307{
306 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);308 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);
307 struct mlx5e_params *params = &priv->channels.params;309 struct mlx5e_params *params = &priv->channels.params;
@@ -385,7 +387,7 @@ int mlx5e_reporter_rx_create(struct mlx5e_priv *priv)
385 reporter = devlink_health_reporter_create(devlink,387 reporter = devlink_health_reporter_create(devlink,
386 &mlx5_rx_reporter_ops,388 &mlx5_rx_reporter_ops,
387 MLX5E_REPORTER_RX_GRACEFUL_PERIOD,389 MLX5E_REPORTER_RX_GRACEFUL_PERIOD,
388 true, priv);390 priv);
389 if (IS_ERR(reporter)) {391 if (IS_ERR(reporter)) {
390 netdev_warn(priv->netdev, "Failed to create rx reporter, err = %ld\n",392 netdev_warn(priv->netdev, "Failed to create rx reporter, err = %ld\n",
391 PTR_ERR(reporter));393 PTR_ERR(reporter));
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
index bfed558..8b1089f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
@@ -135,7 +135,8 @@ static int mlx5e_tx_reporter_recover_from_ctx(struct mlx5e_err_ctx *err_ctx)
135}135}
136136
137static int mlx5e_tx_reporter_recover(struct devlink_health_reporter *reporter,137static int mlx5e_tx_reporter_recover(struct devlink_health_reporter *reporter,
138 void *context)138 void *context,
139 struct netlink_ext_ack *extack)
139{140{
140 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);141 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);
141 struct mlx5e_err_ctx *err_ctx = context;142 struct mlx5e_err_ctx *err_ctx = context;
@@ -205,7 +206,8 @@ mlx5e_tx_reporter_build_diagnose_output(struct devlink_fmsg *fmsg,
205}206}
206207
207static int mlx5e_tx_reporter_diagnose(struct devlink_health_reporter *reporter,208static int mlx5e_tx_reporter_diagnose(struct devlink_health_reporter *reporter,
208 struct devlink_fmsg *fmsg)209 struct devlink_fmsg *fmsg,
210 struct netlink_ext_ack *extack)
209{211{
210 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);212 struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);
211 struct mlx5e_txqsq *generic_sq = priv->txq2sq[0];213 struct mlx5e_txqsq *generic_sq = priv->txq2sq[0];
@@ -291,7 +293,7 @@ int mlx5e_reporter_tx_create(struct mlx5e_priv *priv)
291 reporter =293 reporter =
292 devlink_health_reporter_create(devlink, &mlx5_tx_reporter_ops,294 devlink_health_reporter_create(devlink, &mlx5_tx_reporter_ops,
293 MLX5_REPORTER_TX_GRACEFUL_PERIOD,295 MLX5_REPORTER_TX_GRACEFUL_PERIOD,
294 true, priv);296 priv);
295 if (IS_ERR(reporter)) {297 if (IS_ERR(reporter)) {
296 netdev_warn(priv->netdev,298 netdev_warn(priv->netdev,
297 "Failed to create tx reporter, err = %ld\n",299 "Failed to create tx reporter, err = %ld\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index f628887..780ae27 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -398,7 +398,8 @@ static void print_health_info(struct mlx5_core_dev *dev)
398398
399static int399static int
400mlx5_fw_reporter_diagnose(struct devlink_health_reporter *reporter,400mlx5_fw_reporter_diagnose(struct devlink_health_reporter *reporter,
401 struct devlink_fmsg *fmsg)401 struct devlink_fmsg *fmsg,
402 struct netlink_ext_ack *extack)
402{403{
403 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);404 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);
404 struct mlx5_core_health *health = &dev->priv.health;405 struct mlx5_core_health *health = &dev->priv.health;
@@ -499,7 +500,8 @@ mlx5_fw_reporter_heath_buffer_data_put(struct mlx5_core_dev *dev,
499500
500static int501static int
501mlx5_fw_reporter_dump(struct devlink_health_reporter *reporter,502mlx5_fw_reporter_dump(struct devlink_health_reporter *reporter,
502 struct devlink_fmsg *fmsg, void *priv_ctx)503 struct devlink_fmsg *fmsg, void *priv_ctx,
504 struct netlink_ext_ack *extack)
503{505{
504 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);506 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);
505 int err;507 int err;
@@ -553,7 +555,8 @@ static const struct devlink_health_reporter_ops mlx5_fw_reporter_ops = {
553555
554static int556static int
555mlx5_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,557mlx5_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
556 void *priv_ctx)558 void *priv_ctx,
559 struct netlink_ext_ack *extack)
557{560{
558 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);561 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);
559562
@@ -563,7 +566,8 @@ mlx5_fw_fatal_reporter_recover(struct devlink_health_reporter *reporter,
563#define MLX5_CR_DUMP_CHUNK_SIZE 256566#define MLX5_CR_DUMP_CHUNK_SIZE 256
564static int567static int
565mlx5_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter,568mlx5_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter,
566 struct devlink_fmsg *fmsg, void *priv_ctx)569 struct devlink_fmsg *fmsg, void *priv_ctx,
570 struct netlink_ext_ack *extack)
567{571{
568 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);572 struct mlx5_core_dev *dev = devlink_health_reporter_priv(reporter);
569 u32 crdump_size = dev->priv.health.crdump_size;573 u32 crdump_size = dev->priv.health.crdump_size;
@@ -647,7 +651,7 @@ static void mlx5_fw_reporters_create(struct mlx5_core_dev *dev)
647651
648 health->fw_reporter =652 health->fw_reporter =
649 devlink_health_reporter_create(devlink, &mlx5_fw_reporter_ops,653 devlink_health_reporter_create(devlink, &mlx5_fw_reporter_ops,
650 0, false, dev);654 0, dev);
651 if (IS_ERR(health->fw_reporter))655 if (IS_ERR(health->fw_reporter))
652 mlx5_core_warn(dev, "Failed to create fw reporter, err = %ld\n",656 mlx5_core_warn(dev, "Failed to create fw reporter, err = %ld\n",
653 PTR_ERR(health->fw_reporter));657 PTR_ERR(health->fw_reporter));
@@ -656,7 +660,7 @@ static void mlx5_fw_reporters_create(struct mlx5_core_dev *dev)
656 devlink_health_reporter_create(devlink,660 devlink_health_reporter_create(devlink,
657 &mlx5_fw_fatal_reporter_ops,661 &mlx5_fw_fatal_reporter_ops,
658 MLX5_REPORTER_FW_GRACEFUL_PERIOD,662 MLX5_REPORTER_FW_GRACEFUL_PERIOD,
659 true, dev);663 dev);
660 if (IS_ERR(health->fw_fatal_reporter))664 if (IS_ERR(health->fw_fatal_reporter))
661 mlx5_core_warn(dev, "Failed to create fw fatal reporter, err = %ld\n",665 mlx5_core_warn(dev, "Failed to create fw fatal reporter, err = %ld\n",
662 PTR_ERR(health->fw_fatal_reporter));666 PTR_ERR(health->fw_fatal_reporter));
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 2d39bad..dff8d24 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -990,6 +990,8 @@ mlxsw_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
990990
991static int991static int
992mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,992mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
993 bool netns_change, enum devlink_reload_action action,
994 enum devlink_reload_limit limit,
993 struct netlink_ext_ack *extack)995 struct netlink_ext_ack *extack)
994{996{
995 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);997 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
@@ -1002,11 +1004,14 @@ mlxsw_devlink_core_bus_device_reload_down(struct devlink *devlink,
1002}1004}
10031005
1004static int1006static int
1005mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink,1007mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink, enum devlink_reload_action action,
1008 enum devlink_reload_limit limit, u32 *actions_performed,
1006 struct netlink_ext_ack *extack)1009 struct netlink_ext_ack *extack)
1007{1010{
1008 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);1011 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
10091012
1013 *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
1014 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
1010 return mlxsw_core_bus_device_register(mlxsw_core->bus_info,1015 return mlxsw_core_bus_device_register(mlxsw_core->bus_info,
1011 mlxsw_core->bus,1016 mlxsw_core->bus,
1012 mlxsw_core->bus_priv, true,1017 mlxsw_core->bus_priv, true,
@@ -1076,6 +1081,8 @@ mlxsw_devlink_trap_group_init(struct devlink *devlink,
1076}1081}
10771082
1078static const struct devlink_ops mlxsw_devlink_ops = {1083static const struct devlink_ops mlxsw_devlink_ops = {
1084 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
1085 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
1079 .reload_down = mlxsw_devlink_core_bus_device_reload_down,1086 .reload_down = mlxsw_devlink_core_bus_device_reload_down,
1080 .reload_up = mlxsw_devlink_core_bus_device_reload_up,1087 .reload_up = mlxsw_devlink_core_bus_device_reload_up,
1081 .port_type_set = mlxsw_devlink_port_type_set,1088 .port_type_set = mlxsw_devlink_port_type_set,
@@ -1889,12 +1896,19 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
1889 struct mlxsw_core_port *mlxsw_core_port =1896 struct mlxsw_core_port *mlxsw_core_port =
1890 &mlxsw_core->ports[local_port];1897 &mlxsw_core->ports[local_port];
1891 struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;1898 struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
1899 struct devlink_port_attrs attrs = {};
1892 int err;1900 int err;
18931901
1902 attrs.split = split;
1903 attrs.lanes = lanes;
1904 attrs.splittable = splittable;
1905 attrs.flavour = flavour;
1906 attrs.phys.port_number = port_number;
1907 attrs.phys.split_subport_number = split_port_subnumber;
1908 memcpy(attrs.switch_id.id, switch_id, switch_id_len);
1909 attrs.switch_id.id_len = switch_id_len;
1894 mlxsw_core_port->local_port = local_port;1910 mlxsw_core_port->local_port = local_port;
1895 devlink_port_attrs_set(devlink_port, flavour, port_number,1911 devlink_port_attrs_set(devlink_port, &attrs);
1896 split, split_port_subnumber,
1897 switch_id, switch_id_len);
1898 err = devlink_port_register(devlink, devlink_port, local_port);1912 err = devlink_port_register(devlink, devlink_port, local_port);
1899 if (err)1913 if (err)
1900 memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));1914 memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 5d7d2ab..30a718a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -18,6 +18,11 @@
18#include "cmd.h"18#include "cmd.h"
19#include "resources.h"19#include "resources.h"
2020
21enum mlxsw_core_resource_id {
22 MLXSW_CORE_RESOURCE_PORTS = 1,
23 MLXSW_CORE_RESOURCE_MAX,
24};
25
21struct mlxsw_core;26struct mlxsw_core;
22struct mlxsw_core_port;27struct mlxsw_core_port;
23struct mlxsw_driver;28struct mlxsw_driver;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index b2a0028..9f7107e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -48,7 +48,7 @@
48#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS "large_chunks"48#define MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS "large_chunks"
4949
50enum mlxsw_sp_resource_id {50enum mlxsw_sp_resource_id {
51 MLXSW_SP_RESOURCE_KVD = 1,51 MLXSW_SP_RESOURCE_KVD = MLXSW_CORE_RESOURCE_MAX,
52 MLXSW_SP_RESOURCE_KVD_LINEAR,52 MLXSW_SP_RESOURCE_KVD_LINEAR,
53 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,53 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
54 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,54 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index c50fce4..b6a1056 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -211,7 +211,7 @@ static const struct nfp_devlink_versions {
211 enum nfp_nsp_versions id;211 enum nfp_nsp_versions id;
212 const char *key;212 const char *key;
213} nfp_devlink_versions_nsp[] = {213} nfp_devlink_versions_nsp[] = {
214 { NFP_VERSIONS_BUNDLE, "fw.bundle_id", },214 { NFP_VERSIONS_BUNDLE, DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, },
215 { NFP_VERSIONS_BSP, DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, },215 { NFP_VERSIONS_BSP, DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, },
216 { NFP_VERSIONS_CPLD, "fw.cpld", },216 { NFP_VERSIONS_CPLD, "fw.cpld", },
217 { NFP_VERSIONS_APP, DEVLINK_INFO_VERSION_GENERIC_FW_APP, },217 { NFP_VERSIONS_APP, DEVLINK_INFO_VERSION_GENERIC_FW_APP, },
@@ -353,6 +353,7 @@ const struct devlink_ops nfp_devlink_ops = {
353353
354int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)354int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
355{355{
356 struct devlink_port_attrs attrs = {};
356 struct nfp_eth_table_port eth_port;357 struct nfp_eth_table_port eth_port;
357 struct devlink *devlink;358 struct devlink *devlink;
358 const u8 *serial;359 const u8 *serial;
@@ -365,10 +366,15 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
365 if (ret)366 if (ret)
366 return ret;367 return ret;
367368
369 attrs.split = eth_port.is_split;
370 attrs.splittable = !attrs.split;
371 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
372 attrs.phys.port_number = eth_port.label_port;
373 attrs.phys.split_subport_number = eth_port.label_subport;
368 serial_len = nfp_cpp_serial(port->app->cpp, &serial);374 serial_len = nfp_cpp_serial(port->app->cpp, &serial);
369 devlink_port_attrs_set(&port->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,375 memcpy(attrs.switch_id.id, serial, serial_len);
370 eth_port.label_port, eth_port.is_split,376 attrs.switch_id.id_len = serial_len;
371 eth_port.label_subport, serial, serial_len);377 devlink_port_attrs_set(&port->dl_port, &attrs);
372378
373 devlink = priv_to_devlink(app->pf);379 devlink = priv_to_devlink(app->pf);
374380
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
index af1647a..6a6feb0 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c
@@ -70,6 +70,7 @@ void ionic_devlink_free(struct ionic *ionic)
70int ionic_devlink_register(struct ionic *ionic)70int ionic_devlink_register(struct ionic *ionic)
71{71{
72 struct devlink *dl = priv_to_devlink(ionic);72 struct devlink *dl = priv_to_devlink(ionic);
73 struct devlink_port_attrs attrs = {};
73 int err;74 int err;
7475
75 err = devlink_register(dl, ionic->dev);76 err = devlink_register(dl, ionic->dev);
@@ -78,8 +79,8 @@ int ionic_devlink_register(struct ionic *ionic)
78 return err;79 return err;
79 }80 }
8081
81 devlink_port_attrs_set(&ionic->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,82 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
82 0, false, 0, NULL, 0);83 devlink_port_attrs_set(&ionic->dl_port, &attrs);
83 err = devlink_port_register(dl, &ionic->dl_port, 0);84 err = devlink_port_register(dl, &ionic->dl_port, 0);
84 if (err)85 if (err)
85 dev_err(ionic->dev, "devlink_port_register failed: %d\n", err);86 dev_err(ionic->dev, "devlink_port_register failed: %d\n", err);
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 91b302f..218b4bc 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -43,19 +43,27 @@ static ssize_t nsim_dev_take_snapshot_write(struct file *file,
43 size_t count, loff_t *ppos)43 size_t count, loff_t *ppos)
44{44{
45 struct nsim_dev *nsim_dev = file->private_data;45 struct nsim_dev *nsim_dev = file->private_data;
46 struct devlink *devlink;
46 void *dummy_data;47 void *dummy_data;
47 int err;48 int err;
48 u32 id;49 u32 id;
4950
51 devlink = priv_to_devlink(nsim_dev);
52
50 dummy_data = kmalloc(NSIM_DEV_DUMMY_REGION_SIZE, GFP_KERNEL);53 dummy_data = kmalloc(NSIM_DEV_DUMMY_REGION_SIZE, GFP_KERNEL);
51 if (!dummy_data)54 if (!dummy_data)
52 return -ENOMEM;55 return -ENOMEM;
5356
54 get_random_bytes(dummy_data, NSIM_DEV_DUMMY_REGION_SIZE);57 get_random_bytes(dummy_data, NSIM_DEV_DUMMY_REGION_SIZE);
5558
56 id = devlink_region_shapshot_id_get(priv_to_devlink(nsim_dev));59 err = devlink_region_snapshot_id_get(devlink, &id);
60 if (err) {
61 pr_err("Failed to get snapshot id\n");
62 return err;
63 }
57 err = devlink_region_snapshot_create(nsim_dev->dummy_region,64 err = devlink_region_snapshot_create(nsim_dev->dummy_region,
58 dummy_data, id, kfree);65 dummy_data, id);
66 devlink_region_snapshot_id_put(devlink, id);
59 if (err) {67 if (err) {
60 pr_err("Failed to create region snapshot\n");68 pr_err("Failed to create region snapshot\n");
61 kfree(dummy_data);69 kfree(dummy_data);
@@ -293,11 +301,16 @@ static void nsim_devlink_param_load_driverinit_values(struct devlink *devlink)
293301
294#define NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX 16302#define NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX 16
295303
304static const struct devlink_region_ops dummy_region_ops = {
305 .name = "dummy",
306 .destructor = &kfree,
307};
308
296static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev,309static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev,
297 struct devlink *devlink)310 struct devlink *devlink)
298{311{
299 nsim_dev->dummy_region =312 nsim_dev->dummy_region =
300 devlink_region_create(devlink, "dummy",313 devlink_region_create(devlink, &dummy_region_ops,
301 NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX,314 NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX,
302 NSIM_DEV_DUMMY_REGION_SIZE);315 NSIM_DEV_DUMMY_REGION_SIZE);
303 return PTR_ERR_OR_ZERO(nsim_dev->dummy_region);316 return PTR_ERR_OR_ZERO(nsim_dev->dummy_region);
@@ -321,7 +334,7 @@ struct nsim_trap_data {
321};334};
322335
323/* All driver-specific traps must be documented in336/* All driver-specific traps must be documented in
324 * Documentation/networking/devlink-trap-netdevsim.rst337 * Documentation/networking/devlink/devlink-trap-netdevsim.rst
325 */338 */
326enum {339enum {
327 NSIM_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,340 NSIM_TRAP_ID_BASE = DEVLINK_TRAP_GENERIC_ID_MAX,
@@ -433,7 +446,7 @@ static void nsim_dev_trap_report(struct nsim_dev_port *nsim_dev_port)
433 */446 */
434 local_bh_disable();447 local_bh_disable();
435 devlink_trap_report(devlink, skb, nsim_trap_item->trap_ctx,448 devlink_trap_report(devlink, skb, nsim_trap_item->trap_ctx,
436 &nsim_dev_port->devlink_port);449 &nsim_dev_port->devlink_port, NULL);
437 local_bh_enable();450 local_bh_enable();
438 consume_skb(skb);451 consume_skb(skb);
439 }452 }
@@ -749,6 +762,7 @@ static void nsim_dev_destroy(struct nsim_dev *nsim_dev)
749static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,762static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
750 unsigned int port_index)763 unsigned int port_index)
751{764{
765 struct devlink_port_attrs attrs = {};
752 struct nsim_dev_port *nsim_dev_port;766 struct nsim_dev_port *nsim_dev_port;
753 struct devlink_port *devlink_port;767 struct devlink_port *devlink_port;
754 int err;768 int err;
@@ -759,10 +773,11 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
759 nsim_dev_port->port_index = port_index;773 nsim_dev_port->port_index = port_index;
760774
761 devlink_port = &nsim_dev_port->devlink_port;775 devlink_port = &nsim_dev_port->devlink_port;
762 devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,776 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
763 port_index + 1, 0, 0,777 attrs.phys.port_number = port_index + 1;
764 nsim_dev->switch_id.id,778 memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
765 nsim_dev->switch_id.id_len);779 attrs.switch_id.id_len = nsim_dev->switch_id.id_len;
780 devlink_port_attrs_set(devlink_port, &attrs);
766 err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,781 err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
767 port_index);782 port_index);
768 if (err)783 if (err)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index ac3ad16..08f4c61 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -16,28 +16,44 @@
16#include <linux/workqueue.h>16#include <linux/workqueue.h>
17#include <linux/refcount.h>17#include <linux/refcount.h>
18#include <net/net_namespace.h>18#include <net/net_namespace.h>
19#include <net/flow_offload.h>
19#include <uapi/linux/devlink.h>20#include <uapi/linux/devlink.h>
21#include <linux/xarray.h>
22#include <linux/firmware.h>
23
24#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
25 (__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
26
27struct devlink_dev_stats {
28 u32 reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
29 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
30};
2031
21struct devlink_ops;32struct devlink_ops;
2233
23struct devlink {34struct devlink {
24 struct list_head list;35 struct list_head list;
25 struct list_head port_list;36 struct list_head port_list;
37 struct list_head rate_list;
26 struct list_head sb_list;38 struct list_head sb_list;
27 struct list_head dpipe_table_list;39 struct list_head dpipe_table_list;
28 struct list_head resource_list;40 struct list_head resource_list;
29 struct list_head param_list;41 struct list_head param_list;
30 struct list_head region_list;42 struct list_head region_list;
31 u32 snapshot_id;
32 struct list_head reporter_list;43 struct list_head reporter_list;
33 struct mutex reporters_lock; /* protects reporter_list */44 struct mutex reporters_lock; /* protects reporter_list */
34 struct devlink_dpipe_headers *dpipe_headers;45 struct devlink_dpipe_headers *dpipe_headers;
35 struct list_head trap_list;46 struct list_head trap_list;
36 struct list_head trap_group_list;47 struct list_head trap_group_list;
48 struct list_head trap_policer_list;
37 const struct devlink_ops *ops;49 const struct devlink_ops *ops;
50 struct xarray snapshot_ids;
51 struct devlink_dev_stats stats;
38 struct device *dev;52 struct device *dev;
39 possible_net_t _net;53 possible_net_t _net;
40 struct mutex lock;54 struct mutex lock; /* Serializes access to devlink instance specific objects such as
55 * port, sb, dpipe, resource, params, region, traps and more.
56 */
41 u8 reload_failed:1,57 u8 reload_failed:1,
42 reload_enabled:1;58 reload_enabled:1;
43 char priv[0] __aligned(NETDEV_ALIGN);59 char priv[0] __aligned(NETDEV_ALIGN);
@@ -48,37 +64,99 @@ struct devlink_port_phys_attrs {
48 * A physical port which is visible to the user64 * A physical port which is visible to the user
49 * for a given port flavour.65 * for a given port flavour.
50 */66 */
51 u32 split_subport_number;67 u32 split_subport_number; /* If the port is split, this is the number of subport. */
52};68};
5369
70/**
71 * struct devlink_port_pci_pf_attrs - devlink port's PCI PF attributes
72 * @controller: Associated controller number
73 * @pf: Associated PCI PF number for this port.
74 * @external: when set, indicates if a port is for an external controller
75 */
54struct devlink_port_pci_pf_attrs {76struct devlink_port_pci_pf_attrs {
55 u16 pf; /* Associated PCI PF for this port. */77 u32 controller;
78 u16 pf;
79 u8 external:1;
56};80};
5781
82/**
83 * struct devlink_port_pci_vf_attrs - devlink port's PCI VF attributes
84 * @controller: Associated controller number
85 * @pf: Associated PCI PF number for this port.
86 * @vf: Associated PCI VF for of the PCI PF for this port.
87 * @external: when set, indicates if a port is for an external controller
88 */
58struct devlink_port_pci_vf_attrs {89struct devlink_port_pci_vf_attrs {
59 u16 pf; /* Associated PCI PF for this port. */90 u32 controller;
60 u16 vf; /* Associated PCI VF for of the PCI PF for this port. */91 u16 pf;
92 u16 vf;
93 u8 external:1;
94};
95
96/**
97 * struct devlink_port_pci_sf_attrs - devlink port's PCI SF attributes
98 * @controller: Associated controller number
99 * @sf: Associated PCI SF for of the PCI PF for this port.
100 * @pf: Associated PCI PF number for this port.
101 * @external: when set, indicates if a port is for an external controller
102 */
103struct devlink_port_pci_sf_attrs {
104 u32 controller;
105 u32 sf;
106 u16 pf;
107 u8 external:1;
61};108};
62109
110/**
111 * struct devlink_port_attrs - devlink port object
112 * @flavour: flavour of the port
113 * @split: indicates if this is split port
114 * @splittable: indicates if the port can be split.
115 * @lanes: maximum number of lanes the port supports. 0 value is not passed to netlink.
116 * @switch_id: if the port is part of switch, this is buffer with ID, otherwise this is NULL
117 * @phys: physical port attributes
118 * @pci_pf: PCI PF port attributes
119 * @pci_vf: PCI VF port attributes
120 * @pci_sf: PCI SF port attributes
121 */
63struct devlink_port_attrs {122struct devlink_port_attrs {
64 u8 set:1,123 u8 split:1,
65 split:1,124 splittable:1;
66 switch_port:1;125 u32 lanes;
67 enum devlink_port_flavour flavour;126 enum devlink_port_flavour flavour;
68 struct netdev_phys_item_id switch_id;127 struct netdev_phys_item_id switch_id;
69 union {128 union {
70 struct devlink_port_phys_attrs phys;129 struct devlink_port_phys_attrs phys;
71 struct devlink_port_pci_pf_attrs pci_pf;130 struct devlink_port_pci_pf_attrs pci_pf;
72 struct devlink_port_pci_vf_attrs pci_vf;131 struct devlink_port_pci_vf_attrs pci_vf;
132 struct devlink_port_pci_sf_attrs pci_sf;
133 };
134};
135
136struct devlink_rate {
137 struct list_head list;
138 enum devlink_rate_type type;
139 struct devlink *devlink;
140 void *priv;
141 u64 tx_share;
142 u64 tx_max;
143
144 struct devlink_rate *parent;
145 union {
146 struct devlink_port *devlink_port;
147 struct {
148 char *name;
149 refcount_t refcnt;
150 };
73 };151 };
74};152};
75153
76struct devlink_port {154struct devlink_port {
77 struct list_head list;155 struct list_head list;
78 struct list_head param_list;156 struct list_head param_list;
157 struct list_head region_list;
79 struct devlink *devlink;158 struct devlink *devlink;
80 unsigned int index;159 unsigned int index;
81 bool registered;
82 spinlock_t type_lock; /* Protects type and type_dev160 spinlock_t type_lock; /* Protects type and type_dev
83 * pointer consistency.161 * pointer consistency.
84 */162 */
@@ -86,7 +164,24 @@ struct devlink_port {
86 enum devlink_port_type desired_type;164 enum devlink_port_type desired_type;
87 void *type_dev;165 void *type_dev;
88 struct devlink_port_attrs attrs;166 struct devlink_port_attrs attrs;
167 u8 attrs_set:1,
168 switch_port:1;
89 struct delayed_work type_warn_dw;169 struct delayed_work type_warn_dw;
170 struct list_head reporter_list;
171 struct mutex reporters_lock; /* Protects reporter_list */
172
173 struct devlink_rate *devlink_rate;
174};
175
176struct devlink_port_new_attrs {
177 enum devlink_port_flavour flavour;
178 unsigned int port_index;
179 u32 controller;
180 u32 sfnum;
181 u16 pfnum;
182 u8 port_index_valid:1,
183 controller_valid:1,
184 sfnum_valid:1;
90};185};
91186
92struct devlink_sb_pool_info {187struct devlink_sb_pool_info {
@@ -331,6 +426,8 @@ struct devlink_resource {
331426
332#define DEVLINK_RESOURCE_ID_PARENT_TOP 0427#define DEVLINK_RESOURCE_ID_PARENT_TOP 0
333428
429#define DEVLINK_RESOURCE_GENERIC_NAME_PORTS "physical_ports"
430
334#define __DEVLINK_PARAM_MAX_STRING_VALUE 32431#define __DEVLINK_PARAM_MAX_STRING_VALUE 32
335enum devlink_param_type {432enum devlink_param_type {
336 DEVLINK_PARAM_TYPE_U8,433 DEVLINK_PARAM_TYPE_U8,
@@ -354,6 +451,25 @@ struct devlink_param_gset_ctx {
354};451};
355452
356/**453/**
454 * struct devlink_flash_notify - devlink dev flash notify data
455 * @status_msg: current status string
456 * @component: firmware component being updated
457 * @done: amount of work completed of total amount
458 * @total: amount of work expected to be done
459 * @timeout: expected max timeout in seconds
460 *
461 * These are values to be given to userland to be displayed in order
462 * to show current activity in a firmware update process.
463 */
464struct devlink_flash_notify {
465 const char *status_msg;
466 const char *component;
467 unsigned long done;
468 unsigned long total;
469 unsigned long timeout;
470};
471
472/**
357 * struct devlink_param - devlink configuration parameter data473 * struct devlink_param - devlink configuration parameter data
358 * @name: name of the parameter474 * @name: name of the parameter
359 * @generic: indicates if the parameter is generic or driver specific475 * @generic: indicates if the parameter is generic or driver specific
@@ -402,6 +518,7 @@ enum devlink_param_generic_id {
402 DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,518 DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
403 DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,519 DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
404 DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,520 DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
521 DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
405522
406 /* add new param generic ids above here*/523 /* add new param generic ids above here*/
407 __DEVLINK_PARAM_GENERIC_ID_MAX,524 __DEVLINK_PARAM_GENERIC_ID_MAX,
@@ -439,6 +556,9 @@ enum devlink_param_generic_id {
439#define DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME "enable_roce"556#define DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME "enable_roce"
440#define DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE DEVLINK_PARAM_TYPE_BOOL557#define DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE DEVLINK_PARAM_TYPE_BOOL
441558
559#define DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME "enable_remote_dev_reset"
560#define DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE DEVLINK_PARAM_TYPE_BOOL
561
442#define DEVLINK_PARAM_GENERIC(_id, _cmodes, _get, _set, _validate) \562#define DEVLINK_PARAM_GENERIC(_id, _cmodes, _get, _set, _validate) \
443{ \563{ \
444 .id = DEVLINK_PARAM_GENERIC_ID_##_id, \564 .id = DEVLINK_PARAM_GENERIC_ID_##_id, \
@@ -478,17 +598,81 @@ enum devlink_param_generic_id {
478#define DEVLINK_INFO_VERSION_GENERIC_FW "fw"598#define DEVLINK_INFO_VERSION_GENERIC_FW "fw"
479/* Control processor FW version */599/* Control processor FW version */
480#define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT "fw.mgmt"600#define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT "fw.mgmt"
601/* FW interface specification version */
602#define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API "fw.mgmt.api"
481/* Data path microcode controlling high-speed packet processing */603/* Data path microcode controlling high-speed packet processing */
482#define DEVLINK_INFO_VERSION_GENERIC_FW_APP "fw.app"604#define DEVLINK_INFO_VERSION_GENERIC_FW_APP "fw.app"
483/* UNDI software version */605/* UNDI software version */
484#define DEVLINK_INFO_VERSION_GENERIC_FW_UNDI "fw.undi"606#define DEVLINK_INFO_VERSION_GENERIC_FW_UNDI "fw.undi"
485/* NCSI support/handler version */607/* NCSI support/handler version */
486#define DEVLINK_INFO_VERSION_GENERIC_FW_NCSI "fw.ncsi"608#define DEVLINK_INFO_VERSION_GENERIC_FW_NCSI "fw.ncsi"
609/* FW parameter set id */
610#define DEVLINK_INFO_VERSION_GENERIC_FW_PSID "fw.psid"
611/* RoCE FW version */
612#define DEVLINK_INFO_VERSION_GENERIC_FW_ROCE "fw.roce"
613/* Firmware bundle identifier */
614#define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID "fw.bundle_id"
615
616/**
617 * struct devlink_flash_update_params - Flash Update parameters
618 * @fw: pointer to the firmware data to update from
619 * @component: the flash component to update
620 *
621 * With the exception of fw, drivers must opt-in to parameters by
622 * setting the appropriate bit in the supported_flash_update_params field in
623 * their devlink_ops structure.
624 */
625struct devlink_flash_update_params {
626 const struct firmware *fw;
627 const char *component;
628 u32 overwrite_mask;
629};
630
631#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0)
632#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(1)
487633
488struct devlink_region;634struct devlink_region;
489struct devlink_info_req;635struct devlink_info_req;
490636
491typedef void devlink_snapshot_data_dest_t(const void *data);637/**
638 * struct devlink_region_ops - Region operations
639 * @name: region name
640 * @destructor: callback used to free snapshot memory when deleting
641 * @snapshot: callback to request an immediate snapshot. On success,
642 * the data variable must be updated to point to the snapshot data.
643 * The function will be called while the devlink instance lock is
644 * held.
645 * @priv: Pointer to driver private data for the region operation
646 */
647struct devlink_region_ops {
648 const char *name;
649 void (*destructor)(const void *data);
650 int (*snapshot)(struct devlink *devlink,
651 const struct devlink_region_ops *ops,
652 struct netlink_ext_ack *extack,
653 u8 **data);
654 void *priv;
655};
656
657/**
658 * struct devlink_port_region_ops - Region operations for a port
659 * @name: region name
660 * @destructor: callback used to free snapshot memory when deleting
661 * @snapshot: callback to request an immediate snapshot. On success,
662 * the data variable must be updated to point to the snapshot data.
663 * The function will be called while the devlink instance lock is
664 * held.
665 * @priv: Pointer to driver private data for the region operation
666 */
667struct devlink_port_region_ops {
668 const char *name;
669 void (*destructor)(const void *data);
670 int (*snapshot)(struct devlink_port *port,
671 const struct devlink_port_region_ops *ops,
672 struct netlink_ext_ack *extack,
673 u8 **data);
674 void *priv;
675};
492676
493struct devlink_fmsg;677struct devlink_fmsg;
494struct devlink_health_reporter;678struct devlink_health_reporter;
@@ -506,16 +690,60 @@ enum devlink_health_reporter_state {
506 * @dump: callback to dump an object690 * @dump: callback to dump an object
507 * if priv_ctx is NULL, run a full dump691 * if priv_ctx is NULL, run a full dump
508 * @diagnose: callback to diagnose the current status692 * @diagnose: callback to diagnose the current status
693 * @test: callback to trigger a test event
509 */694 */
510695
511struct devlink_health_reporter_ops {696struct devlink_health_reporter_ops {
512 char *name;697 char *name;
513 int (*recover)(struct devlink_health_reporter *reporter,698 int (*recover)(struct devlink_health_reporter *reporter,
514 void *priv_ctx);699 void *priv_ctx, struct netlink_ext_ack *extack);
515 int (*dump)(struct devlink_health_reporter *reporter,700 int (*dump)(struct devlink_health_reporter *reporter,
516 struct devlink_fmsg *fmsg, void *priv_ctx);701 struct devlink_fmsg *fmsg, void *priv_ctx,
702 struct netlink_ext_ack *extack);
517 int (*diagnose)(struct devlink_health_reporter *reporter,703 int (*diagnose)(struct devlink_health_reporter *reporter,
518 struct devlink_fmsg *fmsg);704 struct devlink_fmsg *fmsg,
705 struct netlink_ext_ack *extack);
706 int (*test)(struct devlink_health_reporter *reporter,
707 struct netlink_ext_ack *extack);
708};
709
710/**
711 * struct devlink_trap_metadata - Packet trap metadata.
712 * @trap_name: Trap name.
713 * @trap_group_name: Trap group name.
714 * @input_dev: Input netdevice.
715 * @fa_cookie: Flow action user cookie.
716 * @trap_type: Trap type.
717 */
718struct devlink_trap_metadata {
719 const char *trap_name;
720 const char *trap_group_name;
721 struct net_device *input_dev;
722 const struct flow_action_cookie *fa_cookie;
723 enum devlink_trap_type trap_type;
724};
725
726/**
727 * struct devlink_trap_policer - Immutable packet trap policer attributes.
728 * @id: Policer identifier.
729 * @init_rate: Initial rate in packets / sec.
730 * @init_burst: Initial burst size in packets.
731 * @max_rate: Maximum rate.
732 * @min_rate: Minimum rate.
733 * @max_burst: Maximum burst size.
734 * @min_burst: Minimum burst size.
735 *
736 * Describes immutable attributes of packet trap policers that drivers register
737 * with devlink.
738 */
739struct devlink_trap_policer {
740 u32 id;
741 u64 init_rate;
742 u64 init_burst;
743 u64 max_rate;
744 u64 min_rate;
745 u64 max_burst;
746 u64 min_burst;
519};747};
520748
521/**749/**
@@ -523,6 +751,7 @@ struct devlink_health_reporter_ops {
523 * @name: Trap group name.751 * @name: Trap group name.
524 * @id: Trap group identifier.752 * @id: Trap group identifier.
525 * @generic: Whether the trap group is generic or not.753 * @generic: Whether the trap group is generic or not.
754 * @init_policer_id: Initial policer identifier.
526 *755 *
527 * Describes immutable attributes of packet trap groups that drivers register756 * Describes immutable attributes of packet trap groups that drivers register
528 * with devlink.757 * with devlink.
@@ -531,9 +760,11 @@ struct devlink_trap_group {
531 const char *name;760 const char *name;
532 u16 id;761 u16 id;
533 bool generic;762 bool generic;
763 u32 init_policer_id;
534};764};
535765
536#define DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT BIT(0)766#define DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT BIT(0)
767#define DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE BIT(1)
537768
538/**769/**
539 * struct devlink_trap - Immutable packet trap attributes.770 * struct devlink_trap - Immutable packet trap attributes.
@@ -542,7 +773,7 @@ struct devlink_trap_group {
542 * @generic: Whether the trap is generic or not.773 * @generic: Whether the trap is generic or not.
543 * @id: Trap identifier.774 * @id: Trap identifier.
544 * @name: Trap name.775 * @name: Trap name.
545 * @group: Immutable packet trap group attributes.776 * @init_group_id: Initial group identifier.
546 * @metadata_cap: Metadata types that can be provided by the trap.777 * @metadata_cap: Metadata types that can be provided by the trap.
547 *778 *
548 * Describes immutable attributes of packet traps that drivers register with779 * Describes immutable attributes of packet traps that drivers register with
@@ -554,12 +785,12 @@ struct devlink_trap {
554 bool generic;785 bool generic;
555 u16 id;786 u16 id;
556 const char *name;787 const char *name;
557 struct devlink_trap_group group;788 u16 init_group_id;
558 u32 metadata_cap;789 u32 metadata_cap;
559};790};
560791
561/* All traps must be documented in792/* All traps must be documented in
562 * Documentation/networking/devlink-trap.rst793 * Documentation/networking/devlink/devlink-trap.rst
563 */794 */
564enum devlink_trap_generic_id {795enum devlink_trap_generic_id {
565 DEVLINK_TRAP_GENERIC_ID_SMAC_MC,796 DEVLINK_TRAP_GENERIC_ID_SMAC_MC,
@@ -571,6 +802,89 @@ enum devlink_trap_generic_id {
571 DEVLINK_TRAP_GENERIC_ID_BLACKHOLE_ROUTE,802 DEVLINK_TRAP_GENERIC_ID_BLACKHOLE_ROUTE,
572 DEVLINK_TRAP_GENERIC_ID_TTL_ERROR,803 DEVLINK_TRAP_GENERIC_ID_TTL_ERROR,
573 DEVLINK_TRAP_GENERIC_ID_TAIL_DROP,804 DEVLINK_TRAP_GENERIC_ID_TAIL_DROP,
805 DEVLINK_TRAP_GENERIC_ID_NON_IP_PACKET,
806 DEVLINK_TRAP_GENERIC_ID_UC_DIP_MC_DMAC,
807 DEVLINK_TRAP_GENERIC_ID_DIP_LB,
808 DEVLINK_TRAP_GENERIC_ID_SIP_MC,
809 DEVLINK_TRAP_GENERIC_ID_SIP_LB,
810 DEVLINK_TRAP_GENERIC_ID_CORRUPTED_IP_HDR,
811 DEVLINK_TRAP_GENERIC_ID_IPV4_SIP_BC,
812 DEVLINK_TRAP_GENERIC_ID_IPV6_MC_DIP_RESERVED_SCOPE,
813 DEVLINK_TRAP_GENERIC_ID_IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE,
814 DEVLINK_TRAP_GENERIC_ID_MTU_ERROR,
815 DEVLINK_TRAP_GENERIC_ID_UNRESOLVED_NEIGH,
816 DEVLINK_TRAP_GENERIC_ID_RPF,
817 DEVLINK_TRAP_GENERIC_ID_REJECT_ROUTE,
818 DEVLINK_TRAP_GENERIC_ID_IPV4_LPM_UNICAST_MISS,
819 DEVLINK_TRAP_GENERIC_ID_IPV6_LPM_UNICAST_MISS,
820 DEVLINK_TRAP_GENERIC_ID_NON_ROUTABLE,
821 DEVLINK_TRAP_GENERIC_ID_DECAP_ERROR,
822 DEVLINK_TRAP_GENERIC_ID_OVERLAY_SMAC_MC,
823 DEVLINK_TRAP_GENERIC_ID_INGRESS_FLOW_ACTION_DROP,
824 DEVLINK_TRAP_GENERIC_ID_EGRESS_FLOW_ACTION_DROP,
825 DEVLINK_TRAP_GENERIC_ID_STP,
826 DEVLINK_TRAP_GENERIC_ID_LACP,
827 DEVLINK_TRAP_GENERIC_ID_LLDP,
828 DEVLINK_TRAP_GENERIC_ID_IGMP_QUERY,
829 DEVLINK_TRAP_GENERIC_ID_IGMP_V1_REPORT,
830 DEVLINK_TRAP_GENERIC_ID_IGMP_V2_REPORT,
831 DEVLINK_TRAP_GENERIC_ID_IGMP_V3_REPORT,
832 DEVLINK_TRAP_GENERIC_ID_IGMP_V2_LEAVE,
833 DEVLINK_TRAP_GENERIC_ID_MLD_QUERY,
834 DEVLINK_TRAP_GENERIC_ID_MLD_V1_REPORT,
835 DEVLINK_TRAP_GENERIC_ID_MLD_V2_REPORT,
836 DEVLINK_TRAP_GENERIC_ID_MLD_V1_DONE,
837 DEVLINK_TRAP_GENERIC_ID_IPV4_DHCP,
838 DEVLINK_TRAP_GENERIC_ID_IPV6_DHCP,
839 DEVLINK_TRAP_GENERIC_ID_ARP_REQUEST,
840 DEVLINK_TRAP_GENERIC_ID_ARP_RESPONSE,
841 DEVLINK_TRAP_GENERIC_ID_ARP_OVERLAY,
842 DEVLINK_TRAP_GENERIC_ID_IPV6_NEIGH_SOLICIT,
843 DEVLINK_TRAP_GENERIC_ID_IPV6_NEIGH_ADVERT,
844 DEVLINK_TRAP_GENERIC_ID_IPV4_BFD,
845 DEVLINK_TRAP_GENERIC_ID_IPV6_BFD,
846 DEVLINK_TRAP_GENERIC_ID_IPV4_OSPF,
847 DEVLINK_TRAP_GENERIC_ID_IPV6_OSPF,
848 DEVLINK_TRAP_GENERIC_ID_IPV4_BGP,
849 DEVLINK_TRAP_GENERIC_ID_IPV6_BGP,
850 DEVLINK_TRAP_GENERIC_ID_IPV4_VRRP,
851 DEVLINK_TRAP_GENERIC_ID_IPV6_VRRP,
852 DEVLINK_TRAP_GENERIC_ID_IPV4_PIM,
853 DEVLINK_TRAP_GENERIC_ID_IPV6_PIM,
854 DEVLINK_TRAP_GENERIC_ID_UC_LB,
855 DEVLINK_TRAP_GENERIC_ID_LOCAL_ROUTE,
856 DEVLINK_TRAP_GENERIC_ID_EXTERNAL_ROUTE,
857 DEVLINK_TRAP_GENERIC_ID_IPV6_UC_DIP_LINK_LOCAL_SCOPE,
858 DEVLINK_TRAP_GENERIC_ID_IPV6_DIP_ALL_NODES,
859 DEVLINK_TRAP_GENERIC_ID_IPV6_DIP_ALL_ROUTERS,
860 DEVLINK_TRAP_GENERIC_ID_IPV6_ROUTER_SOLICIT,
861 DEVLINK_TRAP_GENERIC_ID_IPV6_ROUTER_ADVERT,
862 DEVLINK_TRAP_GENERIC_ID_IPV6_REDIRECT,
863 DEVLINK_TRAP_GENERIC_ID_IPV4_ROUTER_ALERT,
864 DEVLINK_TRAP_GENERIC_ID_IPV6_ROUTER_ALERT,
865 DEVLINK_TRAP_GENERIC_ID_PTP_EVENT,
866 DEVLINK_TRAP_GENERIC_ID_PTP_GENERAL,
867 DEVLINK_TRAP_GENERIC_ID_FLOW_ACTION_SAMPLE,
868 DEVLINK_TRAP_GENERIC_ID_FLOW_ACTION_TRAP,
869 DEVLINK_TRAP_GENERIC_ID_EARLY_DROP,
870 DEVLINK_TRAP_GENERIC_ID_VXLAN_PARSING,
871 DEVLINK_TRAP_GENERIC_ID_LLC_SNAP_PARSING,
872 DEVLINK_TRAP_GENERIC_ID_VLAN_PARSING,
873 DEVLINK_TRAP_GENERIC_ID_PPPOE_PPP_PARSING,
874 DEVLINK_TRAP_GENERIC_ID_MPLS_PARSING,
875 DEVLINK_TRAP_GENERIC_ID_ARP_PARSING,
876 DEVLINK_TRAP_GENERIC_ID_IP_1_PARSING,
877 DEVLINK_TRAP_GENERIC_ID_IP_N_PARSING,
878 DEVLINK_TRAP_GENERIC_ID_GRE_PARSING,
879 DEVLINK_TRAP_GENERIC_ID_UDP_PARSING,
880 DEVLINK_TRAP_GENERIC_ID_TCP_PARSING,
881 DEVLINK_TRAP_GENERIC_ID_IPSEC_PARSING,
882 DEVLINK_TRAP_GENERIC_ID_SCTP_PARSING,
883 DEVLINK_TRAP_GENERIC_ID_DCCP_PARSING,
884 DEVLINK_TRAP_GENERIC_ID_GTP_PARSING,
885 DEVLINK_TRAP_GENERIC_ID_ESP_PARSING,
886 DEVLINK_TRAP_GENERIC_ID_BLACKHOLE_NEXTHOP,
887 DEVLINK_TRAP_GENERIC_ID_DMAC_FILTER,
574888
575 /* Add new generic trap IDs above */889 /* Add new generic trap IDs above */
576 __DEVLINK_TRAP_GENERIC_ID_MAX,890 __DEVLINK_TRAP_GENERIC_ID_MAX,
@@ -578,12 +892,35 @@ enum devlink_trap_generic_id {
578};892};
579893
580/* All trap groups must be documented in894/* All trap groups must be documented in
581 * Documentation/networking/devlink-trap.rst895 * Documentation/networking/devlink/devlink-trap.rst
582 */896 */
583enum devlink_trap_group_generic_id {897enum devlink_trap_group_generic_id {
584 DEVLINK_TRAP_GROUP_GENERIC_ID_L2_DROPS,898 DEVLINK_TRAP_GROUP_GENERIC_ID_L2_DROPS,
585 DEVLINK_TRAP_GROUP_GENERIC_ID_L3_DROPS,899 DEVLINK_TRAP_GROUP_GENERIC_ID_L3_DROPS,
900 DEVLINK_TRAP_GROUP_GENERIC_ID_L3_EXCEPTIONS,
586 DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS,901 DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS,
902 DEVLINK_TRAP_GROUP_GENERIC_ID_TUNNEL_DROPS,
903 DEVLINK_TRAP_GROUP_GENERIC_ID_ACL_DROPS,
904 DEVLINK_TRAP_GROUP_GENERIC_ID_STP,
905 DEVLINK_TRAP_GROUP_GENERIC_ID_LACP,
906 DEVLINK_TRAP_GROUP_GENERIC_ID_LLDP,
907 DEVLINK_TRAP_GROUP_GENERIC_ID_MC_SNOOPING,
908 DEVLINK_TRAP_GROUP_GENERIC_ID_DHCP,
909 DEVLINK_TRAP_GROUP_GENERIC_ID_NEIGH_DISCOVERY,
910 DEVLINK_TRAP_GROUP_GENERIC_ID_BFD,
911 DEVLINK_TRAP_GROUP_GENERIC_ID_OSPF,
912 DEVLINK_TRAP_GROUP_GENERIC_ID_BGP,
913 DEVLINK_TRAP_GROUP_GENERIC_ID_VRRP,
914 DEVLINK_TRAP_GROUP_GENERIC_ID_PIM,
915 DEVLINK_TRAP_GROUP_GENERIC_ID_UC_LB,
916 DEVLINK_TRAP_GROUP_GENERIC_ID_LOCAL_DELIVERY,
917 DEVLINK_TRAP_GROUP_GENERIC_ID_EXTERNAL_DELIVERY,
918 DEVLINK_TRAP_GROUP_GENERIC_ID_IPV6,
919 DEVLINK_TRAP_GROUP_GENERIC_ID_PTP_EVENT,
920 DEVLINK_TRAP_GROUP_GENERIC_ID_PTP_GENERAL,
921 DEVLINK_TRAP_GROUP_GENERIC_ID_ACL_SAMPLE,
922 DEVLINK_TRAP_GROUP_GENERIC_ID_ACL_TRAP,
923 DEVLINK_TRAP_GROUP_GENERIC_ID_PARSER_ERROR_DROPS,
587924
588 /* Add new generic trap group IDs above */925 /* Add new generic trap group IDs above */
589 __DEVLINK_TRAP_GROUP_GENERIC_ID_MAX,926 __DEVLINK_TRAP_GROUP_GENERIC_ID_MAX,
@@ -609,26 +946,239 @@ enum devlink_trap_group_generic_id {
609 "ttl_value_is_too_small"946 "ttl_value_is_too_small"
610#define DEVLINK_TRAP_GENERIC_NAME_TAIL_DROP \947#define DEVLINK_TRAP_GENERIC_NAME_TAIL_DROP \
611 "tail_drop"948 "tail_drop"
949#define DEVLINK_TRAP_GENERIC_NAME_NON_IP_PACKET \
950 "non_ip"
951#define DEVLINK_TRAP_GENERIC_NAME_UC_DIP_MC_DMAC \
952 "uc_dip_over_mc_dmac"
953#define DEVLINK_TRAP_GENERIC_NAME_DIP_LB \
954 "dip_is_loopback_address"
955#define DEVLINK_TRAP_GENERIC_NAME_SIP_MC \
956 "sip_is_mc"
957#define DEVLINK_TRAP_GENERIC_NAME_SIP_LB \
958 "sip_is_loopback_address"
959#define DEVLINK_TRAP_GENERIC_NAME_CORRUPTED_IP_HDR \
960 "ip_header_corrupted"
961#define DEVLINK_TRAP_GENERIC_NAME_IPV4_SIP_BC \
962 "ipv4_sip_is_limited_bc"
963#define DEVLINK_TRAP_GENERIC_NAME_IPV6_MC_DIP_RESERVED_SCOPE \
964 "ipv6_mc_dip_reserved_scope"
965#define DEVLINK_TRAP_GENERIC_NAME_IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE \
966 "ipv6_mc_dip_interface_local_scope"
967#define DEVLINK_TRAP_GENERIC_NAME_MTU_ERROR \
968 "mtu_value_is_too_small"
969#define DEVLINK_TRAP_GENERIC_NAME_UNRESOLVED_NEIGH \
970 "unresolved_neigh"
971#define DEVLINK_TRAP_GENERIC_NAME_RPF \
972 "mc_reverse_path_forwarding"
973#define DEVLINK_TRAP_GENERIC_NAME_REJECT_ROUTE \
974 "reject_route"
975#define DEVLINK_TRAP_GENERIC_NAME_IPV4_LPM_UNICAST_MISS \
976 "ipv4_lpm_miss"
977#define DEVLINK_TRAP_GENERIC_NAME_IPV6_LPM_UNICAST_MISS \
978 "ipv6_lpm_miss"
979#define DEVLINK_TRAP_GENERIC_NAME_NON_ROUTABLE \
980 "non_routable_packet"
981#define DEVLINK_TRAP_GENERIC_NAME_DECAP_ERROR \
982 "decap_error"
983#define DEVLINK_TRAP_GENERIC_NAME_OVERLAY_SMAC_MC \
984 "overlay_smac_is_mc"
985#define DEVLINK_TRAP_GENERIC_NAME_INGRESS_FLOW_ACTION_DROP \
986 "ingress_flow_action_drop"
987#define DEVLINK_TRAP_GENERIC_NAME_EGRESS_FLOW_ACTION_DROP \
988 "egress_flow_action_drop"
989#define DEVLINK_TRAP_GENERIC_NAME_STP \
990 "stp"
991#define DEVLINK_TRAP_GENERIC_NAME_LACP \
992 "lacp"
993#define DEVLINK_TRAP_GENERIC_NAME_LLDP \
994 "lldp"
995#define DEVLINK_TRAP_GENERIC_NAME_IGMP_QUERY \
996 "igmp_query"
997#define DEVLINK_TRAP_GENERIC_NAME_IGMP_V1_REPORT \
998 "igmp_v1_report"
999#define DEVLINK_TRAP_GENERIC_NAME_IGMP_V2_REPORT \
1000 "igmp_v2_report"
1001#define DEVLINK_TRAP_GENERIC_NAME_IGMP_V3_REPORT \
1002 "igmp_v3_report"
1003#define DEVLINK_TRAP_GENERIC_NAME_IGMP_V2_LEAVE \
1004 "igmp_v2_leave"
1005#define DEVLINK_TRAP_GENERIC_NAME_MLD_QUERY \
1006 "mld_query"
1007#define DEVLINK_TRAP_GENERIC_NAME_MLD_V1_REPORT \
1008 "mld_v1_report"
1009#define DEVLINK_TRAP_GENERIC_NAME_MLD_V2_REPORT \
1010 "mld_v2_report"
1011#define DEVLINK_TRAP_GENERIC_NAME_MLD_V1_DONE \
1012 "mld_v1_done"
1013#define DEVLINK_TRAP_GENERIC_NAME_IPV4_DHCP \
1014 "ipv4_dhcp"
1015#define DEVLINK_TRAP_GENERIC_NAME_IPV6_DHCP \
1016 "ipv6_dhcp"
1017#define DEVLINK_TRAP_GENERIC_NAME_ARP_REQUEST \
1018 "arp_request"
1019#define DEVLINK_TRAP_GENERIC_NAME_ARP_RESPONSE \
1020 "arp_response"
1021#define DEVLINK_TRAP_GENERIC_NAME_ARP_OVERLAY \
1022 "arp_overlay"
1023#define DEVLINK_TRAP_GENERIC_NAME_IPV6_NEIGH_SOLICIT \
1024 "ipv6_neigh_solicit"
1025#define DEVLINK_TRAP_GENERIC_NAME_IPV6_NEIGH_ADVERT \
1026 "ipv6_neigh_advert"
1027#define DEVLINK_TRAP_GENERIC_NAME_IPV4_BFD \
1028 "ipv4_bfd"
1029#define DEVLINK_TRAP_GENERIC_NAME_IPV6_BFD \
1030 "ipv6_bfd"
1031#define DEVLINK_TRAP_GENERIC_NAME_IPV4_OSPF \
1032 "ipv4_ospf"
1033#define DEVLINK_TRAP_GENERIC_NAME_IPV6_OSPF \
1034 "ipv6_ospf"
1035#define DEVLINK_TRAP_GENERIC_NAME_IPV4_BGP \
1036 "ipv4_bgp"
1037#define DEVLINK_TRAP_GENERIC_NAME_IPV6_BGP \
1038 "ipv6_bgp"
1039#define DEVLINK_TRAP_GENERIC_NAME_IPV4_VRRP \
1040 "ipv4_vrrp"
1041#define DEVLINK_TRAP_GENERIC_NAME_IPV6_VRRP \
1042 "ipv6_vrrp"
1043#define DEVLINK_TRAP_GENERIC_NAME_IPV4_PIM \
1044 "ipv4_pim"
1045#define DEVLINK_TRAP_GENERIC_NAME_IPV6_PIM \
1046 "ipv6_pim"
1047#define DEVLINK_TRAP_GENERIC_NAME_UC_LB \
1048 "uc_loopback"
1049#define DEVLINK_TRAP_GENERIC_NAME_LOCAL_ROUTE \
1050 "local_route"
1051#define DEVLINK_TRAP_GENERIC_NAME_EXTERNAL_ROUTE \
1052 "external_route"
1053#define DEVLINK_TRAP_GENERIC_NAME_IPV6_UC_DIP_LINK_LOCAL_SCOPE \
1054 "ipv6_uc_dip_link_local_scope"
1055#define DEVLINK_TRAP_GENERIC_NAME_IPV6_DIP_ALL_NODES \
1056 "ipv6_dip_all_nodes"
1057#define DEVLINK_TRAP_GENERIC_NAME_IPV6_DIP_ALL_ROUTERS \
1058 "ipv6_dip_all_routers"
1059#define DEVLINK_TRAP_GENERIC_NAME_IPV6_ROUTER_SOLICIT \
1060 "ipv6_router_solicit"
1061#define DEVLINK_TRAP_GENERIC_NAME_IPV6_ROUTER_ADVERT \
1062 "ipv6_router_advert"
1063#define DEVLINK_TRAP_GENERIC_NAME_IPV6_REDIRECT \
1064 "ipv6_redirect"
1065#define DEVLINK_TRAP_GENERIC_NAME_IPV4_ROUTER_ALERT \
1066 "ipv4_router_alert"
1067#define DEVLINK_TRAP_GENERIC_NAME_IPV6_ROUTER_ALERT \
1068 "ipv6_router_alert"
1069#define DEVLINK_TRAP_GENERIC_NAME_PTP_EVENT \
1070 "ptp_event"
1071#define DEVLINK_TRAP_GENERIC_NAME_PTP_GENERAL \
1072 "ptp_general"
1073#define DEVLINK_TRAP_GENERIC_NAME_FLOW_ACTION_SAMPLE \
1074 "flow_action_sample"
1075#define DEVLINK_TRAP_GENERIC_NAME_FLOW_ACTION_TRAP \
1076 "flow_action_trap"
1077#define DEVLINK_TRAP_GENERIC_NAME_EARLY_DROP \
1078 "early_drop"
1079#define DEVLINK_TRAP_GENERIC_NAME_VXLAN_PARSING \
1080 "vxlan_parsing"
1081#define DEVLINK_TRAP_GENERIC_NAME_LLC_SNAP_PARSING \
1082 "llc_snap_parsing"
1083#define DEVLINK_TRAP_GENERIC_NAME_VLAN_PARSING \
1084 "vlan_parsing"
1085#define DEVLINK_TRAP_GENERIC_NAME_PPPOE_PPP_PARSING \
1086 "pppoe_ppp_parsing"
1087#define DEVLINK_TRAP_GENERIC_NAME_MPLS_PARSING \
1088 "mpls_parsing"
1089#define DEVLINK_TRAP_GENERIC_NAME_ARP_PARSING \
1090 "arp_parsing"
1091#define DEVLINK_TRAP_GENERIC_NAME_IP_1_PARSING \
1092 "ip_1_parsing"
1093#define DEVLINK_TRAP_GENERIC_NAME_IP_N_PARSING \
1094 "ip_n_parsing"
1095#define DEVLINK_TRAP_GENERIC_NAME_GRE_PARSING \
1096 "gre_parsing"
1097#define DEVLINK_TRAP_GENERIC_NAME_UDP_PARSING \
1098 "udp_parsing"
1099#define DEVLINK_TRAP_GENERIC_NAME_TCP_PARSING \
1100 "tcp_parsing"
1101#define DEVLINK_TRAP_GENERIC_NAME_IPSEC_PARSING \
1102 "ipsec_parsing"
1103#define DEVLINK_TRAP_GENERIC_NAME_SCTP_PARSING \
1104 "sctp_parsing"
1105#define DEVLINK_TRAP_GENERIC_NAME_DCCP_PARSING \
1106 "dccp_parsing"
1107#define DEVLINK_TRAP_GENERIC_NAME_GTP_PARSING \
1108 "gtp_parsing"
1109#define DEVLINK_TRAP_GENERIC_NAME_ESP_PARSING \
1110 "esp_parsing"
1111#define DEVLINK_TRAP_GENERIC_NAME_BLACKHOLE_NEXTHOP \
1112 "blackhole_nexthop"
1113#define DEVLINK_TRAP_GENERIC_NAME_DMAC_FILTER \
1114 "dmac_filter"
6121115
613#define DEVLINK_TRAP_GROUP_GENERIC_NAME_L2_DROPS \1116#define DEVLINK_TRAP_GROUP_GENERIC_NAME_L2_DROPS \
614 "l2_drops"1117 "l2_drops"
615#define DEVLINK_TRAP_GROUP_GENERIC_NAME_L3_DROPS \1118#define DEVLINK_TRAP_GROUP_GENERIC_NAME_L3_DROPS \
616 "l3_drops"1119 "l3_drops"
1120#define DEVLINK_TRAP_GROUP_GENERIC_NAME_L3_EXCEPTIONS \
1121 "l3_exceptions"
617#define DEVLINK_TRAP_GROUP_GENERIC_NAME_BUFFER_DROPS \1122#define DEVLINK_TRAP_GROUP_GENERIC_NAME_BUFFER_DROPS \
618 "buffer_drops"1123 "buffer_drops"
6191124#define DEVLINK_TRAP_GROUP_GENERIC_NAME_TUNNEL_DROPS \
620#define DEVLINK_TRAP_GENERIC(_type, _init_action, _id, _group, _metadata_cap) \1125 "tunnel_drops"
1126#define DEVLINK_TRAP_GROUP_GENERIC_NAME_ACL_DROPS \
1127 "acl_drops"
1128#define DEVLINK_TRAP_GROUP_GENERIC_NAME_STP \
1129 "stp"
1130#define DEVLINK_TRAP_GROUP_GENERIC_NAME_LACP \
1131 "lacp"
1132#define DEVLINK_TRAP_GROUP_GENERIC_NAME_LLDP \
1133 "lldp"
1134#define DEVLINK_TRAP_GROUP_GENERIC_NAME_MC_SNOOPING \
1135 "mc_snooping"
1136#define DEVLINK_TRAP_GROUP_GENERIC_NAME_DHCP \
1137 "dhcp"
1138#define DEVLINK_TRAP_GROUP_GENERIC_NAME_NEIGH_DISCOVERY \
1139 "neigh_discovery"
1140#define DEVLINK_TRAP_GROUP_GENERIC_NAME_BFD \
1141 "bfd"
1142#define DEVLINK_TRAP_GROUP_GENERIC_NAME_OSPF \
1143 "ospf"
1144#define DEVLINK_TRAP_GROUP_GENERIC_NAME_BGP \
1145 "bgp"
1146#define DEVLINK_TRAP_GROUP_GENERIC_NAME_VRRP \
1147 "vrrp"
1148#define DEVLINK_TRAP_GROUP_GENERIC_NAME_PIM \
1149 "pim"
1150#define DEVLINK_TRAP_GROUP_GENERIC_NAME_UC_LB \
1151 "uc_loopback"
1152#define DEVLINK_TRAP_GROUP_GENERIC_NAME_LOCAL_DELIVERY \
1153 "local_delivery"
1154#define DEVLINK_TRAP_GROUP_GENERIC_NAME_EXTERNAL_DELIVERY \
1155 "external_delivery"
1156#define DEVLINK_TRAP_GROUP_GENERIC_NAME_IPV6 \
1157 "ipv6"
1158#define DEVLINK_TRAP_GROUP_GENERIC_NAME_PTP_EVENT \
1159 "ptp_event"
1160#define DEVLINK_TRAP_GROUP_GENERIC_NAME_PTP_GENERAL \
1161 "ptp_general"
1162#define DEVLINK_TRAP_GROUP_GENERIC_NAME_ACL_SAMPLE \
1163 "acl_sample"
1164#define DEVLINK_TRAP_GROUP_GENERIC_NAME_ACL_TRAP \
1165 "acl_trap"
1166#define DEVLINK_TRAP_GROUP_GENERIC_NAME_PARSER_ERROR_DROPS \
1167 "parser_error_drops"
1168
1169#define DEVLINK_TRAP_GENERIC(_type, _init_action, _id, _group_id, \
1170 _metadata_cap) \
621 { \1171 { \
622 .type = DEVLINK_TRAP_TYPE_##_type, \1172 .type = DEVLINK_TRAP_TYPE_##_type, \
623 .init_action = DEVLINK_TRAP_ACTION_##_init_action, \1173 .init_action = DEVLINK_TRAP_ACTION_##_init_action, \
624 .generic = true, \1174 .generic = true, \
625 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \1175 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
626 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \1176 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
627 .group = _group, \1177 .init_group_id = _group_id, \
628 .metadata_cap = _metadata_cap, \1178 .metadata_cap = _metadata_cap, \
629 }1179 }
6301180
631#define DEVLINK_TRAP_DRIVER(_type, _init_action, _id, _name, _group, \1181#define DEVLINK_TRAP_DRIVER(_type, _init_action, _id, _name, _group_id, \
632 _metadata_cap) \1182 _metadata_cap) \
633 { \1183 { \
634 .type = DEVLINK_TRAP_TYPE_##_type, \1184 .type = DEVLINK_TRAP_TYPE_##_type, \
@@ -636,21 +1186,45 @@ enum devlink_trap_group_generic_id {
636 .generic = false, \1186 .generic = false, \
637 .id = _id, \1187 .id = _id, \
638 .name = _name, \1188 .name = _name, \
639 .group = _group, \1189 .init_group_id = _group_id, \
640 .metadata_cap = _metadata_cap, \1190 .metadata_cap = _metadata_cap, \
641 }1191 }
6421192
643#define DEVLINK_TRAP_GROUP_GENERIC(_id) \1193#define DEVLINK_TRAP_GROUP_GENERIC(_id, _policer_id) \
644 { \1194 { \
645 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \1195 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
646 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \1196 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
647 .generic = true, \1197 .generic = true, \
1198 .init_policer_id = _policer_id, \
1199 }
1200
1201#define DEVLINK_TRAP_POLICER(_id, _rate, _burst, _max_rate, _min_rate, \
1202 _max_burst, _min_burst) \
1203 { \
1204 .id = _id, \
1205 .init_rate = _rate, \
1206 .init_burst = _burst, \
1207 .max_rate = _max_rate, \
1208 .min_rate = _min_rate, \
1209 .max_burst = _max_burst, \
1210 .min_burst = _min_burst, \
648 }1211 }
6491212
650struct devlink_ops {1213struct devlink_ops {
651 int (*reload_down)(struct devlink *devlink,1214 /**
1215 * @supported_flash_update_params:
1216 * mask of parameters supported by the driver's .flash_update
1217 * implemementation.
1218 */
1219 u32 supported_flash_update_params;
1220 unsigned long reload_actions;
1221 unsigned long reload_limits;
1222 int (*reload_down)(struct devlink *devlink, bool netns_change,
1223 enum devlink_reload_action action,
1224 enum devlink_reload_limit limit,
652 struct netlink_ext_ack *extack);1225 struct netlink_ext_ack *extack);
653 int (*reload_up)(struct devlink *devlink,1226 int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action,
1227 enum devlink_reload_limit limit, u32 *actions_performed,
654 struct netlink_ext_ack *extack);1228 struct netlink_ext_ack *extack);
655 int (*port_type_set)(struct devlink_port *devlink_port,1229 int (*port_type_set)(struct devlink_port *devlink_port,
656 enum devlink_port_type port_type);1230 enum devlink_port_type port_type);
@@ -708,8 +1282,15 @@ struct devlink_ops {
708 struct netlink_ext_ack *extack);1282 struct netlink_ext_ack *extack);
709 int (*info_get)(struct devlink *devlink, struct devlink_info_req *req,1283 int (*info_get)(struct devlink *devlink, struct devlink_info_req *req,
710 struct netlink_ext_ack *extack);1284 struct netlink_ext_ack *extack);
711 int (*flash_update)(struct devlink *devlink, const char *file_name,1285 /**
712 const char *component,1286 * @flash_update: Device flash update function
1287 *
1288 * Used to perform a flash update for the device. The set of
1289 * parameters supported by the driver should be set in
1290 * supported_flash_update_params.
1291 */
1292 int (*flash_update)(struct devlink *devlink,
1293 struct devlink_flash_update_params *params,
713 struct netlink_ext_ack *extack);1294 struct netlink_ext_ack *extack);
714 /**1295 /**
715 * @trap_init: Trap initialization function.1296 * @trap_init: Trap initialization function.
@@ -734,7 +1315,8 @@ struct devlink_ops {
734 */1315 */
735 int (*trap_action_set)(struct devlink *devlink,1316 int (*trap_action_set)(struct devlink *devlink,
736 const struct devlink_trap *trap,1317 const struct devlink_trap *trap,
737 enum devlink_trap_action action);1318 enum devlink_trap_action action,
1319 struct netlink_ext_ack *extack);
738 /**1320 /**
739 * @trap_group_init: Trap group initialization function.1321 * @trap_group_init: Trap group initialization function.
740 *1322 *
@@ -743,6 +1325,187 @@ struct devlink_ops {
743 */1325 */
744 int (*trap_group_init)(struct devlink *devlink,1326 int (*trap_group_init)(struct devlink *devlink,
745 const struct devlink_trap_group *group);1327 const struct devlink_trap_group *group);
1328 /**
1329 * @trap_group_set: Trap group parameters set function.
1330 *
1331 * Note: @policer can be NULL when a policer is being unbound from
1332 * @group.
1333 */
1334 int (*trap_group_set)(struct devlink *devlink,
1335 const struct devlink_trap_group *group,
1336 const struct devlink_trap_policer *policer,
1337 struct netlink_ext_ack *extack);
1338 /**
1339 * @trap_group_action_set: Trap group action set function.
1340 *
1341 * If this callback is populated, it will take precedence over looping
1342 * over all traps in a group and calling .trap_action_set().
1343 */
1344 int (*trap_group_action_set)(struct devlink *devlink,
1345 const struct devlink_trap_group *group,
1346 enum devlink_trap_action action,
1347 struct netlink_ext_ack *extack);
1348 /**
1349 * @trap_drop_counter_get: Trap drop counter get function.
1350 *
1351 * Should be used by device drivers to report number of packets
1352 * that have been dropped, and cannot be passed to the devlink
1353 * subsystem by the underlying device.
1354 */
1355 int (*trap_drop_counter_get)(struct devlink *devlink,
1356 const struct devlink_trap *trap,
1357 u64 *p_drops);
1358 /**
1359 * @trap_policer_init: Trap policer initialization function.
1360 *
1361 * Should be used by device drivers to initialize the trap policer in
1362 * the underlying device.
1363 */
1364 int (*trap_policer_init)(struct devlink *devlink,
1365 const struct devlink_trap_policer *policer);
1366 /**
1367 * @trap_policer_fini: Trap policer de-initialization function.
1368 *
1369 * Should be used by device drivers to de-initialize the trap policer
1370 * in the underlying device.
1371 */
1372 void (*trap_policer_fini)(struct devlink *devlink,
1373 const struct devlink_trap_policer *policer);
1374 /**
1375 * @trap_policer_set: Trap policer parameters set function.
1376 */
1377 int (*trap_policer_set)(struct devlink *devlink,
1378 const struct devlink_trap_policer *policer,
1379 u64 rate, u64 burst,
1380 struct netlink_ext_ack *extack);
1381 /**
1382 * @trap_policer_counter_get: Trap policer counter get function.
1383 *
1384 * Should be used by device drivers to report number of packets dropped
1385 * by the policer.
1386 */
1387 int (*trap_policer_counter_get)(struct devlink *devlink,
1388 const struct devlink_trap_policer *policer,
1389 u64 *p_drops);
1390 /**
1391 * @port_function_hw_addr_get: Port function's hardware address get function.
1392 *
1393 * Should be used by device drivers to report the hardware address of a function managed
1394 * by the devlink port. Driver should return -EOPNOTSUPP if it doesn't support port
1395 * function handling for a particular port.
1396 *
1397 * Note: @extack can be NULL when port notifier queries the port function.
1398 */
1399 int (*port_function_hw_addr_get)(struct devlink *devlink, struct devlink_port *port,
1400 u8 *hw_addr, int *hw_addr_len,
1401 struct netlink_ext_ack *extack);
1402 /**
1403 * @port_function_hw_addr_set: Port function's hardware address set function.
1404 *
1405 * Should be used by device drivers to set the hardware address of a function managed
1406 * by the devlink port. Driver should return -EOPNOTSUPP if it doesn't support port
1407 * function handling for a particular port.
1408 */
1409 int (*port_function_hw_addr_set)(struct devlink *devlink, struct devlink_port *port,
1410 const u8 *hw_addr, int hw_addr_len,
1411 struct netlink_ext_ack *extack);
1412 /**
1413 * port_new() - Add a new port function of a specified flavor
1414 * @devlink: Devlink instance
1415 * @attrs: attributes of the new port
1416 * @extack: extack for reporting error messages
1417 * @new_port_index: index of the new port
1418 *
1419 * Devlink core will call this device driver function upon user request
1420 * to create a new port function of a specified flavor and optional
1421 * attributes
1422 *
1423 * Notes:
1424 * - Called without devlink instance lock being held. Drivers must
1425 * implement own means of synchronization
1426 * - On success, drivers must register a port with devlink core
1427 *
1428 * Return: 0 on success, negative value otherwise.
1429 */
1430 int (*port_new)(struct devlink *devlink,
1431 const struct devlink_port_new_attrs *attrs,
1432 struct netlink_ext_ack *extack,
1433 unsigned int *new_port_index);
1434 /**
1435 * port_del() - Delete a port function
1436 * @devlink: Devlink instance
1437 * @port_index: port function index to delete
1438 * @extack: extack for reporting error messages
1439 *
1440 * Devlink core will call this device driver function upon user request
1441 * to delete a previously created port function
1442 *
1443 * Notes:
1444 * - Called without devlink instance lock being held. Drivers must
1445 * implement own means of synchronization
1446 * - On success, drivers must unregister the corresponding devlink
1447 * port
1448 *
1449 * Return: 0 on success, negative value otherwise.
1450 */
1451 int (*port_del)(struct devlink *devlink, unsigned int port_index,
1452 struct netlink_ext_ack *extack);
1453 /**
1454 * port_fn_state_get() - Get the state of a port function
1455 * @devlink: Devlink instance
1456 * @port: The devlink port
1457 * @state: Admin configured state
1458 * @opstate: Current operational state
1459 * @extack: extack for reporting error messages
1460 *
1461 * Reports the admin and operational state of a devlink port function
1462 *
1463 * Return: 0 on success, negative value otherwise.
1464 */
1465 int (*port_fn_state_get)(struct devlink *devlink,
1466 struct devlink_port *port,
1467 enum devlink_port_fn_state *state,
1468 enum devlink_port_fn_opstate *opstate,
1469 struct netlink_ext_ack *extack);
1470 /**
1471 * port_fn_state_set() - Set the admin state of a port function
1472 * @devlink: Devlink instance
1473 * @port: The devlink port
1474 * @state: Admin state
1475 * @extack: extack for reporting error messages
1476 *
1477 * Set the admin state of a devlink port function
1478 *
1479 * Return: 0 on success, negative value otherwise.
1480 */
1481 int (*port_fn_state_set)(struct devlink *devlink,
1482 struct devlink_port *port,
1483 enum devlink_port_fn_state state,
1484 struct netlink_ext_ack *extack);
1485
1486 /**
1487 * Rate control callbacks.
1488 */
1489 int (*rate_leaf_tx_share_set)(struct devlink_rate *devlink_rate, void *priv,
1490 u64 tx_share, struct netlink_ext_ack *extack);
1491 int (*rate_leaf_tx_max_set)(struct devlink_rate *devlink_rate, void *priv,
1492 u64 tx_max, struct netlink_ext_ack *extack);
1493 int (*rate_node_tx_share_set)(struct devlink_rate *devlink_rate, void *priv,
1494 u64 tx_share, struct netlink_ext_ack *extack);
1495 int (*rate_node_tx_max_set)(struct devlink_rate *devlink_rate, void *priv,
1496 u64 tx_max, struct netlink_ext_ack *extack);
1497 int (*rate_node_new)(struct devlink_rate *rate_node, void **priv,
1498 struct netlink_ext_ack *extack);
1499 int (*rate_node_del)(struct devlink_rate *rate_node, void *priv,
1500 struct netlink_ext_ack *extack);
1501 int (*rate_leaf_parent_set)(struct devlink_rate *child,
1502 struct devlink_rate *parent,
1503 void *priv_child, void *priv_parent,
1504 struct netlink_ext_ack *extack);
1505 int (*rate_node_parent_set)(struct devlink_rate *child,
1506 struct devlink_rate *parent,
1507 void *priv_child, void *priv_parent,
1508 struct netlink_ext_ack *extack);
746};1509};
7471510
748static inline void *devlink_priv(struct devlink *devlink)1511static inline void *devlink_priv(struct devlink *devlink)
@@ -776,7 +1539,19 @@ static inline struct devlink *netdev_to_devlink(struct net_device *dev)
7761539
777struct ib_device;1540struct ib_device;
7781541
779struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size);1542struct net *devlink_net(const struct devlink *devlink);
1543/* This call is intended for software devices that can create
1544 * devlink instances in other namespaces than init_net.
1545 *
1546 * Drivers that operate on real HW must use devlink_alloc() instead.
1547 */
1548struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
1549 size_t priv_size, struct net *net);
1550static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
1551 size_t priv_size)
1552{
1553 return devlink_alloc_ns(ops, priv_size, &init_net);
1554}
780int devlink_register(struct devlink *devlink, struct device *dev);1555int devlink_register(struct devlink *devlink, struct device *dev);
781void devlink_unregister(struct devlink *devlink);1556void devlink_unregister(struct devlink *devlink);
782void devlink_reload_enable(struct devlink *devlink);1557void devlink_reload_enable(struct devlink *devlink);
@@ -792,18 +1567,17 @@ void devlink_port_type_ib_set(struct devlink_port *devlink_port,
792 struct ib_device *ibdev);1567 struct ib_device *ibdev);
793void devlink_port_type_clear(struct devlink_port *devlink_port);1568void devlink_port_type_clear(struct devlink_port *devlink_port);
794void devlink_port_attrs_set(struct devlink_port *devlink_port,1569void devlink_port_attrs_set(struct devlink_port *devlink_port,
795 enum devlink_port_flavour flavour,1570 struct devlink_port_attrs *devlink_port_attrs);
796 u32 port_number, bool split,1571void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
797 u32 split_subport_number,1572 u16 pf, bool external);
798 const unsigned char *switch_id,1573void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
799 unsigned char switch_id_len);1574 u16 pf, u16 vf, bool external);
800void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port,1575void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port,
801 const unsigned char *switch_id,1576 u32 controller, u16 pf, u32 sf,
802 unsigned char switch_id_len, u16 pf);1577 bool external);
803void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port,1578int devlink_rate_leaf_create(struct devlink_port *port, void *priv);
804 const unsigned char *switch_id,1579void devlink_rate_leaf_destroy(struct devlink_port *devlink_port);
805 unsigned char switch_id_len,1580void devlink_rate_nodes_destroy(struct devlink *devlink);
806 u16 pf, u16 vf);
807int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,1581int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
808 u32 size, u16 ingress_pools_count,1582 u32 size, u16 ingress_pools_count,
809 u16 egress_pools_count, u16 ingress_tc_count,1583 u16 egress_pools_count, u16 ingress_tc_count,
@@ -883,19 +1657,27 @@ void devlink_port_param_value_changed(struct devlink_port *devlink_port,
883 u32 param_id);1657 u32 param_id);
884void devlink_param_value_str_fill(union devlink_param_value *dst_val,1658void devlink_param_value_str_fill(union devlink_param_value *dst_val,
885 const char *src);1659 const char *src);
886struct devlink_region *devlink_region_create(struct devlink *devlink,1660struct devlink_region *
887 const char *region_name,1661devlink_region_create(struct devlink *devlink,
888 u32 region_max_snapshots,1662 const struct devlink_region_ops *ops,
889 u64 region_size);1663 u32 region_max_snapshots, u64 region_size);
1664struct devlink_region *
1665devlink_port_region_create(struct devlink_port *port,
1666 const struct devlink_port_region_ops *ops,
1667 u32 region_max_snapshots, u64 region_size);
890void devlink_region_destroy(struct devlink_region *region);1668void devlink_region_destroy(struct devlink_region *region);
891u32 devlink_region_shapshot_id_get(struct devlink *devlink);1669void devlink_port_region_destroy(struct devlink_region *region);
1670
1671int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id);
1672void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id);
892int devlink_region_snapshot_create(struct devlink_region *region,1673int devlink_region_snapshot_create(struct devlink_region *region,
893 u8 *data, u32 snapshot_id,1674 u8 *data, u32 snapshot_id);
894 devlink_snapshot_data_dest_t *data_destructor);
895int devlink_info_serial_number_put(struct devlink_info_req *req,1675int devlink_info_serial_number_put(struct devlink_info_req *req,
896 const char *sn);1676 const char *sn);
897int devlink_info_driver_name_put(struct devlink_info_req *req,1677int devlink_info_driver_name_put(struct devlink_info_req *req,
898 const char *name);1678 const char *name);
1679int devlink_info_board_serial_number_put(struct devlink_info_req *req,
1680 const char *bsn);
899int devlink_info_version_fixed_put(struct devlink_info_req *req,1681int devlink_info_version_fixed_put(struct devlink_info_req *req,
900 const char *version_name,1682 const char *version_name,
901 const char *version_value);1683 const char *version_value);
@@ -915,6 +1697,9 @@ int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg);
915int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,1697int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
916 const char *name);1698 const char *name);
917int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg);1699int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg);
1700int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
1701 const char *name);
1702int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg);
9181703
919int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value);1704int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value);
920int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value);1705int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value);
@@ -935,16 +1720,24 @@ int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
935int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,1720int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
936 const char *value);1721 const char *value);
937int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,1722int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
938 const void *value, u16 value_len);1723 const void *value, u32 value_len);
9391724
940struct devlink_health_reporter *1725struct devlink_health_reporter *
941devlink_health_reporter_create(struct devlink *devlink,1726devlink_health_reporter_create(struct devlink *devlink,
942 const struct devlink_health_reporter_ops *ops,1727 const struct devlink_health_reporter_ops *ops,
943 u64 graceful_period, bool auto_recover,1728 u64 graceful_period, void *priv);
944 void *priv);1729
1730struct devlink_health_reporter *
1731devlink_port_health_reporter_create(struct devlink_port *port,
1732 const struct devlink_health_reporter_ops *ops,
1733 u64 graceful_period, void *priv);
1734
945void1735void
946devlink_health_reporter_destroy(struct devlink_health_reporter *reporter);1736devlink_health_reporter_destroy(struct devlink_health_reporter *reporter);
9471737
1738void
1739devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter);
1740
948void *1741void *
949devlink_health_reporter_priv(struct devlink_health_reporter *reporter);1742devlink_health_reporter_priv(struct devlink_health_reporter *reporter);
950int devlink_health_report(struct devlink_health_reporter *reporter,1743int devlink_health_report(struct devlink_health_reporter *reporter,
@@ -952,16 +1745,23 @@ int devlink_health_report(struct devlink_health_reporter *reporter,
952void1745void
953devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,1746devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
954 enum devlink_health_reporter_state state);1747 enum devlink_health_reporter_state state);
1748void
1749devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter);
9551750
956bool devlink_is_reload_failed(const struct devlink *devlink);1751bool devlink_is_reload_failed(const struct devlink *devlink);
1752void devlink_remote_reload_actions_performed(struct devlink *devlink,
1753 enum devlink_reload_limit limit,
1754 u32 actions_performed);
9571755
958void devlink_flash_update_begin_notify(struct devlink *devlink);
959void devlink_flash_update_end_notify(struct devlink *devlink);
960void devlink_flash_update_status_notify(struct devlink *devlink,1756void devlink_flash_update_status_notify(struct devlink *devlink,
961 const char *status_msg,1757 const char *status_msg,
962 const char *component,1758 const char *component,
963 unsigned long done,1759 unsigned long done,
964 unsigned long total);1760 unsigned long total);
1761void devlink_flash_update_timeout_notify(struct devlink *devlink,
1762 const char *status_msg,
1763 const char *component,
1764 unsigned long timeout);
9651765
966int devlink_traps_register(struct devlink *devlink,1766int devlink_traps_register(struct devlink *devlink,
967 const struct devlink_trap *traps,1767 const struct devlink_trap *traps,
@@ -969,10 +1769,24 @@ int devlink_traps_register(struct devlink *devlink,
969void devlink_traps_unregister(struct devlink *devlink,1769void devlink_traps_unregister(struct devlink *devlink,
970 const struct devlink_trap *traps,1770 const struct devlink_trap *traps,
971 size_t traps_count);1771 size_t traps_count);
972void devlink_trap_report(struct devlink *devlink,1772void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
973 struct sk_buff *skb, void *trap_ctx,1773 void *trap_ctx, struct devlink_port *in_devlink_port,
974 struct devlink_port *in_devlink_port);1774 const struct flow_action_cookie *fa_cookie);
975void *devlink_trap_ctx_priv(void *trap_ctx);1775void *devlink_trap_ctx_priv(void *trap_ctx);
1776int devlink_trap_groups_register(struct devlink *devlink,
1777 const struct devlink_trap_group *groups,
1778 size_t groups_count);
1779void devlink_trap_groups_unregister(struct devlink *devlink,
1780 const struct devlink_trap_group *groups,
1781 size_t groups_count);
1782int
1783devlink_trap_policers_register(struct devlink *devlink,
1784 const struct devlink_trap_policer *policers,
1785 size_t policers_count);
1786void
1787devlink_trap_policers_unregister(struct devlink *devlink,
1788 const struct devlink_trap_policer *policers,
1789 size_t policers_count);
9761790
977#if IS_ENABLED(CONFIG_NET_DEVLINK)1791#if IS_ENABLED(CONFIG_NET_DEVLINK)
9781792
diff --git a/include/net/drop_monitor.h b/include/net/drop_monitor.h
979deleted file mode 1006441793deleted file mode 100644
index f68bc37..0000000
--- a/include/net/drop_monitor.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#ifndef _NET_DROP_MONITOR_H_
4#define _NET_DROP_MONITOR_H_
5
6#include <linux/ktime.h>
7#include <linux/netdevice.h>
8#include <linux/skbuff.h>
9
10/**
11 * struct net_dm_hw_metadata - Hardware-supplied packet metadata.
12 * @trap_group_name: Hardware trap group name.
13 * @trap_name: Hardware trap name.
14 * @input_dev: Input netdevice.
15 */
16struct net_dm_hw_metadata {
17 const char *trap_group_name;
18 const char *trap_name;
19 struct net_device *input_dev;
20};
21
22#if IS_REACHABLE(CONFIG_NET_DROP_MONITOR)
23void net_dm_hw_report(struct sk_buff *skb,
24 const struct net_dm_hw_metadata *hw_metadata);
25#else
26static inline void
27net_dm_hw_report(struct sk_buff *skb,
28 const struct net_dm_hw_metadata *hw_metadata)
29{
30}
31#endif
32
33#endif /* _NET_DROP_MONITOR_H_ */
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 2d9e67a..1f0f363 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -49,8 +49,11 @@ struct genl_family {
49 char name[GENL_NAMSIZ];49 char name[GENL_NAMSIZ];
50 unsigned int version;50 unsigned int version;
51 unsigned int maxattr;51 unsigned int maxattr;
52 bool netnsok;52 unsigned int mcgrp_offset; /* private */
53 bool parallel_ops;53 u8 netnsok:1;
54 u8 parallel_ops:1;
55 u8 n_ops;
56 u8 n_mcgrps;
54 const struct nla_policy *policy;57 const struct nla_policy *policy;
55 int (*pre_doit)(const struct genl_ops *ops,58 int (*pre_doit)(const struct genl_ops *ops,
56 struct sk_buff *skb,59 struct sk_buff *skb,
@@ -61,14 +64,9 @@ struct genl_family {
61 struct nlattr ** attrbuf; /* private */64 struct nlattr ** attrbuf; /* private */
62 const struct genl_ops * ops;65 const struct genl_ops * ops;
63 const struct genl_multicast_group *mcgrps;66 const struct genl_multicast_group *mcgrps;
64 unsigned int n_ops;
65 unsigned int n_mcgrps;
66 unsigned int mcgrp_offset; /* private */
67 struct module *module;67 struct module *module;
68};68};
6969
70struct nlattr **genl_family_attrbuf(const struct genl_family *family);
71
72/**70/**
73 * struct genl_info - receiving information71 * struct genl_info - receiving information
74 * @snd_seq: sending sequence number72 * @snd_seq: sending sequence number
@@ -120,6 +118,24 @@ enum genl_validate_flags {
120};118};
121119
122/**120/**
121 * struct genl_info - info that is available during dumpit op call
122 * @family: generic netlink family - for internal genl code usage
123 * @ops: generic netlink ops - for internal genl code usage
124 * @attrs: netlink attributes
125 */
126struct genl_dumpit_info {
127 const struct genl_family *family;
128 const struct genl_ops *ops;
129 struct nlattr **attrs;
130};
131
132static inline const struct genl_dumpit_info *
133genl_dumpit_info(struct netlink_callback *cb)
134{
135 return cb->data;
136}
137
138/**
123 * struct genl_ops - generic netlink operations139 * struct genl_ops - generic netlink operations
124 * @cmd: command identifier140 * @cmd: command identifier
125 * @internal_flags: flags used by the family141 * @internal_flags: flags used by the family
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 22dd99b..f91d2e3 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -219,7 +219,7 @@ enum nla_policy_validation {
219 * NLA_NESTED,219 * NLA_NESTED,
220 * NLA_NESTED_ARRAY Length verification is done by checking len of220 * NLA_NESTED_ARRAY Length verification is done by checking len of
221 * nested header (or empty); len field is used if221 * nested header (or empty); len field is used if
222 * validation_data is also used, for the max attr222 * nested_policy is also used, for the max attr
223 * number in the nested policy.223 * number in the nested policy.
224 * NLA_U8, NLA_U16,224 * NLA_U8, NLA_U16,
225 * NLA_U32, NLA_U64,225 * NLA_U32, NLA_U64,
@@ -237,27 +237,25 @@ enum nla_policy_validation {
237 * NLA_MIN_LEN Minimum length of attribute payload237 * NLA_MIN_LEN Minimum length of attribute payload
238 * All other Minimum length of attribute payload238 * All other Minimum length of attribute payload
239 *239 *
240 * Meaning of `validation_data' field:240 * Meaning of validation union:
241 * NLA_BITFIELD32 This is a 32-bit bitmap/bitselector attribute and241 * NLA_BITFIELD32 This is a 32-bit bitmap/bitselector attribute and
242 * validation data must point to a u32 value of valid242 * `bitfield32_valid' is the u32 value of valid flags
243 * flags243 * NLA_REJECT This attribute is always rejected and `reject_message'
244 * NLA_REJECT This attribute is always rejected and validation data
245 * may point to a string to report as the error instead244 * may point to a string to report as the error instead
246 * of the generic one in extended ACK.245 * of the generic one in extended ACK.
247 * NLA_NESTED Points to a nested policy to validate, must also set246 * NLA_NESTED `nested_policy' to a nested policy to validate, must
248 * `len' to the max attribute number.247 * also set `len' to the max attribute number. Use the
248 * provided NLA_POLICY_NESTED() macro.
249 * Note that nla_parse() will validate, but of course not249 * Note that nla_parse() will validate, but of course not
250 * parse, the nested sub-policies.250 * parse, the nested sub-policies.
251 * NLA_NESTED_ARRAY Points to a nested policy to validate, must also set251 * NLA_NESTED_ARRAY `nested_policy' points to a nested policy to validate,
252 * `len' to the max attribute number. The difference to252 * must also set `len' to the max attribute number. Use
253 * NLA_NESTED is the structure - NLA_NESTED has the253 * the provided NLA_POLICY_NESTED_ARRAY() macro.
254 * nested attributes directly inside, while an array has254 * The difference to NLA_NESTED is the structure:
255 * the nested attributes at another level down and the255 * NLA_NESTED has the nested attributes directly inside
256 * attributes directly in the nesting don't matter.256 * while an array has the nested attributes at another
257 * All other Unused - but note that it's a union257 * level down and the attribute types directly in the
258 *258 * nesting don't matter.
259 * Meaning of `min' and `max' fields, use via NLA_POLICY_MIN, NLA_POLICY_MAX
260 * and NLA_POLICY_RANGE:
261 * NLA_U8,259 * NLA_U8,
262 * NLA_U16,260 * NLA_U16,
263 * NLA_U32,261 * NLA_U32,
@@ -265,29 +263,31 @@ enum nla_policy_validation {
265 * NLA_S8,263 * NLA_S8,
266 * NLA_S16,264 * NLA_S16,
267 * NLA_S32,265 * NLA_S32,
268 * NLA_S64 These are used depending on the validation_type266 * NLA_S64 The `min' and `max' fields are used depending on the
269 * field, if that is min/max/range then the minimum,267 * validation_type field, if that is min/max/range then
270 * maximum and both are used (respectively) to check268 * the min, max or both are used (respectively) to check
271 * the value of the integer attribute.269 * the value of the integer attribute.
272 * Note that in the interest of code simplicity and270 * Note that in the interest of code simplicity and
273 * struct size both limits are s16, so you cannot271 * struct size both limits are s16, so you cannot
274 * enforce a range that doesn't fall within the range272 * enforce a range that doesn't fall within the range
275 * of s16 - do that as usual in the code instead.273 * of s16 - do that as usual in the code instead.
274 * Use the NLA_POLICY_MIN(), NLA_POLICY_MAX() and
275 * NLA_POLICY_RANGE() macros.
276 * All other Unused - but note that it's a union276 * All other Unused - but note that it's a union
277 *277 *
278 * Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN:278 * Meaning of `validate' field, use via NLA_POLICY_VALIDATE_FN:
279 * NLA_BINARY Validation function called for the attribute,279 * NLA_BINARY Validation function called for the attribute.
280 * not compatible with use of the validation_data
281 * as in NLA_BITFIELD32, NLA_REJECT, NLA_NESTED and
282 * NLA_NESTED_ARRAY.
283 * All other Unused - but note that it's a union280 * All other Unused - but note that it's a union
284 *281 *
285 * Example:282 * Example:
283 *
284 * static const u32 myvalidflags = 0xff231023;
285 *
286 * static const struct nla_policy my_policy[ATTR_MAX+1] = {286 * static const struct nla_policy my_policy[ATTR_MAX+1] = {
287 * [ATTR_FOO] = { .type = NLA_U16 },287 * [ATTR_FOO] = { .type = NLA_U16 },
288 * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },288 * [ATTR_BAR] = { .type = NLA_STRING, .len = BARSIZ },
289 * [ATTR_BAZ] = { .type = NLA_EXACT_LEN, .len = sizeof(struct mystruct) },289 * [ATTR_BAZ] = { .type = NLA_EXACT_LEN, .len = sizeof(struct mystruct) },
290 * [ATTR_GOO] = { .type = NLA_BITFIELD32, .validation_data = &myvalidflags },290 * [ATTR_GOO] = NLA_POLICY_BITFIELD32(myvalidflags),
291 * };291 * };
292 */292 */
293struct nla_policy {293struct nla_policy {
@@ -295,8 +295,10 @@ struct nla_policy {
295 u8 validation_type;295 u8 validation_type;
296 u16 len;296 u16 len;
297 union {297 union {
298 const void *validation_data;
299 const u32 mask;298 const u32 mask;
299 const u32 bitfield32_valid;
300 const char *reject_message;
301 const struct nla_policy *nested_policy;
300 struct {302 struct {
301 s16 min, max;303 s16 min, max;
302 };304 };
@@ -332,13 +334,15 @@ struct nla_policy {
332#define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)334#define NLA_POLICY_ETH_ADDR_COMPAT NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN)
333335
334#define _NLA_POLICY_NESTED(maxattr, policy) \336#define _NLA_POLICY_NESTED(maxattr, policy) \
335 { .type = NLA_NESTED, .validation_data = policy, .len = maxattr }337 { .type = NLA_NESTED, .nested_policy = policy, .len = maxattr }
336#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \338#define _NLA_POLICY_NESTED_ARRAY(maxattr, policy) \
337 { .type = NLA_NESTED_ARRAY, .validation_data = policy, .len = maxattr }339 { .type = NLA_NESTED_ARRAY, .nested_policy = policy, .len = maxattr }
338#define NLA_POLICY_NESTED(policy) \340#define NLA_POLICY_NESTED(policy) \
339 _NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy)341 _NLA_POLICY_NESTED(ARRAY_SIZE(policy) - 1, policy)
340#define NLA_POLICY_NESTED_ARRAY(policy) \342#define NLA_POLICY_NESTED_ARRAY(policy) \
341 _NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy)343 _NLA_POLICY_NESTED_ARRAY(ARRAY_SIZE(policy) - 1, policy)
344#define NLA_POLICY_BITFIELD32(valid) \
345 { .type = NLA_BITFIELD32, .bitfield32_valid = valid }
342346
343#define __NLA_IS_UINT_TYPE(tp) \347#define __NLA_IS_UINT_TYPE(tp) \
344 (tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64)348 (tp == NLA_U8 || tp == NLA_U16 || tp == NLA_U32 || tp == NLA_U64)
@@ -1482,6 +1486,21 @@ static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
1482}1486}
14831487
1484/**1488/**
1489 * nla_put_bitfield32 - Add a bitfield32 netlink attribute to a socket buffer
1490 * @skb: socket buffer to add attribute to
1491 * @attrtype: attribute type
1492 * @value: value carrying bits
1493 * @selector: selector of valid bits
1494 */
1495static inline int nla_put_bitfield32(struct sk_buff *skb, int attrtype,
1496 __u32 value, __u32 selector)
1497{
1498 struct nla_bitfield32 tmp = { value, selector, };
1499
1500 return nla_put(skb, attrtype, sizeof(tmp), &tmp);
1501}
1502
1503/**
1485 * nla_get_u32 - return payload of u32 attribute1504 * nla_get_u32 - return payload of u32 attribute
1486 * @nla: u32 netlink attribute1505 * @nla: u32 netlink attribute
1487 */1506 */
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 0aac605..d23d7fe 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -751,6 +751,7 @@ struct tc_red_qopt_offload_params {
751 u32 limit;751 u32 limit;
752 bool is_ecn;752 bool is_ecn;
753 bool is_harddrop;753 bool is_harddrop;
754 bool is_nodrop;
754 struct gnet_stats_queue *qstats;755 struct gnet_stats_queue *qstats;
755};756};
756757
diff --git a/include/net/red.h b/include/net/red.h
index ff07a7c..cc9f6b0 100644
--- a/include/net/red.h
+++ b/include/net/red.h
@@ -189,6 +189,44 @@ static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog,
189 return true;189 return true;
190}190}
191191
192static inline int red_get_flags(unsigned char qopt_flags,
193 unsigned char historic_mask,
194 struct nlattr *flags_attr,
195 unsigned char supported_mask,
196 struct nla_bitfield32 *p_flags,
197 unsigned char *p_userbits,
198 struct netlink_ext_ack *extack)
199{
200 struct nla_bitfield32 flags;
201
202 if (qopt_flags && flags_attr) {
203 NL_SET_ERR_MSG_MOD(extack, "flags should be passed either through qopt, or through a dedicated attribute");
204 return -EINVAL;
205 }
206
207 if (flags_attr) {
208 flags = nla_get_bitfield32(flags_attr);
209 } else {
210 flags.selector = historic_mask;
211 flags.value = qopt_flags & historic_mask;
212 }
213
214 *p_flags = flags;
215 *p_userbits = qopt_flags & ~historic_mask;
216 return 0;
217}
218
219static inline int red_validate_flags(unsigned char flags,
220 struct netlink_ext_ack *extack)
221{
222 if ((flags & TC_RED_NODROP) && !(flags & TC_RED_ECN)) {
223 NL_SET_ERR_MSG_MOD(extack, "nodrop mode is only meaningful with ECN");
224 return -EINVAL;
225 }
226
227 return 0;
228}
229
192static inline void red_set_parms(struct red_parms *p,230static inline void red_set_parms(struct red_parms *p,
193 u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog,231 u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog,
194 u8 Scell_log, u8 *stab, u32 max_P)232 u8 Scell_log, u8 *stab, u32 max_P)
diff --git a/include/trace/events/devlink.h b/include/trace/events/devlink.h
index 6f60a78..44d8e29 100644
--- a/include/trace/events/devlink.h
+++ b/include/trace/events/devlink.h
@@ -171,6 +171,43 @@ TRACE_EVENT(devlink_health_reporter_state_update,
171 __entry->new_state)171 __entry->new_state)
172);172);
173173
174/*
175 * Tracepoint for devlink packet trap:
176 */
177TRACE_EVENT(devlink_trap_report,
178 TP_PROTO(const struct devlink *devlink, struct sk_buff *skb,
179 const struct devlink_trap_metadata *metadata),
180
181 TP_ARGS(devlink, skb, metadata),
182
183 TP_STRUCT__entry(
184 __string(bus_name, devlink->dev->bus->name)
185 __string(dev_name, dev_name(devlink->dev))
186 __string(driver_name, devlink->dev->driver->name)
187 __string(trap_name, metadata->trap_name)
188 __string(trap_group_name, metadata->trap_group_name)
189 __dynamic_array(char, input_dev_name, IFNAMSIZ)
190 ),
191
192 TP_fast_assign(
193 struct net_device *input_dev = metadata->input_dev;
194
195 __assign_str(bus_name, devlink->dev->bus->name);
196 __assign_str(dev_name, dev_name(devlink->dev));
197 __assign_str(driver_name, devlink->dev->driver->name);
198 __assign_str(trap_name, metadata->trap_name);
199 __assign_str(trap_group_name, metadata->trap_group_name);
200 __assign_str(input_dev_name,
201 (input_dev ? input_dev->name : "NULL"));
202 ),
203
204 TP_printk("bus_name=%s dev_name=%s driver_name=%s trap_name=%s "
205 "trap_group_name=%s input_dev_name=%s", __get_str(bus_name),
206 __get_str(dev_name), __get_str(driver_name),
207 __get_str(trap_name), __get_str(trap_group_name),
208 __get_str(input_dev_name))
209);
210
174#endif /* _TRACE_DEVLINK_H */211#endif /* _TRACE_DEVLINK_H */
175212
176/* This part must be outside protection */213/* This part must be outside protection */
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index a8a2174..7896b44 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -117,6 +117,18 @@ enum devlink_command {
117 DEVLINK_CMD_TRAP_GROUP_NEW,117 DEVLINK_CMD_TRAP_GROUP_NEW,
118 DEVLINK_CMD_TRAP_GROUP_DEL,118 DEVLINK_CMD_TRAP_GROUP_DEL,
119119
120 DEVLINK_CMD_TRAP_POLICER_GET, /* can dump */
121 DEVLINK_CMD_TRAP_POLICER_SET,
122 DEVLINK_CMD_TRAP_POLICER_NEW,
123 DEVLINK_CMD_TRAP_POLICER_DEL,
124
125 DEVLINK_CMD_HEALTH_REPORTER_TEST,
126
127 DEVLINK_CMD_RATE_GET, /* can dump */
128 DEVLINK_CMD_RATE_SET,
129 DEVLINK_CMD_RATE_NEW,
130 DEVLINK_CMD_RATE_DEL,
131
120 /* add new commands above here */132 /* add new commands above here */
121 __DEVLINK_CMD_MAX,133 __DEVLINK_CMD_MAX,
122 DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1134 DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -187,6 +199,19 @@ enum devlink_port_flavour {
187 * for the PCI VF. It is an internal199 * for the PCI VF. It is an internal
188 * port that faces the PCI VF.200 * port that faces the PCI VF.
189 */201 */
202 DEVLINK_PORT_FLAVOUR_VIRTUAL, /* Any virtual port facing the user. */
203 DEVLINK_PORT_FLAVOUR_UNUSED, /* Port which exists in the switch, but
204 * is not used in any way.
205 */
206 DEVLINK_PORT_FLAVOUR_PCI_SF, /* Represents eswitch port
207 * for the PCI SF. It is an internal
208 * port that faces the PCI SF.
209 */
210};
211
212enum devlink_rate_type {
213 DEVLINK_RATE_TYPE_LEAF,
214 DEVLINK_RATE_TYPE_NODE,
190};215};
191216
192enum devlink_param_cmode {217enum devlink_param_cmode {
@@ -216,11 +241,34 @@ enum devlink_param_reset_dev_on_drv_probe_value {
216enum {241enum {
217 DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */242 DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */
218 DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */243 DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */
244 DEVLINK_ATTR_STATS_RX_DROPPED, /* u64 */
219245
220 __DEVLINK_ATTR_STATS_MAX,246 __DEVLINK_ATTR_STATS_MAX,
221 DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1247 DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
222};248};
223249
250/* Specify what sections of a flash component can be overwritten when
251 * performing an update. Overwriting of firmware binary sections is always
252 * implicitly assumed to be allowed.
253 *
254 * Each section must be documented in
255 * Documentation/networking/devlink/devlink-flash.rst
256 *
257 */
258enum {
259 DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT,
260 DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT,
261
262 __DEVLINK_FLASH_OVERWRITE_MAX_BIT,
263 DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1
264};
265
266#define DEVLINK_FLASH_OVERWRITE_SETTINGS _BITUL(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
267#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS _BITUL(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
268
269#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
270 (_BITUL(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
271
224/**272/**
225 * enum devlink_trap_action - Packet trap action.273 * enum devlink_trap_action - Packet trap action.
226 * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not274 * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
@@ -243,17 +291,48 @@ enum devlink_trap_action {
243 * control plane for resolution. Trapped packets291 * control plane for resolution. Trapped packets
244 * are processed by devlink and injected to292 * are processed by devlink and injected to
245 * the kernel's Rx path.293 * the kernel's Rx path.
294 * @DEVLINK_TRAP_TYPE_CONTROL: Packet was trapped because it is required for
295 * the correct functioning of the control plane.
296 * For example, an ARP request packet. Trapped
297 * packets are injected to the kernel's Rx path,
298 * but not reported to drop monitor.
246 */299 */
247enum devlink_trap_type {300enum devlink_trap_type {
248 DEVLINK_TRAP_TYPE_DROP,301 DEVLINK_TRAP_TYPE_DROP,
249 DEVLINK_TRAP_TYPE_EXCEPTION,302 DEVLINK_TRAP_TYPE_EXCEPTION,
303 DEVLINK_TRAP_TYPE_CONTROL,
250};304};
251305
252enum {306enum {
253 /* Trap can report input port as metadata */307 /* Trap can report input port as metadata */
254 DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT,308 DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT,
309 /* Trap can report flow action cookie as metadata */
310 DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE,
255};311};
256312
313enum devlink_reload_action {
314 DEVLINK_RELOAD_ACTION_UNSPEC,
315 DEVLINK_RELOAD_ACTION_DRIVER_REINIT, /* Driver entities re-instantiation */
316 DEVLINK_RELOAD_ACTION_FW_ACTIVATE, /* FW activate */
317
318 /* Add new reload actions above */
319 __DEVLINK_RELOAD_ACTION_MAX,
320 DEVLINK_RELOAD_ACTION_MAX = __DEVLINK_RELOAD_ACTION_MAX - 1
321};
322
323enum devlink_reload_limit {
324 DEVLINK_RELOAD_LIMIT_UNSPEC, /* unspecified, no constraints */
325 DEVLINK_RELOAD_LIMIT_NO_RESET, /* No reset allowed, no down time allowed,
326 * no link flap and no configuration is lost.
327 */
328
329 /* Add new reload limit above */
330 __DEVLINK_RELOAD_LIMIT_MAX,
331 DEVLINK_RELOAD_LIMIT_MAX = __DEVLINK_RELOAD_LIMIT_MAX - 1
332};
333
334#define DEVLINK_RELOAD_LIMITS_VALID_MASK (BIT(__DEVLINK_RELOAD_LIMIT_MAX) - 1)
335
257enum devlink_attr {336enum devlink_attr {
258 /* don't change the order or add anything between, this is ABI! */337 /* don't change the order or add anything between, this is ABI! */
259 DEVLINK_ATTR_UNSPEC,338 DEVLINK_ATTR_UNSPEC,
@@ -422,6 +501,51 @@ enum devlink_attr {
422 DEVLINK_ATTR_RELOAD_FAILED, /* u8 0 or 1 */501 DEVLINK_ATTR_RELOAD_FAILED, /* u8 0 or 1 */
423502
424 DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, /* u64 */503 DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, /* u64 */
504
505 DEVLINK_ATTR_NETNS_FD, /* u32 */
506 DEVLINK_ATTR_NETNS_PID, /* u32 */
507 DEVLINK_ATTR_NETNS_ID, /* u32 */
508
509 DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, /* u8 */
510
511 DEVLINK_ATTR_TRAP_POLICER_ID, /* u32 */
512 DEVLINK_ATTR_TRAP_POLICER_RATE, /* u64 */
513 DEVLINK_ATTR_TRAP_POLICER_BURST, /* u64 */
514
515 DEVLINK_ATTR_PORT_FUNCTION, /* nested */
516
517 DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, /* string */
518
519 DEVLINK_ATTR_PORT_LANES, /* u32 */
520 DEVLINK_ATTR_PORT_SPLITTABLE, /* u8 */
521
522 DEVLINK_ATTR_PORT_EXTERNAL, /* u8 */
523 DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, /* u32 */
524
525 DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, /* u64 */
526 DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK, /* bitfield32 */
527
528 DEVLINK_ATTR_RELOAD_ACTION, /* u8 */
529 DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, /* bitfield32 */
530 DEVLINK_ATTR_RELOAD_LIMITS, /* bitfield32 */
531
532 DEVLINK_ATTR_DEV_STATS, /* nested */
533 DEVLINK_ATTR_RELOAD_STATS, /* nested */
534 DEVLINK_ATTR_RELOAD_STATS_ENTRY, /* nested */
535 DEVLINK_ATTR_RELOAD_STATS_LIMIT, /* u8 */
536 DEVLINK_ATTR_RELOAD_STATS_VALUE, /* u32 */
537 DEVLINK_ATTR_REMOTE_RELOAD_STATS, /* nested */
538 DEVLINK_ATTR_RELOAD_ACTION_INFO, /* nested */
539 DEVLINK_ATTR_RELOAD_ACTION_STATS, /* nested */
540
541 DEVLINK_ATTR_PORT_PCI_SF_NUMBER, /* u32 */
542
543 DEVLINK_ATTR_RATE_TYPE, /* u16 */
544 DEVLINK_ATTR_RATE_TX_SHARE, /* u64 */
545 DEVLINK_ATTR_RATE_TX_MAX, /* u64 */
546 DEVLINK_ATTR_RATE_NODE_NAME, /* string */
547 DEVLINK_ATTR_RATE_PARENT_NODE_NAME, /* string */
548
425 /* add new attributes above here, update the policy in devlink.c */549 /* add new attributes above here, update the policy in devlink.c */
426550
427 __DEVLINK_ATTR_MAX,551 __DEVLINK_ATTR_MAX,
@@ -468,4 +592,32 @@ enum devlink_resource_unit {
468 DEVLINK_RESOURCE_UNIT_ENTRY,592 DEVLINK_RESOURCE_UNIT_ENTRY,
469};593};
470594
595enum devlink_port_function_attr {
596 DEVLINK_PORT_FUNCTION_ATTR_UNSPEC,
597 DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, /* binary */
598 DEVLINK_PORT_FN_ATTR_STATE, /* u8 */
599 DEVLINK_PORT_FN_ATTR_OPSTATE, /* u8 */
600
601 __DEVLINK_PORT_FUNCTION_ATTR_MAX,
602 DEVLINK_PORT_FUNCTION_ATTR_MAX = __DEVLINK_PORT_FUNCTION_ATTR_MAX - 1
603};
604
605enum devlink_port_fn_state {
606 DEVLINK_PORT_FN_STATE_INACTIVE,
607 DEVLINK_PORT_FN_STATE_ACTIVE,
608};
609
610/**
611 * enum devlink_port_fn_opstate - indicates operational state of the function
612 * @DEVLINK_PORT_FN_OPSTATE_ATTACHED: Driver is attached to the function.
613 * For graceful tear down of the function, after inactivation of the
614 * function, user should wait for operational state to turn DETACHED.
615 * @DEVLINK_PORT_FN_OPSTATE_DETACHED: Driver is detached from the function.
616 * It is safe to delete the port.
617 */
618enum devlink_port_fn_opstate {
619 DEVLINK_PORT_FN_OPSTATE_DETACHED,
620 DEVLINK_PORT_FN_OPSTATE_ATTACHED,
621};
622
471#endif /* _UAPI_LINUX_DEVLINK_H_ */623#endif /* _UAPI_LINUX_DEVLINK_H_ */
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 4a245d7..0070ef1 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -256,6 +256,7 @@ enum {
256 TCA_RED_PARMS,256 TCA_RED_PARMS,
257 TCA_RED_STAB,257 TCA_RED_STAB,
258 TCA_RED_MAX_P,258 TCA_RED_MAX_P,
259 TCA_RED_FLAGS, /* bitfield32 */
259 __TCA_RED_MAX,260 __TCA_RED_MAX,
260};261};
261262
@@ -268,12 +269,28 @@ struct tc_red_qopt {
268 unsigned char Wlog; /* log(W) */269 unsigned char Wlog; /* log(W) */
269 unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */270 unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
270 unsigned char Scell_log; /* cell size for idle damping */271 unsigned char Scell_log; /* cell size for idle damping */
272
273 /* This field can be used for flags that a RED-like qdisc has
274 * historically supported. E.g. when configuring RED, it can be used for
275 * ECN, HARDDROP and ADAPTATIVE. For SFQ it can be used for ECN,
276 * HARDDROP. Etc. Because this field has not been validated, and is
277 * copied back on dump, any bits besides those to which a given qdisc
278 * has assigned a historical meaning need to be considered for free use
279 * by userspace tools.
280 *
281 * Any further flags need to be passed differently, e.g. through an
282 * attribute (such as TCA_RED_FLAGS above). Such attribute should allow
283 * passing both recent and historic flags in one value.
284 */
271 unsigned char flags;285 unsigned char flags;
272#define TC_RED_ECN 1286#define TC_RED_ECN 1
273#define TC_RED_HARDDROP 2287#define TC_RED_HARDDROP 2
274#define TC_RED_ADAPTATIVE 4288#define TC_RED_ADAPTATIVE 4
289#define TC_RED_NODROP 8
275};290};
276291
292#define TC_RED_HISTORIC_FLAGS (TC_RED_ECN | TC_RED_HARDDROP | TC_RED_ADAPTATIVE)
293
277struct tc_red_xstats {294struct tc_red_xstats {
278 __u32 early; /* Early drops */295 __u32 early; /* Early drops */
279 __u32 pdrop; /* Drops due to queue limits */296 __u32 pdrop; /* Drops due to queue limits */
diff --git a/lib/nlattr.c b/lib/nlattr.c
index c94b014..b61f3a5 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -45,7 +45,7 @@ static const u8 nla_attr_minlen[NLA_TYPE_MAX+1] = {
45};45};
4646
47static int validate_nla_bitfield32(const struct nlattr *nla,47static int validate_nla_bitfield32(const struct nlattr *nla,
48 const u32 *valid_flags_mask)48 const u32 valid_flags_mask)
49{49{
50 const struct nla_bitfield32 *bf = nla_data(nla);50 const struct nla_bitfield32 *bf = nla_data(nla);
5151
@@ -53,11 +53,11 @@ static int validate_nla_bitfield32(const struct nlattr *nla,
53 return -EINVAL;53 return -EINVAL;
5454
55 /*disallow invalid bit selector */55 /*disallow invalid bit selector */
56 if (bf->selector & ~*valid_flags_mask)56 if (bf->selector & ~valid_flags_mask)
57 return -EINVAL;57 return -EINVAL;
5858
59 /*disallow invalid bit values */59 /*disallow invalid bit values */
60 if (bf->value & ~*valid_flags_mask)60 if (bf->value & ~valid_flags_mask)
61 return -EINVAL;61 return -EINVAL;
6262
63 /*disallow valid bit values that are not selected*/63 /*disallow valid bit values that are not selected*/
@@ -237,9 +237,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
237 break;237 break;
238238
239 case NLA_REJECT:239 case NLA_REJECT:
240 if (extack && pt->validation_data) {240 if (extack && pt->reject_message) {
241 NL_SET_BAD_ATTR(extack, nla);241 NL_SET_BAD_ATTR(extack, nla);
242 extack->_msg = pt->validation_data;242 extack->_msg = pt->reject_message;
243 return -EINVAL;243 return -EINVAL;
244 }244 }
245 err = -EINVAL;245 err = -EINVAL;
@@ -254,7 +254,7 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
254 if (attrlen != sizeof(struct nla_bitfield32))254 if (attrlen != sizeof(struct nla_bitfield32))
255 goto out_err;255 goto out_err;
256256
257 err = validate_nla_bitfield32(nla, pt->validation_data);257 err = validate_nla_bitfield32(nla, pt->bitfield32_valid);
258 if (err)258 if (err)
259 goto out_err;259 goto out_err;
260 break;260 break;
@@ -299,9 +299,9 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
299 break;299 break;
300 if (attrlen < NLA_HDRLEN)300 if (attrlen < NLA_HDRLEN)
301 goto out_err;301 goto out_err;
302 if (pt->validation_data) {302 if (pt->nested_policy) {
303 err = __nla_validate(nla_data(nla), nla_len(nla), pt->len,303 err = __nla_validate(nla_data(nla), nla_len(nla), pt->len,
304 pt->validation_data, validate,304 pt->nested_policy, validate,
305 extack);305 extack);
306 if (err < 0) {306 if (err < 0) {
307 /*307 /*
@@ -320,11 +320,11 @@ static int validate_nla(const struct nlattr *nla, int maxtype,
320 break;320 break;
321 if (attrlen < NLA_HDRLEN)321 if (attrlen < NLA_HDRLEN)
322 goto out_err;322 goto out_err;
323 if (pt->validation_data) {323 if (pt->nested_policy) {
324 int err;324 int err;
325325
326 err = nla_validate_array(nla_data(nla), nla_len(nla),326 err = nla_validate_array(nla_data(nla), nla_len(nla),
327 pt->len, pt->validation_data,327 pt->len, pt->nested_policy,
328 extack, validate);328 extack, validate);
329 if (err < 0) {329 if (err < 0) {
330 /*330 /*
diff --git a/net/Kconfig b/net/Kconfig
index 0b2fecc..5aa30bc 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -433,7 +433,6 @@ config NET_SOCK_MSG
433config NET_DEVLINK433config NET_DEVLINK
434 bool434 bool
435 default n435 default n
436 imply NET_DROP_MONITOR
437436
438config PAGE_POOL437config PAGE_POOL
439 bool438 bool
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 09eb3e6..0ee0fb6 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -27,7 +27,6 @@
27#include <net/net_namespace.h>27#include <net/net_namespace.h>
28#include <net/sock.h>28#include <net/sock.h>
29#include <net/devlink.h>29#include <net/devlink.h>
30#include <net/drop_monitor.h>
31#define CREATE_TRACE_POINTS30#define CREATE_TRACE_POINTS
32#include <trace/events/devlink.h>31#include <trace/events/devlink.h>
3332
@@ -84,6 +83,14 @@ EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
8483
85EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);84EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
86EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);85EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
86EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
87
88static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
89 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
90 [DEVLINK_PORT_FN_ATTR_STATE] =
91 NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
92 DEVLINK_PORT_FN_STATE_ACTIVE),
93};
8794
88static LIST_HEAD(devlink_list);95static LIST_HEAD(devlink_list);
8996
@@ -95,15 +102,11 @@ static LIST_HEAD(devlink_list);
95 */102 */
96static DEFINE_MUTEX(devlink_mutex);103static DEFINE_MUTEX(devlink_mutex);
97104
98static struct net *devlink_net(const struct devlink *devlink)105struct net *devlink_net(const struct devlink *devlink)
99{106{
100 return read_pnet(&devlink->_net);107 return read_pnet(&devlink->_net);
101}108}
102109EXPORT_SYMBOL_GPL(devlink_net);
103static void devlink_net_set(struct devlink *devlink, struct net *net)
104{
105 write_pnet(&devlink->_net, net);
106}
107110
108static struct devlink *devlink_get_from_attrs(struct net *net,111static struct devlink *devlink_get_from_attrs(struct net *net,
109 struct nlattr **attrs)112 struct nlattr **attrs)
@@ -174,6 +177,80 @@ static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
174 return devlink_port_get_from_attrs(devlink, info->attrs);177 return devlink_port_get_from_attrs(devlink, info->attrs);
175}178}
176179
180static inline bool
181devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
182{
183 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
184}
185
186static inline bool
187devlink_rate_is_node(struct devlink_rate *devlink_rate)
188{
189 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
190}
191
192static struct devlink_rate *
193devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
194{
195 struct devlink_rate *devlink_rate;
196 struct devlink_port *devlink_port;
197
198 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
199 if (IS_ERR(devlink_port))
200 return ERR_CAST(devlink_port);
201 devlink_rate = devlink_port->devlink_rate;
202 return devlink_rate ?: ERR_PTR(-ENODEV);
203}
204
205static struct devlink_rate *
206devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
207{
208 static struct devlink_rate *devlink_rate;
209
210 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
211 if (devlink_rate_is_node(devlink_rate) &&
212 !strcmp(node_name, devlink_rate->name))
213 return devlink_rate;
214 }
215 return ERR_PTR(-ENODEV);
216}
217
218static struct devlink_rate *
219devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
220{
221 const char *rate_node_name;
222 size_t len;
223
224 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
225 return ERR_PTR(-EINVAL);
226 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
227 len = strlen(rate_node_name);
228 /* Name cannot be empty or decimal number */
229 if (!len || strspn(rate_node_name, "0123456789") == len)
230 return ERR_PTR(-EINVAL);
231
232 return devlink_rate_node_get_by_name(devlink, rate_node_name);
233}
234
235static struct devlink_rate *
236devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
237{
238 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
239}
240
241static struct devlink_rate *
242devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
243{
244 struct nlattr **attrs = info->attrs;
245
246 if (attrs[DEVLINK_ATTR_PORT_INDEX])
247 return devlink_rate_leaf_get_from_info(devlink, info);
248 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
249 return devlink_rate_node_get_from_info(devlink, info);
250 else
251 return ERR_PTR(-EINVAL);
252}
253
177struct devlink_sb {254struct devlink_sb {
178 struct list_head list;255 struct list_head list;
179 unsigned int index;256 unsigned int index;
@@ -334,8 +411,12 @@ devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
334411
335struct devlink_region {412struct devlink_region {
336 struct devlink *devlink;413 struct devlink *devlink;
414 struct devlink_port *port;
337 struct list_head list;415 struct list_head list;
338 const char *name;416 union {
417 const struct devlink_region_ops *ops;
418 const struct devlink_port_region_ops *port_ops;
419 };
339 struct list_head snapshot_list;420 struct list_head snapshot_list;
340 u32 max_snapshots;421 u32 max_snapshots;
341 u32 cur_snapshots;422 u32 cur_snapshots;
@@ -345,7 +426,6 @@ struct devlink_region {
345struct devlink_snapshot {426struct devlink_snapshot {
346 struct list_head list;427 struct list_head list;
347 struct devlink_region *region;428 struct devlink_region *region;
348 devlink_snapshot_data_dest_t *data_destructor;
349 u8 *data;429 u8 *data;
350 u32 id;430 u32 id;
351};431};
@@ -356,7 +436,20 @@ devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
356 struct devlink_region *region;436 struct devlink_region *region;
357437
358 list_for_each_entry(region, &devlink->region_list, list)438 list_for_each_entry(region, &devlink->region_list, list)
359 if (!strcmp(region->name, region_name))439 if (!strcmp(region->ops->name, region_name))
440 return region;
441
442 return NULL;
443}
444
445static struct devlink_region *
446devlink_port_region_get_by_name(struct devlink_port *port,
447 const char *region_name)
448{
449 struct devlink_region *region;
450
451 list_for_each_entry(region, &port->region_list, list)
452 if (!strcmp(region->ops->name, region_name))
360 return region;453 return region;
361454
362 return NULL;455 return NULL;
@@ -374,19 +467,21 @@ devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
374 return NULL;467 return NULL;
375}468}
376469
377#define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)470#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
378#define DEVLINK_NL_FLAG_NEED_PORT BIT(1)471#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
379#define DEVLINK_NL_FLAG_NEED_SB BIT(2)472#define DEVLINK_NL_FLAG_NEED_RATE BIT(2)
473#define DEVLINK_NL_FLAG_NEED_RATE_NODE BIT(3)
380474
381/* The per devlink instance lock is taken by default in the pre-doit475/* The per devlink instance lock is taken by default in the pre-doit
382 * operation, yet several commands do not require this. The global476 * operation, yet several commands do not require this. The global
383 * devlink lock is taken and protects from disruption by user-calls.477 * devlink lock is taken and protects from disruption by user-calls.
384 */478 */
385#define DEVLINK_NL_FLAG_NO_LOCK BIT(3)479#define DEVLINK_NL_FLAG_NO_LOCK BIT(4)
386480
387static int devlink_nl_pre_doit(const struct genl_ops *ops,481static int devlink_nl_pre_doit(const struct genl_ops *ops,
388 struct sk_buff *skb, struct genl_info *info)482 struct sk_buff *skb, struct genl_info *info)
389{483{
484 struct devlink_port *devlink_port;
390 struct devlink *devlink;485 struct devlink *devlink;
391 int err;486 int err;
392487
@@ -398,27 +493,36 @@ static int devlink_nl_pre_doit(const struct genl_ops *ops,
398 }493 }
399 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)494 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
400 mutex_lock(&devlink->lock);495 mutex_lock(&devlink->lock);
401 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {496 info->user_ptr[0] = devlink;
402 info->user_ptr[0] = devlink;497 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
403 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
404 struct devlink_port *devlink_port;
405
406 devlink_port = devlink_port_get_from_info(devlink, info);498 devlink_port = devlink_port_get_from_info(devlink, info);
407 if (IS_ERR(devlink_port)) {499 if (IS_ERR(devlink_port)) {
408 err = PTR_ERR(devlink_port);500 err = PTR_ERR(devlink_port);
409 goto unlock;501 goto unlock;
410 }502 }
411 info->user_ptr[0] = devlink_port;503 info->user_ptr[1] = devlink_port;
412 }504 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
413 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {505 devlink_port = devlink_port_get_from_info(devlink, info);
414 struct devlink_sb *devlink_sb;506 if (!IS_ERR(devlink_port))
507 info->user_ptr[1] = devlink_port;
508 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE) {
509 struct devlink_rate *devlink_rate;
510
511 devlink_rate = devlink_rate_get_from_info(devlink, info);
512 if (IS_ERR(devlink_rate)) {
513 err = PTR_ERR(devlink_rate);
514 goto unlock;
515 }
516 info->user_ptr[1] = devlink_rate;
517 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_RATE_NODE) {
518 struct devlink_rate *rate_node;
415519
416 devlink_sb = devlink_sb_get_from_info(devlink, info);520 rate_node = devlink_rate_node_get_from_info(devlink, info);
417 if (IS_ERR(devlink_sb)) {521 if (IS_ERR(rate_node)) {
418 err = PTR_ERR(devlink_sb);522 err = PTR_ERR(rate_node);
419 goto unlock;523 goto unlock;
420 }524 }
421 info->user_ptr[1] = devlink_sb;525 info->user_ptr[1] = rate_node;
422 }526 }
423 return 0;527 return 0;
424528
@@ -434,7 +538,7 @@ static void devlink_nl_post_doit(const struct genl_ops *ops,
434{538{
435 struct devlink *devlink;539 struct devlink *devlink;
436540
437 devlink = devlink_get_from_info(info);541 devlink = info->user_ptr[0];
438 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)542 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
439 mutex_unlock(&devlink->lock);543 mutex_unlock(&devlink->lock);
440 mutex_unlock(&devlink_mutex);544 mutex_unlock(&devlink_mutex);
@@ -459,10 +563,132 @@ static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
459 return 0;563 return 0;
460}564}
461565
566struct devlink_reload_combination {
567 enum devlink_reload_action action;
568 enum devlink_reload_limit limit;
569};
570
571static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
572 {
573 /* can't reinitialize driver with no down time */
574 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
575 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
576 },
577};
578
579static bool
580devlink_reload_combination_is_invalid(enum devlink_reload_action action,
581 enum devlink_reload_limit limit)
582{
583 int i;
584
585 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
586 if (devlink_reload_invalid_combinations[i].action == action &&
587 devlink_reload_invalid_combinations[i].limit == limit)
588 return true;
589 return false;
590}
591
592static bool
593devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
594{
595 return test_bit(action, &devlink->ops->reload_actions);
596}
597
598static bool
599devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
600{
601 return test_bit(limit, &devlink->ops->reload_limits);
602}
603
604static int devlink_reload_stat_put(struct sk_buff *msg,
605 enum devlink_reload_limit limit, u32 value)
606{
607 struct nlattr *reload_stats_entry;
608
609 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
610 if (!reload_stats_entry)
611 return -EMSGSIZE;
612
613 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
614 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
615 goto nla_put_failure;
616 nla_nest_end(msg, reload_stats_entry);
617 return 0;
618
619nla_put_failure:
620 nla_nest_cancel(msg, reload_stats_entry);
621 return -EMSGSIZE;
622}
623
624static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
625{
626 struct nlattr *reload_stats_attr, *act_info, *act_stats;
627 int i, j, stat_idx;
628 u32 value;
629
630 if (!is_remote)
631 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
632 else
633 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
634
635 if (!reload_stats_attr)
636 return -EMSGSIZE;
637
638 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
639 if ((!is_remote &&
640 !devlink_reload_action_is_supported(devlink, i)) ||
641 i == DEVLINK_RELOAD_ACTION_UNSPEC)
642 continue;
643 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
644 if (!act_info)
645 goto nla_put_failure;
646
647 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
648 goto action_info_nest_cancel;
649 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
650 if (!act_stats)
651 goto action_info_nest_cancel;
652
653 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
654 /* Remote stats are shown even if not locally supported.
655 * Stats of actions with unspecified limit are shown
656 * though drivers don't need to register unspecified
657 * limit.
658 */
659 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
660 !devlink_reload_limit_is_supported(devlink, j)) ||
661 devlink_reload_combination_is_invalid(i, j))
662 continue;
663
664 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
665 if (!is_remote)
666 value = devlink->stats.reload_stats[stat_idx];
667 else
668 value = devlink->stats.remote_reload_stats[stat_idx];
669 if (devlink_reload_stat_put(msg, j, value))
670 goto action_stats_nest_cancel;
671 }
672 nla_nest_end(msg, act_stats);
673 nla_nest_end(msg, act_info);
674 }
675 nla_nest_end(msg, reload_stats_attr);
676 return 0;
677
678action_stats_nest_cancel:
679 nla_nest_cancel(msg, act_stats);
680action_info_nest_cancel:
681 nla_nest_cancel(msg, act_info);
682nla_put_failure:
683 nla_nest_cancel(msg, reload_stats_attr);
684 return -EMSGSIZE;
685}
686
462static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,687static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
463 enum devlink_command cmd, u32 portid,688 enum devlink_command cmd, u32 portid,
464 u32 seq, int flags)689 u32 seq, int flags)
465{690{
691 struct nlattr *dev_stats;
466 void *hdr;692 void *hdr;
467693
468 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);694 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
@@ -474,9 +700,21 @@ static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
474 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))700 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
475 goto nla_put_failure;701 goto nla_put_failure;
476702
703 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
704 if (!dev_stats)
705 goto nla_put_failure;
706
707 if (devlink_reload_stats_put(msg, devlink, false))
708 goto dev_stats_nest_cancel;
709 if (devlink_reload_stats_put(msg, devlink, true))
710 goto dev_stats_nest_cancel;
711
712 nla_nest_end(msg, dev_stats);
477 genlmsg_end(msg, hdr);713 genlmsg_end(msg, hdr);
478 return 0;714 return 0;
479715
716dev_stats_nest_cancel:
717 nla_nest_cancel(msg, dev_stats);
480nla_put_failure:718nla_put_failure:
481 genlmsg_cancel(msg, hdr);719 genlmsg_cancel(msg, hdr);
482 return -EMSGSIZE;720 return -EMSGSIZE;
@@ -508,26 +746,47 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
508{746{
509 struct devlink_port_attrs *attrs = &devlink_port->attrs;747 struct devlink_port_attrs *attrs = &devlink_port->attrs;
510748
511 if (!attrs->set)749 if (!devlink_port->attrs_set)
512 return 0;750 return 0;
751 if (attrs->lanes) {
752 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
753 return -EMSGSIZE;
754 }
755 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
756 return -EMSGSIZE;
513 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))757 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
514 return -EMSGSIZE;758 return -EMSGSIZE;
515 switch (devlink_port->attrs.flavour) {759 switch (devlink_port->attrs.flavour) {
516 case DEVLINK_PORT_FLAVOUR_PCI_PF:760 case DEVLINK_PORT_FLAVOUR_PCI_PF:
517 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,761 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
518 attrs->pci_pf.pf))762 attrs->pci_pf.controller) ||
763 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
764 return -EMSGSIZE;
765 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
519 return -EMSGSIZE;766 return -EMSGSIZE;
520 break;767 break;
521 case DEVLINK_PORT_FLAVOUR_PCI_VF:768 case DEVLINK_PORT_FLAVOUR_PCI_VF:
522 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,769 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
523 attrs->pci_vf.pf) ||770 attrs->pci_vf.controller) ||
524 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER,771 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
525 attrs->pci_vf.vf))772 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
773 return -EMSGSIZE;
774 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
775 return -EMSGSIZE;
776 break;
777 case DEVLINK_PORT_FLAVOUR_PCI_SF:
778 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
779 attrs->pci_sf.controller) ||
780 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
781 attrs->pci_sf.pf) ||
782 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
783 attrs->pci_sf.sf))
526 return -EMSGSIZE;784 return -EMSGSIZE;
527 break;785 break;
528 case DEVLINK_PORT_FLAVOUR_PHYSICAL:786 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
529 case DEVLINK_PORT_FLAVOUR_CPU:787 case DEVLINK_PORT_FLAVOUR_CPU:
530 case DEVLINK_PORT_FLAVOUR_DSA:788 case DEVLINK_PORT_FLAVOUR_DSA:
789 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
531 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,790 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
532 attrs->phys.port_number))791 attrs->phys.port_number))
533 return -EMSGSIZE;792 return -EMSGSIZE;
@@ -546,11 +805,167 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
546 return 0;805 return 0;
547}806}
548807
549static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,808static int
809devlink_port_fn_hw_addr_fill(struct devlink *devlink, const struct devlink_ops *ops,
810 struct devlink_port *port, struct sk_buff *msg,
811 struct netlink_ext_ack *extack, bool *msg_updated)
812{
813 u8 hw_addr[MAX_ADDR_LEN];
814 int hw_addr_len;
815 int err;
816
817 if (!ops->port_function_hw_addr_get)
818 return 0;
819
820 err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
821 if (err) {
822 if (err == -EOPNOTSUPP)
823 return 0;
824 return err;
825 }
826 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
827 if (err)
828 return err;
829 *msg_updated = true;
830 return 0;
831}
832
833static int devlink_nl_rate_fill(struct sk_buff *msg,
834 struct devlink_rate *devlink_rate,
835 enum devlink_command cmd, u32 portid, u32 seq,
836 int flags, struct netlink_ext_ack *extack)
837{
838 struct devlink *devlink = devlink_rate->devlink;
839 void *hdr;
840
841 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
842 if (!hdr)
843 return -EMSGSIZE;
844
845 if (devlink_nl_put_handle(msg, devlink))
846 goto nla_put_failure;
847
848 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
849 goto nla_put_failure;
850
851 if (devlink_rate_is_leaf(devlink_rate)) {
852 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
853 devlink_rate->devlink_port->index))
854 goto nla_put_failure;
855 } else if (devlink_rate_is_node(devlink_rate)) {
856 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
857 devlink_rate->name))
858 goto nla_put_failure;
859 }
860
861 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
862 devlink_rate->tx_share, DEVLINK_ATTR_PAD))
863 goto nla_put_failure;
864
865 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
866 devlink_rate->tx_max, DEVLINK_ATTR_PAD))
867 goto nla_put_failure;
868
869 if (devlink_rate->parent)
870 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
871 devlink_rate->parent->name))
872 goto nla_put_failure;
873
874 genlmsg_end(msg, hdr);
875 return 0;
876
877nla_put_failure:
878 genlmsg_cancel(msg, hdr);
879 return -EMSGSIZE;
880}
881
882static bool
883devlink_port_fn_state_valid(enum devlink_port_fn_state state)
884{
885 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
886 state == DEVLINK_PORT_FN_STATE_ACTIVE;
887}
888
889static bool
890devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
891{
892 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
893 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
894}
895
896static int
897devlink_port_fn_state_fill(struct devlink *devlink,
898 const struct devlink_ops *ops,
899 struct devlink_port *port, struct sk_buff *msg,
900 struct netlink_ext_ack *extack,
901 bool *msg_updated)
902{
903 enum devlink_port_fn_opstate opstate;
904 enum devlink_port_fn_state state;
905 int err;
906
907 if (!ops->port_fn_state_get)
908 return 0;
909
910 err = ops->port_fn_state_get(devlink, port, &state, &opstate, extack);
911 if (err) {
912 if (err == -EOPNOTSUPP)
913 return 0;
914 return err;
915 }
916 if (!devlink_port_fn_state_valid(state)) {
917 WARN_ON_ONCE(1);
918 NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
919 return -EINVAL;
920 }
921 if (!devlink_port_fn_opstate_valid(opstate)) {
922 WARN_ON_ONCE(1);
923 NL_SET_ERR_MSG_MOD(extack,
924 "Invalid operational state read from driver");
925 return -EINVAL;
926 }
927 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
928 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
929 return -EMSGSIZE;
930 *msg_updated = true;
931 return 0;
932}
933
934static int
935devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
936 struct netlink_ext_ack *extack)
937{
938 struct devlink *devlink = port->devlink;
939 const struct devlink_ops *ops;
940 struct nlattr *function_attr;
941 bool msg_updated = false;
942 int err;
943
944 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
945 if (!function_attr)
946 return -EMSGSIZE;
947
948 ops = devlink->ops;
949 err = devlink_port_fn_hw_addr_fill(devlink, ops, port, msg,
950 extack, &msg_updated);
951 if (err)
952 goto out;
953 err = devlink_port_fn_state_fill(devlink, ops, port, msg, extack,
954 &msg_updated);
955out:
956 if (err || !msg_updated)
957 nla_nest_cancel(msg, function_attr);
958 else
959 nla_nest_end(msg, function_attr);
960 return err;
961}
962
963static int devlink_nl_port_fill(struct sk_buff *msg,
550 struct devlink_port *devlink_port,964 struct devlink_port *devlink_port,
551 enum devlink_command cmd, u32 portid,965 enum devlink_command cmd, u32 portid, u32 seq,
552 u32 seq, int flags)966 int flags, struct netlink_ext_ack *extack)
553{967{
968 struct devlink *devlink = devlink_port->devlink;
554 void *hdr;969 void *hdr;
555970
556 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);971 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
@@ -593,6 +1008,8 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
593 rtnl_unlock();1008 rtnl_unlock();
594 if (devlink_nl_port_attrs_put(msg, devlink_port))1009 if (devlink_nl_port_attrs_put(msg, devlink_port))
595 goto nla_put_failure;1010 goto nla_put_failure;
1011 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
1012 goto nla_put_failure;
5961013
597 genlmsg_end(msg, hdr);1014 genlmsg_end(msg, hdr);
598 return 0;1015 return 0;
@@ -608,84 +1025,95 @@ nla_put_failure:
608static void devlink_port_notify(struct devlink_port *devlink_port,1025static void devlink_port_notify(struct devlink_port *devlink_port,
609 enum devlink_command cmd)1026 enum devlink_command cmd)
610{1027{
611 struct devlink *devlink = devlink_port->devlink;
612 struct sk_buff *msg;1028 struct sk_buff *msg;
613 int err;1029 int err;
6141030
615 if (!devlink_port->registered)
616 return;
617
618 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);1031 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
6191032
620 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);1033 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
621 if (!msg)1034 if (!msg)
622 return;1035 return;
6231036
624 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);1037 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
625 if (err) {1038 if (err) {
626 nlmsg_free(msg);1039 nlmsg_free(msg);
627 return;1040 return;
628 }1041 }
6291042
630 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),1043 genlmsg_multicast_netns(&devlink_nl_family,
631 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);1044 devlink_net(devlink_port->devlink), msg, 0,
1045 DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
632}1046}
6331047
634static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)1048static void devlink_rate_notify(struct devlink_rate *devlink_rate,
1049 enum devlink_command cmd)
635{1050{
636 struct devlink *devlink = info->user_ptr[0];
637 struct sk_buff *msg;1051 struct sk_buff *msg;
638 int err;1052 int err;
6391053
1054 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
1055
640 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);1056 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
641 if (!msg)1057 if (!msg)
642 return -ENOMEM;1058 return;
6431059
644 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,1060 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
645 info->snd_portid, info->snd_seq, 0);
646 if (err) {1061 if (err) {
647 nlmsg_free(msg);1062 nlmsg_free(msg);
648 return err;1063 return;
649 }1064 }
6501065
651 return genlmsg_reply(msg, info);1066 genlmsg_multicast_netns(&devlink_nl_family,
1067 devlink_net(devlink_rate->devlink), msg, 0,
1068 DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
652}1069}
6531070
654static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,1071static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
655 struct netlink_callback *cb)1072 struct netlink_callback *cb)
656{1073{
1074 struct devlink_rate *devlink_rate;
657 struct devlink *devlink;1075 struct devlink *devlink;
658 int start = cb->args[0];1076 int start = cb->args[0];
659 int idx = 0;1077 int idx = 0;
660 int err;1078 int err = 0;
6611079
662 mutex_lock(&devlink_mutex);1080 mutex_lock(&devlink_mutex);
663 list_for_each_entry(devlink, &devlink_list, list) {1081 list_for_each_entry(devlink, &devlink_list, list) {
664 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))1082 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
665 continue;1083 continue;
666 if (idx < start) {1084 mutex_lock(&devlink->lock);
1085 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1086 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1087 u32 id = NETLINK_CB(cb->skb).portid;
1088
1089 if (idx < start) {
1090 idx++;
1091 continue;
1092 }
1093 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1094 cb->nlh->nlmsg_seq,
1095 NLM_F_MULTI, NULL);
1096 if (err) {
1097 mutex_unlock(&devlink->lock);
1098 goto out;
1099 }
667 idx++;1100 idx++;
668 continue;
669 }1101 }
670 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,1102 mutex_unlock(&devlink->lock);
671 NETLINK_CB(cb->skb).portid,
672 cb->nlh->nlmsg_seq, NLM_F_MULTI);
673 if (err)
674 goto out;
675 idx++;
676 }1103 }
677out:1104out:
678 mutex_unlock(&devlink_mutex);1105 mutex_unlock(&devlink_mutex);
1106 if (err != -EMSGSIZE)
1107 return err;
6791108
680 cb->args[0] = idx;1109 cb->args[0] = idx;
681 return msg->len;1110 return msg->len;
682}1111}
6831112
684static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,1113static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
685 struct genl_info *info)1114 struct genl_info *info)
686{1115{
687 struct devlink_port *devlink_port = info->user_ptr[0];1116 struct devlink_rate *devlink_rate = info->user_ptr[1];
688 struct devlink *devlink = devlink_port->devlink;
689 struct sk_buff *msg;1117 struct sk_buff *msg;
690 int err;1118 int err;
6911119
@@ -693,9 +1121,9 @@ static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
693 if (!msg)1121 if (!msg)
694 return -ENOMEM;1122 return -ENOMEM;
6951123
696 err = devlink_nl_port_fill(msg, devlink, devlink_port,1124 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
697 DEVLINK_CMD_PORT_NEW,1125 info->snd_portid, info->snd_seq, 0,
698 info->snd_portid, info->snd_seq, 0);1126 info->extack);
699 if (err) {1127 if (err) {
700 nlmsg_free(msg);1128 nlmsg_free(msg);
701 return err;1129 return err;
@@ -704,8 +1132,92 @@ static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
704 return genlmsg_reply(msg, info);1132 return genlmsg_reply(msg, info);
705}1133}
7061134
707static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,1135static bool
708 struct netlink_callback *cb)1136devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1137 struct devlink_rate *parent)
1138{
1139 while (parent) {
1140 if (parent == devlink_rate)
1141 return true;
1142 parent = parent->parent;
1143 }
1144 return false;
1145}
1146
1147static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
1148{
1149 struct devlink *devlink = info->user_ptr[0];
1150 struct sk_buff *msg;
1151 int err;
1152
1153 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1154 if (!msg)
1155 return -ENOMEM;
1156
1157 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1158 info->snd_portid, info->snd_seq, 0);
1159 if (err) {
1160 nlmsg_free(msg);
1161 return err;
1162 }
1163
1164 return genlmsg_reply(msg, info);
1165}
1166
1167static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
1168 struct netlink_callback *cb)
1169{
1170 struct devlink *devlink;
1171 int start = cb->args[0];
1172 int idx = 0;
1173 int err;
1174
1175 mutex_lock(&devlink_mutex);
1176 list_for_each_entry(devlink, &devlink_list, list) {
1177 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
1178 continue;
1179 if (idx < start) {
1180 idx++;
1181 continue;
1182 }
1183 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1184 NETLINK_CB(cb->skb).portid,
1185 cb->nlh->nlmsg_seq, NLM_F_MULTI);
1186 if (err)
1187 goto out;
1188 idx++;
1189 }
1190out:
1191 mutex_unlock(&devlink_mutex);
1192
1193 cb->args[0] = idx;
1194 return msg->len;
1195}
1196
1197static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1198 struct genl_info *info)
1199{
1200 struct devlink_port *devlink_port = info->user_ptr[1];
1201 struct sk_buff *msg;
1202 int err;
1203
1204 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1205 if (!msg)
1206 return -ENOMEM;
1207
1208 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1209 info->snd_portid, info->snd_seq, 0,
1210 info->extack);
1211 if (err) {
1212 nlmsg_free(msg);
1213 return err;
1214 }
1215
1216 return genlmsg_reply(msg, info);
1217}
1218
1219static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
1220 struct netlink_callback *cb)
709{1221{
710 struct devlink *devlink;1222 struct devlink *devlink;
711 struct devlink_port *devlink_port;1223 struct devlink_port *devlink_port;
@@ -723,11 +1235,11 @@ static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
723 idx++;1235 idx++;
724 continue;1236 continue;
725 }1237 }
726 err = devlink_nl_port_fill(msg, devlink, devlink_port,1238 err = devlink_nl_port_fill(msg, devlink_port,
727 DEVLINK_CMD_NEW,1239 DEVLINK_CMD_NEW,
728 NETLINK_CB(cb->skb).portid,1240 NETLINK_CB(cb->skb).portid,
729 cb->nlh->nlmsg_seq,1241 cb->nlh->nlmsg_seq,
730 NLM_F_MULTI);1242 NLM_F_MULTI, cb->extack);
731 if (err) {1243 if (err) {
732 mutex_unlock(&devlink->lock);1244 mutex_unlock(&devlink->lock);
733 goto out;1245 goto out;
@@ -765,10 +1277,95 @@ static int devlink_port_type_set(struct devlink *devlink,
765 return -EOPNOTSUPP;1277 return -EOPNOTSUPP;
766}1278}
7671279
1280static int
1281devlink_port_function_hw_addr_set(struct devlink *devlink, struct devlink_port *port,
1282 const struct nlattr *attr, struct netlink_ext_ack *extack)
1283{
1284 const struct devlink_ops *ops;
1285 const u8 *hw_addr;
1286 int hw_addr_len;
1287
1288 hw_addr = nla_data(attr);
1289 hw_addr_len = nla_len(attr);
1290 if (hw_addr_len > MAX_ADDR_LEN) {
1291 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
1292 return -EINVAL;
1293 }
1294 if (port->type == DEVLINK_PORT_TYPE_ETH) {
1295 if (hw_addr_len != ETH_ALEN) {
1296 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
1297 return -EINVAL;
1298 }
1299 if (!is_unicast_ether_addr(hw_addr)) {
1300 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
1301 return -EINVAL;
1302 }
1303 }
1304
1305 ops = devlink->ops;
1306 if (!ops->port_function_hw_addr_set) {
1307 NL_SET_ERR_MSG_MOD(extack, "Port doesn't support function attributes");
1308 return -EOPNOTSUPP;
1309 }
1310
1311 return ops->port_function_hw_addr_set(devlink, port, hw_addr, hw_addr_len, extack);
1312}
1313
1314static int devlink_port_fn_state_set(struct devlink *devlink,
1315 struct devlink_port *port,
1316 const struct nlattr *attr,
1317 struct netlink_ext_ack *extack)
1318{
1319 enum devlink_port_fn_state state;
1320 const struct devlink_ops *ops;
1321
1322 state = nla_get_u8(attr);
1323 ops = devlink->ops;
1324 if (!ops->port_fn_state_set) {
1325 NL_SET_ERR_MSG_MOD(extack,
1326 "Function does not support state setting");
1327 return -EOPNOTSUPP;
1328 }
1329 return ops->port_fn_state_set(devlink, port, state, extack);
1330}
1331
1332static int
1333devlink_port_function_set(struct devlink *devlink, struct devlink_port *port,
1334 const struct nlattr *attr, struct netlink_ext_ack *extack)
1335{
1336 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1337 int err;
1338
1339 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1340 devlink_function_nl_policy, extack);
1341 if (err < 0) {
1342 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
1343 return err;
1344 }
1345
1346 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1347 if (attr) {
1348 err = devlink_port_function_hw_addr_set(devlink, port, attr, extack);
1349 if (err)
1350 return err;
1351 }
1352 /* Keep this as the last function attribute set, so that when
1353 * multiple port function attributes are set along with state,
1354 * Those can be applied first before activating the state.
1355 */
1356 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1357 if (attr)
1358 err = devlink_port_fn_state_set(devlink, port, attr, extack);
1359
1360 if (!err)
1361 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1362 return err;
1363}
1364
768static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,1365static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
769 struct genl_info *info)1366 struct genl_info *info)
770{1367{
771 struct devlink_port *devlink_port = info->user_ptr[0];1368 struct devlink_port *devlink_port = info->user_ptr[1];
772 struct devlink *devlink = devlink_port->devlink;1369 struct devlink *devlink = devlink_port->devlink;
773 int err;1370 int err;
7741371
@@ -780,6 +1377,16 @@ static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
780 if (err)1377 if (err)
781 return err;1378 return err;
782 }1379 }
1380
1381 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1382 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1383 struct netlink_ext_ack *extack = info->extack;
1384
1385 err = devlink_port_function_set(devlink, devlink_port, attr, extack);
1386 if (err)
1387 return err;
1388 }
1389
783 return 0;1390 return 0;
784}1391}
7851392
@@ -831,6 +1438,359 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
831 return devlink_port_unsplit(devlink, port_index, info->extack);1438 return devlink_port_unsplit(devlink, port_index, info->extack);
832}1439}
8331440
1441static int devlink_port_new_notifiy(struct devlink *devlink,
1442 unsigned int port_index,
1443 struct genl_info *info)
1444{
1445 struct devlink_port *devlink_port;
1446 struct sk_buff *msg;
1447 int err;
1448
1449 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1450 if (!msg)
1451 return -ENOMEM;
1452
1453 mutex_lock(&devlink->lock);
1454 devlink_port = devlink_port_get_by_index(devlink, port_index);
1455 if (!devlink_port) {
1456 err = -ENODEV;
1457 goto out;
1458 }
1459
1460 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1461 info->snd_portid, info->snd_seq, 0, NULL);
1462 if (err)
1463 goto out;
1464
1465 err = genlmsg_reply(msg, info);
1466 mutex_unlock(&devlink->lock);
1467 return err;
1468
1469out:
1470 mutex_unlock(&devlink->lock);
1471 nlmsg_free(msg);
1472 return err;
1473}
1474
1475static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1476 struct genl_info *info)
1477{
1478 struct netlink_ext_ack *extack = info->extack;
1479 struct devlink_port_new_attrs new_attrs = {};
1480 struct devlink *devlink = info->user_ptr[0];
1481 unsigned int new_port_index;
1482 int err;
1483
1484 if (!devlink->ops->port_new || !devlink->ops->port_del)
1485 return -EOPNOTSUPP;
1486
1487 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1488 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1489 NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified");
1490 return -EINVAL;
1491 }
1492 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1493 new_attrs.pfnum =
1494 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1495
1496 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1497 /* Port index of the new port being created by driver. */
1498 new_attrs.port_index =
1499 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1500 new_attrs.port_index_valid = true;
1501 }
1502 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1503 new_attrs.controller =
1504 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1505 new_attrs.controller_valid = true;
1506 }
1507 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1508 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1509 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1510 new_attrs.sfnum_valid = true;
1511 }
1512
1513 err = devlink->ops->port_new(devlink, &new_attrs, extack,
1514 &new_port_index);
1515 if (err)
1516 return err;
1517
1518 err = devlink_port_new_notifiy(devlink, new_port_index, info);
1519 if (err && err != -ENODEV) {
1520 /* Fail to send the response; destroy newly created port. */
1521 devlink->ops->port_del(devlink, new_port_index, extack);
1522 }
1523 return err;
1524}
1525
1526static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1527 struct genl_info *info)
1528{
1529 struct netlink_ext_ack *extack = info->extack;
1530 struct devlink *devlink = info->user_ptr[0];
1531 unsigned int port_index;
1532
1533 if (!devlink->ops->port_del)
1534 return -EOPNOTSUPP;
1535
1536 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1537 NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
1538 return -EINVAL;
1539 }
1540 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1541
1542 return devlink->ops->port_del(devlink, port_index, extack);
1543}
1544
1545static int
1546devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1547 struct genl_info *info,
1548 struct nlattr *nla_parent)
1549{
1550 struct devlink *devlink = devlink_rate->devlink;
1551 const char *parent_name = nla_data(nla_parent);
1552 const struct devlink_ops *ops = devlink->ops;
1553 size_t len = strlen(parent_name);
1554 struct devlink_rate *parent;
1555 int err = -EOPNOTSUPP;
1556
1557 parent = devlink_rate->parent;
1558 if (parent && len) {
1559 NL_SET_ERR_MSG_MOD(info->extack, "Rate object already has parent.");
1560 return -EBUSY;
1561 } else if (parent && !len) {
1562 if (devlink_rate_is_leaf(devlink_rate))
1563 err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1564 devlink_rate->priv, NULL,
1565 info->extack);
1566 else if (devlink_rate_is_node(devlink_rate))
1567 err = ops->rate_node_parent_set(devlink_rate, NULL,
1568 devlink_rate->priv, NULL,
1569 info->extack);
1570 if (err)
1571 return err;
1572
1573 refcount_dec(&parent->refcnt);
1574 devlink_rate->parent = NULL;
1575 } else if (!parent && len) {
1576 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1577 if (IS_ERR(parent))
1578 return -ENODEV;
1579
1580 if (parent == devlink_rate) {
1581 NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
1582 return -EINVAL;
1583 }
1584
1585 if (devlink_rate_is_node(devlink_rate) &&
1586 devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1587 NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node.");
1588 return -EEXIST;
1589 }
1590
1591 if (devlink_rate_is_leaf(devlink_rate))
1592 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1593 devlink_rate->priv, parent->priv,
1594 info->extack);
1595 else if (devlink_rate_is_node(devlink_rate))
1596 err = ops->rate_node_parent_set(devlink_rate, parent,
1597 devlink_rate->priv, parent->priv,
1598 info->extack);
1599 if (err)
1600 return err;
1601
1602 refcount_inc(&parent->refcnt);
1603 devlink_rate->parent = parent;
1604 }
1605
1606 return 0;
1607}
1608
1609static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1610 const struct devlink_ops *ops,
1611 struct genl_info *info)
1612{
1613 struct nlattr *nla_parent, **attrs = info->attrs;
1614 int err = -EOPNOTSUPP;
1615 u64 rate;
1616
1617 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1618 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1619 if (devlink_rate_is_leaf(devlink_rate))
1620 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1621 rate, info->extack);
1622 else if (devlink_rate_is_node(devlink_rate))
1623 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1624 rate, info->extack);
1625 if (err)
1626 return err;
1627 devlink_rate->tx_share = rate;
1628 }
1629
1630 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1631 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1632 if (devlink_rate_is_leaf(devlink_rate))
1633 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1634 rate, info->extack);
1635 else if (devlink_rate_is_node(devlink_rate))
1636 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1637 rate, info->extack);
1638 if (err)
1639 return err;
1640 devlink_rate->tx_max = rate;
1641 }
1642
1643 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1644 if (nla_parent) {
1645 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1646 nla_parent);
1647 if (err)
1648 return err;
1649 }
1650
1651 return 0;
1652}
1653
1654static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1655 struct genl_info *info,
1656 enum devlink_rate_type type)
1657{
1658 struct nlattr **attrs = info->attrs;
1659
1660 if (type == DEVLINK_RATE_TYPE_LEAF) {
1661 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1662 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs");
1663 return false;
1664 }
1665 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1666 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs");
1667 return false;
1668 }
1669 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1670 !ops->rate_leaf_parent_set) {
1671 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
1672 return false;
1673 }
1674 } else if (type == DEVLINK_RATE_TYPE_NODE) {
1675 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1676 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
1677 return false;
1678 }
1679 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1680 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes");
1681 return false;
1682 }
1683 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1684 !ops->rate_node_parent_set) {
1685 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
1686 return false;
1687 }
1688 } else {
1689 WARN_ON("Unknown type of rate object");
1690 return false;
1691 }
1692
1693 return true;
1694}
1695
1696static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
1697 struct genl_info *info)
1698{
1699 struct devlink_rate *devlink_rate = info->user_ptr[1];
1700 struct devlink *devlink = devlink_rate->devlink;
1701 const struct devlink_ops *ops = devlink->ops;
1702 int err;
1703
1704 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
1705 return -EOPNOTSUPP;
1706
1707 err = devlink_nl_rate_set(devlink_rate, ops, info);
1708
1709 if (!err)
1710 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
1711 return err;
1712}
1713
1714static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
1715 struct genl_info *info)
1716{
1717 struct devlink *devlink = info->user_ptr[0];
1718 struct devlink_rate *rate_node;
1719 const struct devlink_ops *ops;
1720 int err;
1721
1722 ops = devlink->ops;
1723 if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
1724 NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported");
1725 return -EOPNOTSUPP;
1726 }
1727
1728 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
1729 return -EOPNOTSUPP;
1730
1731 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
1732 if (!IS_ERR(rate_node))
1733 return -EEXIST;
1734 else if (rate_node == ERR_PTR(-EINVAL))
1735 return -EINVAL;
1736
1737 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
1738 if (!rate_node)
1739 return -ENOMEM;
1740
1741 rate_node->devlink = devlink;
1742 rate_node->type = DEVLINK_RATE_TYPE_NODE;
1743 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
1744 if (!rate_node->name) {
1745 err = -ENOMEM;
1746 goto err_strdup;
1747 }
1748
1749 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
1750 if (err)
1751 goto err_node_new;
1752
1753 err = devlink_nl_rate_set(rate_node, ops, info);
1754 if (err)
1755 goto err_rate_set;
1756
1757 refcount_set(&rate_node->refcnt, 1);
1758 list_add(&rate_node->list, &devlink->rate_list);
1759 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
1760 return 0;
1761
1762err_rate_set:
1763 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1764err_node_new:
1765 kfree(rate_node->name);
1766err_strdup:
1767 kfree(rate_node);
1768 return err;
1769}
1770
1771static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
1772 struct genl_info *info)
1773{
1774 struct devlink_rate *rate_node = info->user_ptr[1];
1775 struct devlink *devlink = rate_node->devlink;
1776 const struct devlink_ops *ops = devlink->ops;
1777 int err;
1778
1779 if (refcount_read(&rate_node->refcnt) > 1) {
1780 NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
1781 return -EBUSY;
1782 }
1783
1784 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
1785 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1786 if (rate_node->parent)
1787 refcount_dec(&rate_node->parent->refcnt);
1788 list_del(&rate_node->list);
1789 kfree(rate_node->name);
1790 kfree(rate_node);
1791 return err;
1792}
1793
834static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,1794static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
835 struct devlink_sb *devlink_sb,1795 struct devlink_sb *devlink_sb,
836 enum devlink_command cmd, u32 portid,1796 enum devlink_command cmd, u32 portid,
@@ -873,10 +1833,14 @@ static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
873 struct genl_info *info)1833 struct genl_info *info)
874{1834{
875 struct devlink *devlink = info->user_ptr[0];1835 struct devlink *devlink = info->user_ptr[0];
876 struct devlink_sb *devlink_sb = info->user_ptr[1];1836 struct devlink_sb *devlink_sb;
877 struct sk_buff *msg;1837 struct sk_buff *msg;
878 int err;1838 int err;
8791839
1840 devlink_sb = devlink_sb_get_from_info(devlink, info);
1841 if (IS_ERR(devlink_sb))
1842 return PTR_ERR(devlink_sb);
1843
880 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);1844 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
881 if (!msg)1845 if (!msg)
882 return -ENOMEM;1846 return -ENOMEM;
@@ -978,11 +1942,15 @@ static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
978 struct genl_info *info)1942 struct genl_info *info)
979{1943{
980 struct devlink *devlink = info->user_ptr[0];1944 struct devlink *devlink = info->user_ptr[0];
981 struct devlink_sb *devlink_sb = info->user_ptr[1];1945 struct devlink_sb *devlink_sb;
982 struct sk_buff *msg;1946 struct sk_buff *msg;
983 u16 pool_index;1947 u16 pool_index;
984 int err;1948 int err;
9851949
1950 devlink_sb = devlink_sb_get_from_info(devlink, info);
1951 if (IS_ERR(devlink_sb))
1952 return PTR_ERR(devlink_sb);
1953
986 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,1954 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
987 &pool_index);1955 &pool_index);
988 if (err)1956 if (err)
@@ -1052,7 +2020,9 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1052 devlink_sb,2020 devlink_sb,
1053 NETLINK_CB(cb->skb).portid,2021 NETLINK_CB(cb->skb).portid,
1054 cb->nlh->nlmsg_seq);2022 cb->nlh->nlmsg_seq);
1055 if (err && err != -EOPNOTSUPP) {2023 if (err == -EOPNOTSUPP) {
2024 err = 0;
2025 } else if (err) {
1056 mutex_unlock(&devlink->lock);2026 mutex_unlock(&devlink->lock);
1057 goto out;2027 goto out;
1058 }2028 }
@@ -1084,12 +2054,16 @@ static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1084 struct genl_info *info)2054 struct genl_info *info)
1085{2055{
1086 struct devlink *devlink = info->user_ptr[0];2056 struct devlink *devlink = info->user_ptr[0];
1087 struct devlink_sb *devlink_sb = info->user_ptr[1];
1088 enum devlink_sb_threshold_type threshold_type;2057 enum devlink_sb_threshold_type threshold_type;
2058 struct devlink_sb *devlink_sb;
1089 u16 pool_index;2059 u16 pool_index;
1090 u32 size;2060 u32 size;
1091 int err;2061 int err;
10922062
2063 devlink_sb = devlink_sb_get_from_info(devlink, info);
2064 if (IS_ERR(devlink_sb))
2065 return PTR_ERR(devlink_sb);
2066
1093 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,2067 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1094 &pool_index);2068 &pool_index);
1095 if (err)2069 if (err)
@@ -1170,13 +2144,17 @@ sb_occ_get_failure:
1170static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,2144static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1171 struct genl_info *info)2145 struct genl_info *info)
1172{2146{
1173 struct devlink_port *devlink_port = info->user_ptr[0];2147 struct devlink_port *devlink_port = info->user_ptr[1];
1174 struct devlink *devlink = devlink_port->devlink;2148 struct devlink *devlink = devlink_port->devlink;
1175 struct devlink_sb *devlink_sb = info->user_ptr[1];2149 struct devlink_sb *devlink_sb;
1176 struct sk_buff *msg;2150 struct sk_buff *msg;
1177 u16 pool_index;2151 u16 pool_index;
1178 int err;2152 int err;
11792153
2154 devlink_sb = devlink_sb_get_from_info(devlink, info);
2155 if (IS_ERR(devlink_sb))
2156 return PTR_ERR(devlink_sb);
2157
1180 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,2158 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1181 &pool_index);2159 &pool_index);
1182 if (err)2160 if (err)
@@ -1252,7 +2230,9 @@ static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1252 devlink, devlink_sb,2230 devlink, devlink_sb,
1253 NETLINK_CB(cb->skb).portid,2231 NETLINK_CB(cb->skb).portid,
1254 cb->nlh->nlmsg_seq);2232 cb->nlh->nlmsg_seq);
1255 if (err && err != -EOPNOTSUPP) {2233 if (err == -EOPNOTSUPP) {
2234 err = 0;
2235 } else if (err) {
1256 mutex_unlock(&devlink->lock);2236 mutex_unlock(&devlink->lock);
1257 goto out;2237 goto out;
1258 }2238 }
@@ -1283,12 +2263,17 @@ static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1283static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,2263static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1284 struct genl_info *info)2264 struct genl_info *info)
1285{2265{
1286 struct devlink_port *devlink_port = info->user_ptr[0];2266 struct devlink_port *devlink_port = info->user_ptr[1];
1287 struct devlink_sb *devlink_sb = info->user_ptr[1];2267 struct devlink *devlink = info->user_ptr[0];
2268 struct devlink_sb *devlink_sb;
1288 u16 pool_index;2269 u16 pool_index;
1289 u32 threshold;2270 u32 threshold;
1290 int err;2271 int err;
12912272
2273 devlink_sb = devlink_sb_get_from_info(devlink, info);
2274 if (IS_ERR(devlink_sb))
2275 return PTR_ERR(devlink_sb);
2276
1292 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,2277 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1293 &pool_index);2278 &pool_index);
1294 if (err)2279 if (err)
@@ -1370,14 +2355,18 @@ nla_put_failure:
1370static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,2355static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1371 struct genl_info *info)2356 struct genl_info *info)
1372{2357{
1373 struct devlink_port *devlink_port = info->user_ptr[0];2358 struct devlink_port *devlink_port = info->user_ptr[1];
1374 struct devlink *devlink = devlink_port->devlink;2359 struct devlink *devlink = devlink_port->devlink;
1375 struct devlink_sb *devlink_sb = info->user_ptr[1];2360 struct devlink_sb *devlink_sb;
1376 struct sk_buff *msg;2361 struct sk_buff *msg;
1377 enum devlink_sb_pool_type pool_type;2362 enum devlink_sb_pool_type pool_type;
1378 u16 tc_index;2363 u16 tc_index;
1379 int err;2364 int err;
13802365
2366 devlink_sb = devlink_sb_get_from_info(devlink, info);
2367 if (IS_ERR(devlink_sb))
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: