]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - include/net/switchdev.h
Merge tag 'pm-5.11-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[mirror_ubuntu-jammy-kernel.git] / include / net / switchdev.h
CommitLineData
2874c5fd 1/* SPDX-License-Identifier: GPL-2.0-or-later */
007f790c
JP
2/*
3 * include/net/switchdev.h - Switch device API
7ea6eb3f 4 * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
f8f21471 5 * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
007f790c
JP
6 */
7#ifndef _LINUX_SWITCHDEV_H_
8#define _LINUX_SWITCHDEV_H_
9
10#include <linux/netdevice.h>
03bf0c28 11#include <linux/notifier.h>
7ea6eb3f 12#include <linux/list.h>
850d0cbc 13#include <net/ip_fib.h>
03bf0c28 14
3094333d 15#define SWITCHDEV_F_NO_RECURSE BIT(0)
464314ea 16#define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1)
0bc05d58 17#define SWITCHDEV_F_DEFER BIT(2)
3094333d 18
7ea6eb3f 19struct switchdev_trans {
f623ab7f 20 bool ph_prepare;
7ea6eb3f
JP
21};
22
8bdb4272
JP
23static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans)
24{
f623ab7f 25 return trans && trans->ph_prepare;
8bdb4272
JP
26}
27
28static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
29{
f623ab7f 30 return trans && !trans->ph_prepare;
8bdb4272
JP
31}
32
3094333d 33enum switchdev_attr_id {
1f868398 34 SWITCHDEV_ATTR_ID_UNDEFINED,
1f868398
JP
35 SWITCHDEV_ATTR_ID_PORT_STP_STATE,
36 SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
746dc184 37 SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS,
6d549648 38 SWITCHDEV_ATTR_ID_PORT_MROUTER,
f55ac58a 39 SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
81435c33 40 SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
22ec19f3 41 SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL,
147c1e9b 42 SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
77041420 43 SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
c284b545 44#if IS_ENABLED(CONFIG_BRIDGE_MRP)
c284b545
HV
45 SWITCHDEV_ATTR_ID_MRP_PORT_ROLE,
46#endif
3094333d
SF
47};
48
49struct switchdev_attr {
6ff64f6f 50 struct net_device *orig_dev;
3094333d 51 enum switchdev_attr_id id;
3094333d 52 u32 flags;
7ceb2afb
ER
53 void *complete_priv;
54 void (*complete)(struct net_device *dev, int err, void *priv);
f8e20a9f 55 union {
35636062 56 u8 stp_state; /* PORT_STP_STATE */
746dc184 57 unsigned long brport_flags; /* PORT_{PRE}_BRIDGE_FLAGS */
6d549648 58 bool mrouter; /* PORT_MROUTER */
eabfdda9 59 clock_t ageing_time; /* BRIDGE_AGEING_TIME */
81435c33 60 bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
22ec19f3 61 u16 vlan_protocol; /* BRIDGE_VLAN_PROTOCOL */
147c1e9b 62 bool mc_disabled; /* MC_DISABLED */
c284b545 63#if IS_ENABLED(CONFIG_BRIDGE_MRP)
c284b545 64 u8 mrp_port_role; /* MRP_PORT_ROLE */
c284b545 65#endif
42275bd8 66 } u;
3094333d
SF
67};
68
491d0f15 69enum switchdev_obj_id {
57d80838
JP
70 SWITCHDEV_OBJ_ID_UNDEFINED,
71 SWITCHDEV_OBJ_ID_PORT_VLAN,
4d41e125 72 SWITCHDEV_OBJ_ID_PORT_MDB,
47d5b6db 73 SWITCHDEV_OBJ_ID_HOST_MDB,
c284b545
HV
74#if IS_ENABLED(CONFIG_BRIDGE_MRP)
75 SWITCHDEV_OBJ_ID_MRP,
76 SWITCHDEV_OBJ_ID_RING_TEST_MRP,
77 SWITCHDEV_OBJ_ID_RING_ROLE_MRP,
78 SWITCHDEV_OBJ_ID_RING_STATE_MRP,
cf7c5274
HV
79 SWITCHDEV_OBJ_ID_IN_TEST_MRP,
80 SWITCHDEV_OBJ_ID_IN_ROLE_MRP,
81 SWITCHDEV_OBJ_ID_IN_STATE_MRP,
82
c284b545 83#endif
491d0f15
SF
84};
85
648b4a99 86struct switchdev_obj {
6ff64f6f 87 struct net_device *orig_dev;
9e8f4a54 88 enum switchdev_obj_id id;
4d429c5d 89 u32 flags;
7ceb2afb
ER
90 void *complete_priv;
91 void (*complete)(struct net_device *dev, int err, void *priv);
648b4a99
JP
92};
93
57d80838 94/* SWITCHDEV_OBJ_ID_PORT_VLAN */
8f24f309 95struct switchdev_obj_port_vlan {
648b4a99 96 struct switchdev_obj obj;
44bbcf5c
VD
97 u16 flags;
98 u16 vid_begin;
99 u16 vid_end;
100};
101
ec394af5
PM
102#define SWITCHDEV_OBJ_PORT_VLAN(OBJ) \
103 container_of((OBJ), struct switchdev_obj_port_vlan, obj)
648b4a99 104
4d41e125
ER
105/* SWITCHDEV_OBJ_ID_PORT_MDB */
106struct switchdev_obj_port_mdb {
107 struct switchdev_obj obj;
108 unsigned char addr[ETH_ALEN];
109 u16 vid;
110};
111
ec394af5
PM
112#define SWITCHDEV_OBJ_PORT_MDB(OBJ) \
113 container_of((OBJ), struct switchdev_obj_port_mdb, obj)
4d41e125 114
c284b545
HV
115
116#if IS_ENABLED(CONFIG_BRIDGE_MRP)
117/* SWITCHDEV_OBJ_ID_MRP */
118struct switchdev_obj_mrp {
119 struct switchdev_obj obj;
120 struct net_device *p_port;
121 struct net_device *s_port;
122 u32 ring_id;
4b3a61b0 123 u16 prio;
c284b545
HV
124};
125
126#define SWITCHDEV_OBJ_MRP(OBJ) \
127 container_of((OBJ), struct switchdev_obj_mrp, obj)
128
129/* SWITCHDEV_OBJ_ID_RING_TEST_MRP */
130struct switchdev_obj_ring_test_mrp {
131 struct switchdev_obj obj;
132 /* The value is in us and a value of 0 represents to stop */
133 u32 interval;
134 u8 max_miss;
135 u32 ring_id;
136 u32 period;
c6676e7d 137 bool monitor;
c284b545
HV
138};
139
140#define SWITCHDEV_OBJ_RING_TEST_MRP(OBJ) \
141 container_of((OBJ), struct switchdev_obj_ring_test_mrp, obj)
142
143/* SWICHDEV_OBJ_ID_RING_ROLE_MRP */
144struct switchdev_obj_ring_role_mrp {
145 struct switchdev_obj obj;
146 u8 ring_role;
147 u32 ring_id;
148};
149
150#define SWITCHDEV_OBJ_RING_ROLE_MRP(OBJ) \
151 container_of((OBJ), struct switchdev_obj_ring_role_mrp, obj)
152
153struct switchdev_obj_ring_state_mrp {
154 struct switchdev_obj obj;
155 u8 ring_state;
156 u32 ring_id;
157};
158
159#define SWITCHDEV_OBJ_RING_STATE_MRP(OBJ) \
160 container_of((OBJ), struct switchdev_obj_ring_state_mrp, obj)
161
cf7c5274
HV
162/* SWITCHDEV_OBJ_ID_IN_TEST_MRP */
163struct switchdev_obj_in_test_mrp {
164 struct switchdev_obj obj;
165 /* The value is in us and a value of 0 represents to stop */
166 u32 interval;
167 u32 in_id;
168 u32 period;
169 u8 max_miss;
170};
171
172#define SWITCHDEV_OBJ_IN_TEST_MRP(OBJ) \
173 container_of((OBJ), struct switchdev_obj_in_test_mrp, obj)
174
175/* SWICHDEV_OBJ_ID_IN_ROLE_MRP */
176struct switchdev_obj_in_role_mrp {
177 struct switchdev_obj obj;
178 struct net_device *i_port;
179 u32 ring_id;
180 u16 in_id;
181 u8 in_role;
182};
183
184#define SWITCHDEV_OBJ_IN_ROLE_MRP(OBJ) \
185 container_of((OBJ), struct switchdev_obj_in_role_mrp, obj)
186
187struct switchdev_obj_in_state_mrp {
188 struct switchdev_obj obj;
189 u32 in_id;
190 u8 in_state;
191};
192
193#define SWITCHDEV_OBJ_IN_STATE_MRP(OBJ) \
194 container_of((OBJ), struct switchdev_obj_in_state_mrp, obj)
195
c284b545
HV
196#endif
197
648b4a99
JP
198typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
199
ebb9a03a 200enum switchdev_notifier_type {
6b26b51b
AS
201 SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
202 SWITCHDEV_FDB_DEL_TO_BRIDGE,
203 SWITCHDEV_FDB_ADD_TO_DEVICE,
204 SWITCHDEV_FDB_DEL_TO_DEVICE,
9fe8bcec 205 SWITCHDEV_FDB_OFFLOADED,
d05e8e68 206 SWITCHDEV_FDB_FLUSH_TO_BRIDGE,
9a997353 207
aa4efe21
PM
208 SWITCHDEV_PORT_OBJ_ADD, /* Blocking. */
209 SWITCHDEV_PORT_OBJ_DEL, /* Blocking. */
1cb33af1 210 SWITCHDEV_PORT_ATTR_SET, /* May be blocking . */
aa4efe21 211
5728ae0d
PM
212 SWITCHDEV_VXLAN_FDB_ADD_TO_BRIDGE,
213 SWITCHDEV_VXLAN_FDB_DEL_TO_BRIDGE,
9a997353
PM
214 SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
215 SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE,
0efe1173 216 SWITCHDEV_VXLAN_FDB_OFFLOADED,
3aeb6617
JP
217};
218
ebb9a03a 219struct switchdev_notifier_info {
03bf0c28 220 struct net_device *dev;
479c86dc 221 struct netlink_ext_ack *extack;
03bf0c28
JP
222};
223
ebb9a03a
JP
224struct switchdev_notifier_fdb_info {
225 struct switchdev_notifier_info info; /* must be first */
3aeb6617
JP
226 const unsigned char *addr;
227 u16 vid;
e9ba0fbc
IS
228 u8 added_by_user:1,
229 offloaded:1;
3aeb6617
JP
230};
231
aa4efe21
PM
232struct switchdev_notifier_port_obj_info {
233 struct switchdev_notifier_info info; /* must be first */
234 const struct switchdev_obj *obj;
235 struct switchdev_trans *trans;
236 bool handled;
237};
238
1cb33af1
FF
239struct switchdev_notifier_port_attr_info {
240 struct switchdev_notifier_info info; /* must be first */
241 const struct switchdev_attr *attr;
242 struct switchdev_trans *trans;
243 bool handled;
244};
245
03bf0c28 246static inline struct net_device *
ebb9a03a 247switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
03bf0c28
JP
248{
249 return info->dev;
250}
007f790c 251
479c86dc
PM
252static inline struct netlink_ext_ack *
253switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
254{
255 return info->extack;
256}
257
007f790c
JP
258#ifdef CONFIG_NET_SWITCHDEV
259
793f4014 260void switchdev_deferred_process(void);
3094333d 261int switchdev_port_attr_set(struct net_device *dev,
f7fadf30 262 const struct switchdev_attr *attr);
9e8f4a54 263int switchdev_port_obj_add(struct net_device *dev,
69b7320e
PM
264 const struct switchdev_obj *obj,
265 struct netlink_ext_ack *extack);
9e8f4a54 266int switchdev_port_obj_del(struct net_device *dev,
648b4a99 267 const struct switchdev_obj *obj);
a93e3b17 268
ebb9a03a
JP
269int register_switchdev_notifier(struct notifier_block *nb);
270int unregister_switchdev_notifier(struct notifier_block *nb);
271int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
6685987c
PM
272 struct switchdev_notifier_info *info,
273 struct netlink_ext_ack *extack);
a93e3b17
PM
274
275int register_switchdev_blocking_notifier(struct notifier_block *nb);
276int unregister_switchdev_blocking_notifier(struct notifier_block *nb);
277int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
479c86dc
PM
278 struct switchdev_notifier_info *info,
279 struct netlink_ext_ack *extack);
a93e3b17 280
1a3b2ec9
SF
281void switchdev_port_fwd_mark_set(struct net_device *dev,
282 struct net_device *group_dev,
283 bool joining);
5e8d9049 284
f30f0601
PM
285int switchdev_handle_port_obj_add(struct net_device *dev,
286 struct switchdev_notifier_port_obj_info *port_obj_info,
287 bool (*check_cb)(const struct net_device *dev),
288 int (*add_cb)(struct net_device *dev,
289 const struct switchdev_obj *obj,
69213513
PM
290 struct switchdev_trans *trans,
291 struct netlink_ext_ack *extack));
f30f0601
PM
292int switchdev_handle_port_obj_del(struct net_device *dev,
293 struct switchdev_notifier_port_obj_info *port_obj_info,
294 bool (*check_cb)(const struct net_device *dev),
295 int (*del_cb)(struct net_device *dev,
296 const struct switchdev_obj *obj));
297
1cb33af1
FF
298int switchdev_handle_port_attr_set(struct net_device *dev,
299 struct switchdev_notifier_port_attr_info *port_attr_info,
300 bool (*check_cb)(const struct net_device *dev),
301 int (*set_cb)(struct net_device *dev,
302 const struct switchdev_attr *attr,
303 struct switchdev_trans *trans));
007f790c
JP
304#else
305
793f4014
JP
306static inline void switchdev_deferred_process(void)
307{
308}
309
3094333d 310static inline int switchdev_port_attr_set(struct net_device *dev,
f7fadf30 311 const struct switchdev_attr *attr)
3094333d
SF
312{
313 return -EOPNOTSUPP;
314}
315
491d0f15 316static inline int switchdev_port_obj_add(struct net_device *dev,
69b7320e
PM
317 const struct switchdev_obj *obj,
318 struct netlink_ext_ack *extack)
491d0f15
SF
319{
320 return -EOPNOTSUPP;
321}
322
323static inline int switchdev_port_obj_del(struct net_device *dev,
648b4a99 324 const struct switchdev_obj *obj)
491d0f15
SF
325{
326 return -EOPNOTSUPP;
327}
328
ebb9a03a 329static inline int register_switchdev_notifier(struct notifier_block *nb)
03bf0c28
JP
330{
331 return 0;
332}
333
ebb9a03a 334static inline int unregister_switchdev_notifier(struct notifier_block *nb)
03bf0c28
JP
335{
336 return 0;
337}
338
ebb9a03a
JP
339static inline int call_switchdev_notifiers(unsigned long val,
340 struct net_device *dev,
6685987c
PM
341 struct switchdev_notifier_info *info,
342 struct netlink_ext_ack *extack)
03bf0c28
JP
343{
344 return NOTIFY_DONE;
345}
346
a93e3b17
PM
347static inline int
348register_switchdev_blocking_notifier(struct notifier_block *nb)
349{
350 return 0;
351}
352
353static inline int
354unregister_switchdev_blocking_notifier(struct notifier_block *nb)
355{
356 return 0;
357}
358
359static inline int
360call_switchdev_blocking_notifiers(unsigned long val,
361 struct net_device *dev,
479c86dc
PM
362 struct switchdev_notifier_info *info,
363 struct netlink_ext_ack *extack)
a93e3b17
PM
364{
365 return NOTIFY_DONE;
366}
367
f30f0601
PM
368static inline int
369switchdev_handle_port_obj_add(struct net_device *dev,
370 struct switchdev_notifier_port_obj_info *port_obj_info,
371 bool (*check_cb)(const struct net_device *dev),
372 int (*add_cb)(struct net_device *dev,
373 const struct switchdev_obj *obj,
69213513
PM
374 struct switchdev_trans *trans,
375 struct netlink_ext_ack *extack))
f30f0601
PM
376{
377 return 0;
378}
379
380static inline int
381switchdev_handle_port_obj_del(struct net_device *dev,
382 struct switchdev_notifier_port_obj_info *port_obj_info,
383 bool (*check_cb)(const struct net_device *dev),
384 int (*del_cb)(struct net_device *dev,
385 const struct switchdev_obj *obj))
386{
387 return 0;
388}
389
1cb33af1
FF
390static inline int
391switchdev_handle_port_attr_set(struct net_device *dev,
392 struct switchdev_notifier_port_attr_info *port_attr_info,
393 bool (*check_cb)(const struct net_device *dev),
394 int (*set_cb)(struct net_device *dev,
395 const struct switchdev_attr *attr,
396 struct switchdev_trans *trans))
397{
398 return 0;
399}
007f790c
JP
400#endif
401
402#endif /* _LINUX_SWITCHDEV_H_ */