xref: /linux-6.15/include/net/switchdev.h (revision fee6d4c7)
1 /*
2  * include/net/switchdev.h - Switch device API
3  * Copyright (c) 2014-2015 Jiri Pirko <[email protected]>
4  * Copyright (c) 2014-2015 Scott Feldman <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11 #ifndef _LINUX_SWITCHDEV_H_
12 #define _LINUX_SWITCHDEV_H_
13 
14 #include <linux/netdevice.h>
15 #include <linux/notifier.h>
16 #include <linux/list.h>
17 
18 #define SWITCHDEV_F_NO_RECURSE		BIT(0)
19 
20 struct switchdev_trans_item {
21 	struct list_head list;
22 	void *data;
23 	void (*destructor)(const void *data);
24 };
25 
26 struct switchdev_trans {
27 	struct list_head item_list;
28 	bool ph_prepare;
29 };
30 
31 static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans)
32 {
33 	return trans && trans->ph_prepare;
34 }
35 
36 static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
37 {
38 	return trans && !trans->ph_prepare;
39 }
40 
41 enum switchdev_attr_id {
42 	SWITCHDEV_ATTR_ID_UNDEFINED,
43 	SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
44 	SWITCHDEV_ATTR_ID_PORT_STP_STATE,
45 	SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
46 };
47 
48 struct switchdev_attr {
49 	enum switchdev_attr_id id;
50 	u32 flags;
51 	union {
52 		struct netdev_phys_item_id ppid;	/* PORT_PARENT_ID */
53 		u8 stp_state;				/* PORT_STP_STATE */
54 		unsigned long brport_flags;		/* PORT_BRIDGE_FLAGS */
55 	} u;
56 };
57 
58 struct fib_info;
59 
60 enum switchdev_obj_id {
61 	SWITCHDEV_OBJ_ID_UNDEFINED,
62 	SWITCHDEV_OBJ_ID_PORT_VLAN,
63 	SWITCHDEV_OBJ_ID_IPV4_FIB,
64 	SWITCHDEV_OBJ_ID_PORT_FDB,
65 };
66 
67 struct switchdev_obj {
68 	enum switchdev_obj_id id;
69 };
70 
71 /* SWITCHDEV_OBJ_ID_PORT_VLAN */
72 struct switchdev_obj_port_vlan {
73 	struct switchdev_obj obj;
74 	u16 flags;
75 	u16 vid_begin;
76 	u16 vid_end;
77 };
78 
79 #define SWITCHDEV_OBJ_PORT_VLAN(obj) \
80 	container_of(obj, struct switchdev_obj_port_vlan, obj)
81 
82 /* SWITCHDEV_OBJ_ID_IPV4_FIB */
83 struct switchdev_obj_ipv4_fib {
84 	struct switchdev_obj obj;
85 	u32 dst;
86 	int dst_len;
87 	struct fib_info *fi;
88 	u8 tos;
89 	u8 type;
90 	u32 nlflags;
91 	u32 tb_id;
92 };
93 
94 #define SWITCHDEV_OBJ_IPV4_FIB(obj) \
95 	container_of(obj, struct switchdev_obj_ipv4_fib, obj)
96 
97 /* SWITCHDEV_OBJ_ID_PORT_FDB */
98 struct switchdev_obj_port_fdb {
99 	struct switchdev_obj obj;
100 	const unsigned char *addr;
101 	u16 vid;
102 	u16 ndm_state;
103 };
104 
105 #define SWITCHDEV_OBJ_PORT_FDB(obj) \
106 	container_of(obj, struct switchdev_obj_port_fdb, obj)
107 
108 void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
109 				  void *data, void (*destructor)(void const *),
110 				  struct switchdev_trans_item *tritem);
111 void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
112 
113 typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
114 
115 /**
116  * struct switchdev_ops - switchdev operations
117  *
118  * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
119  *
120  * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
121  *
122  * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
123  *
124  * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
125  *
126  * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*).
127  */
128 struct switchdev_ops {
129 	int	(*switchdev_port_attr_get)(struct net_device *dev,
130 					   struct switchdev_attr *attr);
131 	int	(*switchdev_port_attr_set)(struct net_device *dev,
132 					   struct switchdev_attr *attr,
133 					   struct switchdev_trans *trans);
134 	int	(*switchdev_port_obj_add)(struct net_device *dev,
135 					  const struct switchdev_obj *obj,
136 					  struct switchdev_trans *trans);
137 	int	(*switchdev_port_obj_del)(struct net_device *dev,
138 					  const struct switchdev_obj *obj);
139 	int	(*switchdev_port_obj_dump)(struct net_device *dev,
140 					   struct switchdev_obj *obj,
141 					   switchdev_obj_dump_cb_t *cb);
142 };
143 
144 enum switchdev_notifier_type {
145 	SWITCHDEV_FDB_ADD = 1,
146 	SWITCHDEV_FDB_DEL,
147 };
148 
149 struct switchdev_notifier_info {
150 	struct net_device *dev;
151 };
152 
153 struct switchdev_notifier_fdb_info {
154 	struct switchdev_notifier_info info; /* must be first */
155 	const unsigned char *addr;
156 	u16 vid;
157 };
158 
159 static inline struct net_device *
160 switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
161 {
162 	return info->dev;
163 }
164 
165 #ifdef CONFIG_NET_SWITCHDEV
166 
167 int switchdev_port_attr_get(struct net_device *dev,
168 			    struct switchdev_attr *attr);
169 int switchdev_port_attr_set(struct net_device *dev,
170 			    struct switchdev_attr *attr);
171 int switchdev_port_obj_add(struct net_device *dev,
172 			   const struct switchdev_obj *obj);
173 int switchdev_port_obj_del(struct net_device *dev,
174 			   const struct switchdev_obj *obj);
175 int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj,
176 			    switchdev_obj_dump_cb_t *cb);
177 int register_switchdev_notifier(struct notifier_block *nb);
178 int unregister_switchdev_notifier(struct notifier_block *nb);
179 int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
180 			     struct switchdev_notifier_info *info);
181 int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
182 				  struct net_device *dev, u32 filter_mask,
183 				  int nlflags);
184 int switchdev_port_bridge_setlink(struct net_device *dev,
185 				  struct nlmsghdr *nlh, u16 flags);
186 int switchdev_port_bridge_dellink(struct net_device *dev,
187 				  struct nlmsghdr *nlh, u16 flags);
188 int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
189 			   u8 tos, u8 type, u32 nlflags, u32 tb_id);
190 int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
191 			   u8 tos, u8 type, u32 tb_id);
192 void switchdev_fib_ipv4_abort(struct fib_info *fi);
193 int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
194 			   struct net_device *dev, const unsigned char *addr,
195 			   u16 vid, u16 nlm_flags);
196 int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
197 			   struct net_device *dev, const unsigned char *addr,
198 			   u16 vid);
199 int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
200 			    struct net_device *dev,
201 			    struct net_device *filter_dev, int idx);
202 void switchdev_port_fwd_mark_set(struct net_device *dev,
203 				 struct net_device *group_dev,
204 				 bool joining);
205 
206 #else
207 
208 static inline int switchdev_port_attr_get(struct net_device *dev,
209 					  struct switchdev_attr *attr)
210 {
211 	return -EOPNOTSUPP;
212 }
213 
214 static inline int switchdev_port_attr_set(struct net_device *dev,
215 					  struct switchdev_attr *attr)
216 {
217 	return -EOPNOTSUPP;
218 }
219 
220 static inline int switchdev_port_obj_add(struct net_device *dev,
221 					 const struct switchdev_obj *obj)
222 {
223 	return -EOPNOTSUPP;
224 }
225 
226 static inline int switchdev_port_obj_del(struct net_device *dev,
227 					 const struct switchdev_obj *obj)
228 {
229 	return -EOPNOTSUPP;
230 }
231 
232 static inline int switchdev_port_obj_dump(struct net_device *dev,
233 					  const struct switchdev_obj *obj,
234 					  switchdev_obj_dump_cb_t *cb)
235 {
236 	return -EOPNOTSUPP;
237 }
238 
239 static inline int register_switchdev_notifier(struct notifier_block *nb)
240 {
241 	return 0;
242 }
243 
244 static inline int unregister_switchdev_notifier(struct notifier_block *nb)
245 {
246 	return 0;
247 }
248 
249 static inline int call_switchdev_notifiers(unsigned long val,
250 					   struct net_device *dev,
251 					   struct switchdev_notifier_info *info)
252 {
253 	return NOTIFY_DONE;
254 }
255 
256 static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid,
257 					    u32 seq, struct net_device *dev,
258 					    u32 filter_mask, int nlflags)
259 {
260 	return -EOPNOTSUPP;
261 }
262 
263 static inline int switchdev_port_bridge_setlink(struct net_device *dev,
264 						struct nlmsghdr *nlh,
265 						u16 flags)
266 {
267 	return -EOPNOTSUPP;
268 }
269 
270 static inline int switchdev_port_bridge_dellink(struct net_device *dev,
271 						struct nlmsghdr *nlh,
272 						u16 flags)
273 {
274 	return -EOPNOTSUPP;
275 }
276 
277 static inline int switchdev_fib_ipv4_add(u32 dst, int dst_len,
278 					 struct fib_info *fi,
279 					 u8 tos, u8 type,
280 					 u32 nlflags, u32 tb_id)
281 {
282 	return 0;
283 }
284 
285 static inline int switchdev_fib_ipv4_del(u32 dst, int dst_len,
286 					 struct fib_info *fi,
287 					 u8 tos, u8 type, u32 tb_id)
288 {
289 	return 0;
290 }
291 
292 static inline void switchdev_fib_ipv4_abort(struct fib_info *fi)
293 {
294 }
295 
296 static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
297 					 struct net_device *dev,
298 					 const unsigned char *addr,
299 					 u16 vid, u16 nlm_flags)
300 {
301 	return -EOPNOTSUPP;
302 }
303 
304 static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
305 					 struct net_device *dev,
306 					 const unsigned char *addr, u16 vid)
307 {
308 	return -EOPNOTSUPP;
309 }
310 
311 static inline int switchdev_port_fdb_dump(struct sk_buff *skb,
312 					  struct netlink_callback *cb,
313 					  struct net_device *dev,
314 					  struct net_device *filter_dev,
315 					  int idx)
316 {
317 	return -EOPNOTSUPP;
318 }
319 
320 static inline void switchdev_port_fwd_mark_set(struct net_device *dev,
321 					       struct net_device *group_dev,
322 					       bool joining)
323 {
324 }
325 
326 #endif
327 
328 #endif /* _LINUX_SWITCHDEV_H_ */
329