blob: aee86a1894327f0ba2bee3a645e730fe6f53af60 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Jiri Pirko007f7902014-11-28 14:34:17 +01002/*
3 * include/net/switchdev.h - Switch device API
Jiri Pirko7ea6eb32015-09-24 10:02:41 +02004 * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
Scott Feldmanf8f21472015-03-09 13:59:09 -07005 * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
Jiri Pirko007f7902014-11-28 14:34:17 +01006 */
7#ifndef _LINUX_SWITCHDEV_H_
8#define _LINUX_SWITCHDEV_H_
9
10#include <linux/netdevice.h>
Jiri Pirko03bf0c22015-01-15 23:49:36 +010011#include <linux/notifier.h>
Jiri Pirko7ea6eb32015-09-24 10:02:41 +020012#include <linux/list.h>
Jiri Pirko850d0cb2015-10-14 19:40:51 +020013#include <net/ip_fib.h>
Jiri Pirko03bf0c22015-01-15 23:49:36 +010014
Scott Feldman30943332015-05-10 09:47:48 -070015#define SWITCHDEV_F_NO_RECURSE BIT(0)
Scott Feldman464314e2015-10-08 19:23:18 -070016#define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1)
Jiri Pirko0bc05d52015-10-14 19:40:50 +020017#define SWITCHDEV_F_DEFER BIT(2)
Scott Feldman30943332015-05-10 09:47:48 -070018
Jiri Pirko7ea6eb32015-09-24 10:02:41 +020019struct switchdev_trans {
Jiri Pirkof623ab72015-09-24 10:02:49 +020020 bool ph_prepare;
Jiri Pirko7ea6eb32015-09-24 10:02:41 +020021};
22
Jiri Pirko8bdb4272015-09-24 10:02:43 +020023static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans)
24{
Jiri Pirkof623ab72015-09-24 10:02:49 +020025 return trans && trans->ph_prepare;
Jiri Pirko8bdb4272015-09-24 10:02:43 +020026}
27
28static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
29{
Jiri Pirkof623ab72015-09-24 10:02:49 +020030 return trans && !trans->ph_prepare;
Jiri Pirko8bdb4272015-09-24 10:02:43 +020031}
32
Scott Feldman30943332015-05-10 09:47:48 -070033enum switchdev_attr_id {
Jiri Pirko1f868392015-10-01 11:03:42 +020034 SWITCHDEV_ATTR_ID_UNDEFINED,
Jiri Pirko1f868392015-10-01 11:03:42 +020035 SWITCHDEV_ATTR_ID_PORT_STP_STATE,
36 SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
Florian Fainelli746dc182019-02-20 16:58:19 -080037 SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS,
Nogah Frankel6d549642017-02-09 14:54:42 +010038 SWITCHDEV_ATTR_ID_PORT_MROUTER,
Scott Feldmanf55ac582015-10-08 19:23:17 -070039 SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
Elad Raz81435c32016-01-06 13:01:05 +010040 SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
Nogah Frankel147c1e92017-02-09 14:54:40 +010041 SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
Yotam Gigi77041422017-10-09 11:15:31 +020042 SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
Scott Feldman30943332015-05-10 09:47:48 -070043};
44
45struct switchdev_attr {
Ido Schimmel6ff64f62015-12-15 16:03:35 +010046 struct net_device *orig_dev;
Scott Feldman30943332015-05-10 09:47:48 -070047 enum switchdev_attr_id id;
Scott Feldman30943332015-05-10 09:47:48 -070048 u32 flags;
Elad Raz7ceb2af2016-04-21 12:52:43 +020049 void *complete_priv;
50 void (*complete)(struct net_device *dev, int err, void *priv);
Scott Feldmanf8e20a92015-05-10 09:47:49 -070051 union {
Scott Feldman35636062015-05-10 09:47:51 -070052 u8 stp_state; /* PORT_STP_STATE */
Florian Fainelli746dc182019-02-20 16:58:19 -080053 unsigned long brport_flags; /* PORT_{PRE}_BRIDGE_FLAGS */
Nogah Frankel6d549642017-02-09 14:54:42 +010054 bool mrouter; /* PORT_MROUTER */
Vivien Dideloteabfdda2016-07-18 15:02:06 -040055 clock_t ageing_time; /* BRIDGE_AGEING_TIME */
Elad Raz81435c32016-01-06 13:01:05 +010056 bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
Nogah Frankel147c1e92017-02-09 14:54:40 +010057 bool mc_disabled; /* MC_DISABLED */
Scott Feldman42275bd2015-05-13 11:16:50 -070058 } u;
Scott Feldman30943332015-05-10 09:47:48 -070059};
60
Scott Feldman491d0f12015-05-10 09:47:52 -070061enum switchdev_obj_id {
Jiri Pirko57d80832015-10-01 11:03:41 +020062 SWITCHDEV_OBJ_ID_UNDEFINED,
63 SWITCHDEV_OBJ_ID_PORT_VLAN,
Elad Raz4d41e1252016-01-10 21:06:22 +010064 SWITCHDEV_OBJ_ID_PORT_MDB,
Andrew Lunn47d5b6d2017-11-09 23:10:59 +010065 SWITCHDEV_OBJ_ID_HOST_MDB,
Scott Feldman491d0f12015-05-10 09:47:52 -070066};
67
Jiri Pirko648b4a92015-10-01 11:03:45 +020068struct switchdev_obj {
Ido Schimmel6ff64f62015-12-15 16:03:35 +010069 struct net_device *orig_dev;
Jiri Pirko9e8f4a52015-10-01 11:03:46 +020070 enum switchdev_obj_id id;
Jiri Pirko4d429c52015-10-14 19:40:52 +020071 u32 flags;
Elad Raz7ceb2af2016-04-21 12:52:43 +020072 void *complete_priv;
73 void (*complete)(struct net_device *dev, int err, void *priv);
Jiri Pirko648b4a92015-10-01 11:03:45 +020074};
75
Jiri Pirko57d80832015-10-01 11:03:41 +020076/* SWITCHDEV_OBJ_ID_PORT_VLAN */
Jiri Pirko8f24f302015-10-01 11:03:43 +020077struct switchdev_obj_port_vlan {
Jiri Pirko648b4a92015-10-01 11:03:45 +020078 struct switchdev_obj obj;
Vivien Didelot44bbcf52015-09-29 12:07:18 -040079 u16 flags;
80 u16 vid_begin;
81 u16 vid_end;
82};
83
Petr Machataec394af2018-11-22 23:28:07 +000084#define SWITCHDEV_OBJ_PORT_VLAN(OBJ) \
85 container_of((OBJ), struct switchdev_obj_port_vlan, obj)
Jiri Pirko648b4a92015-10-01 11:03:45 +020086
Elad Raz4d41e1252016-01-10 21:06:22 +010087/* SWITCHDEV_OBJ_ID_PORT_MDB */
88struct switchdev_obj_port_mdb {
89 struct switchdev_obj obj;
90 unsigned char addr[ETH_ALEN];
91 u16 vid;
92};
93
Petr Machataec394af2018-11-22 23:28:07 +000094#define SWITCHDEV_OBJ_PORT_MDB(OBJ) \
95 container_of((OBJ), struct switchdev_obj_port_mdb, obj)
Elad Raz4d41e1252016-01-10 21:06:22 +010096
Jiri Pirko648b4a92015-10-01 11:03:45 +020097typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
98
Jiri Pirkoebb9a032015-05-10 09:47:46 -070099enum switchdev_notifier_type {
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +0200100 SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
101 SWITCHDEV_FDB_DEL_TO_BRIDGE,
102 SWITCHDEV_FDB_ADD_TO_DEVICE,
103 SWITCHDEV_FDB_DEL_TO_DEVICE,
Arkadi Sharshevsky9fe8bce2017-06-08 08:44:15 +0200104 SWITCHDEV_FDB_OFFLOADED,
Petr Machata9a997352018-10-17 08:53:22 +0000105
Petr Machataaa4efe22018-11-22 23:28:38 +0000106 SWITCHDEV_PORT_OBJ_ADD, /* Blocking. */
107 SWITCHDEV_PORT_OBJ_DEL, /* Blocking. */
Florian Fainelli1cb33af2019-02-27 11:44:25 -0800108 SWITCHDEV_PORT_ATTR_SET, /* May be blocking . */
Petr Machataaa4efe22018-11-22 23:28:38 +0000109
Petr Machata5728ae02018-11-21 08:02:39 +0000110 SWITCHDEV_VXLAN_FDB_ADD_TO_BRIDGE,
111 SWITCHDEV_VXLAN_FDB_DEL_TO_BRIDGE,
Petr Machata9a997352018-10-17 08:53:22 +0000112 SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
113 SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE,
Petr Machata0efe1172018-10-17 08:53:26 +0000114 SWITCHDEV_VXLAN_FDB_OFFLOADED,
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100115};
116
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700117struct switchdev_notifier_info {
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100118 struct net_device *dev;
Petr Machata479c86d2018-12-12 17:02:54 +0000119 struct netlink_ext_ack *extack;
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100120};
121
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700122struct switchdev_notifier_fdb_info {
123 struct switchdev_notifier_info info; /* must be first */
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100124 const unsigned char *addr;
125 u16 vid;
Ido Schimmele9ba0fb2018-10-17 08:53:29 +0000126 u8 added_by_user:1,
127 offloaded:1;
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100128};
129
Petr Machataaa4efe22018-11-22 23:28:38 +0000130struct switchdev_notifier_port_obj_info {
131 struct switchdev_notifier_info info; /* must be first */
132 const struct switchdev_obj *obj;
133 struct switchdev_trans *trans;
134 bool handled;
135};
136
Florian Fainelli1cb33af2019-02-27 11:44:25 -0800137struct switchdev_notifier_port_attr_info {
138 struct switchdev_notifier_info info; /* must be first */
139 const struct switchdev_attr *attr;
140 struct switchdev_trans *trans;
141 bool handled;
142};
143
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100144static inline struct net_device *
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700145switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100146{
147 return info->dev;
148}
Jiri Pirko007f7902014-11-28 14:34:17 +0100149
Petr Machata479c86d2018-12-12 17:02:54 +0000150static inline struct netlink_ext_ack *
151switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
152{
153 return info->extack;
154}
155
Jiri Pirko007f7902014-11-28 14:34:17 +0100156#ifdef CONFIG_NET_SWITCHDEV
157
Jiri Pirko793f4012015-10-14 19:40:48 +0200158void switchdev_deferred_process(void);
Scott Feldman30943332015-05-10 09:47:48 -0700159int switchdev_port_attr_set(struct net_device *dev,
Jiri Pirkof7fadf32015-10-14 19:40:49 +0200160 const struct switchdev_attr *attr);
Jiri Pirko9e8f4a52015-10-01 11:03:46 +0200161int switchdev_port_obj_add(struct net_device *dev,
Petr Machata69b73202018-12-12 17:02:52 +0000162 const struct switchdev_obj *obj,
163 struct netlink_ext_ack *extack);
Jiri Pirko9e8f4a52015-10-01 11:03:46 +0200164int switchdev_port_obj_del(struct net_device *dev,
Jiri Pirko648b4a92015-10-01 11:03:45 +0200165 const struct switchdev_obj *obj);
Petr Machataa93e3b12018-11-22 23:28:25 +0000166
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700167int register_switchdev_notifier(struct notifier_block *nb);
168int unregister_switchdev_notifier(struct notifier_block *nb);
169int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
Petr Machata66859872019-01-16 23:06:56 +0000170 struct switchdev_notifier_info *info,
171 struct netlink_ext_ack *extack);
Petr Machataa93e3b12018-11-22 23:28:25 +0000172
173int register_switchdev_blocking_notifier(struct notifier_block *nb);
174int unregister_switchdev_blocking_notifier(struct notifier_block *nb);
175int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
Petr Machata479c86d2018-12-12 17:02:54 +0000176 struct switchdev_notifier_info *info,
177 struct netlink_ext_ack *extack);
Petr Machataa93e3b12018-11-22 23:28:25 +0000178
Scott Feldman1a3b2ec2015-07-18 18:24:50 -0700179void switchdev_port_fwd_mark_set(struct net_device *dev,
180 struct net_device *group_dev,
181 bool joining);
Scott Feldman5e8d9042015-03-05 21:21:15 -0800182
Petr Machataf30f0602018-11-22 23:29:44 +0000183int switchdev_handle_port_obj_add(struct net_device *dev,
184 struct switchdev_notifier_port_obj_info *port_obj_info,
185 bool (*check_cb)(const struct net_device *dev),
186 int (*add_cb)(struct net_device *dev,
187 const struct switchdev_obj *obj,
Petr Machata69213512018-12-12 17:02:56 +0000188 struct switchdev_trans *trans,
189 struct netlink_ext_ack *extack));
Petr Machataf30f0602018-11-22 23:29:44 +0000190int switchdev_handle_port_obj_del(struct net_device *dev,
191 struct switchdev_notifier_port_obj_info *port_obj_info,
192 bool (*check_cb)(const struct net_device *dev),
193 int (*del_cb)(struct net_device *dev,
194 const struct switchdev_obj *obj));
195
Florian Fainelli1cb33af2019-02-27 11:44:25 -0800196int switchdev_handle_port_attr_set(struct net_device *dev,
197 struct switchdev_notifier_port_attr_info *port_attr_info,
198 bool (*check_cb)(const struct net_device *dev),
199 int (*set_cb)(struct net_device *dev,
200 const struct switchdev_attr *attr,
201 struct switchdev_trans *trans));
Jiri Pirko007f7902014-11-28 14:34:17 +0100202#else
203
Jiri Pirko793f4012015-10-14 19:40:48 +0200204static inline void switchdev_deferred_process(void)
205{
206}
207
Scott Feldman30943332015-05-10 09:47:48 -0700208static inline int switchdev_port_attr_set(struct net_device *dev,
Jiri Pirkof7fadf32015-10-14 19:40:49 +0200209 const struct switchdev_attr *attr)
Scott Feldman30943332015-05-10 09:47:48 -0700210{
211 return -EOPNOTSUPP;
212}
213
Scott Feldman491d0f12015-05-10 09:47:52 -0700214static inline int switchdev_port_obj_add(struct net_device *dev,
Petr Machata69b73202018-12-12 17:02:52 +0000215 const struct switchdev_obj *obj,
216 struct netlink_ext_ack *extack)
Scott Feldman491d0f12015-05-10 09:47:52 -0700217{
218 return -EOPNOTSUPP;
219}
220
221static inline int switchdev_port_obj_del(struct net_device *dev,
Jiri Pirko648b4a92015-10-01 11:03:45 +0200222 const struct switchdev_obj *obj)
Scott Feldman491d0f12015-05-10 09:47:52 -0700223{
224 return -EOPNOTSUPP;
225}
226
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700227static inline int register_switchdev_notifier(struct notifier_block *nb)
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100228{
229 return 0;
230}
231
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700232static inline int unregister_switchdev_notifier(struct notifier_block *nb)
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100233{
234 return 0;
235}
236
Jiri Pirkoebb9a032015-05-10 09:47:46 -0700237static inline int call_switchdev_notifiers(unsigned long val,
238 struct net_device *dev,
Petr Machata66859872019-01-16 23:06:56 +0000239 struct switchdev_notifier_info *info,
240 struct netlink_ext_ack *extack)
Jiri Pirko03bf0c22015-01-15 23:49:36 +0100241{
242 return NOTIFY_DONE;
243}
244
Petr Machataa93e3b12018-11-22 23:28:25 +0000245static inline int
246register_switchdev_blocking_notifier(struct notifier_block *nb)
247{
248 return 0;
249}
250
251static inline int
252unregister_switchdev_blocking_notifier(struct notifier_block *nb)
253{
254 return 0;
255}
256
257static inline int
258call_switchdev_blocking_notifiers(unsigned long val,
259 struct net_device *dev,
Petr Machata479c86d2018-12-12 17:02:54 +0000260 struct switchdev_notifier_info *info,
261 struct netlink_ext_ack *extack)
Petr Machataa93e3b12018-11-22 23:28:25 +0000262{
263 return NOTIFY_DONE;
264}
265
Petr Machataf30f0602018-11-22 23:29:44 +0000266static inline int
267switchdev_handle_port_obj_add(struct net_device *dev,
268 struct switchdev_notifier_port_obj_info *port_obj_info,
269 bool (*check_cb)(const struct net_device *dev),
270 int (*add_cb)(struct net_device *dev,
271 const struct switchdev_obj *obj,
Petr Machata69213512018-12-12 17:02:56 +0000272 struct switchdev_trans *trans,
273 struct netlink_ext_ack *extack))
Petr Machataf30f0602018-11-22 23:29:44 +0000274{
275 return 0;
276}
277
278static inline int
279switchdev_handle_port_obj_del(struct net_device *dev,
280 struct switchdev_notifier_port_obj_info *port_obj_info,
281 bool (*check_cb)(const struct net_device *dev),
282 int (*del_cb)(struct net_device *dev,
283 const struct switchdev_obj *obj))
284{
285 return 0;
286}
287
Florian Fainelli1cb33af2019-02-27 11:44:25 -0800288static inline int
289switchdev_handle_port_attr_set(struct net_device *dev,
290 struct switchdev_notifier_port_attr_info *port_attr_info,
291 bool (*check_cb)(const struct net_device *dev),
292 int (*set_cb)(struct net_device *dev,
293 const struct switchdev_attr *attr,
294 struct switchdev_trans *trans))
295{
296 return 0;
297}
Jiri Pirko007f7902014-11-28 14:34:17 +0100298#endif
299
300#endif /* _LINUX_SWITCHDEV_H_ */