xref: /linux-6.15/include/net/switchdev.h (revision 1b69c6d0)
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_UNDEFINED,
43 	SWITCHDEV_ATTR_PORT_PARENT_ID,
44 	SWITCHDEV_ATTR_PORT_STP_STATE,
45 	SWITCHDEV_ATTR_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_UNDEFINED,
62 	SWITCHDEV_OBJ_PORT_VLAN,
63 	SWITCHDEV_OBJ_IPV4_FIB,
64 	SWITCHDEV_OBJ_PORT_FDB,
65 };
66 
67 struct switchdev_obj {
68 	enum switchdev_obj_id id;
69 	int (*cb)(struct net_device *dev, struct switchdev_obj *obj);
70 	union {
71 		struct switchdev_obj_vlan {		/* PORT_VLAN */
72 			u16 flags;
73 			u16 vid_begin;
74 			u16 vid_end;
75 		} vlan;
76 		struct switchdev_obj_ipv4_fib {		/* IPV4_FIB */
77 			u32 dst;
78 			int dst_len;
79 			struct fib_info *fi;
80 			u8 tos;
81 			u8 type;
82 			u32 nlflags;
83 			u32 tb_id;
84 		} ipv4_fib;
85 		struct switchdev_obj_fdb {		/* PORT_FDB */
86 			const unsigned char *addr;
87 			u16 vid;
88 			u16 ndm_state;
89 		} fdb;
90 	} u;
91 };
92 
93 void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
94 				  void *data, void (*destructor)(void const *),
95 				  struct switchdev_trans_item *tritem);
96 void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
97 
98 /**
99  * struct switchdev_ops - switchdev operations
100  *
101  * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
102  *
103  * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
104  *
105  * @switchdev_port_obj_add: Add an object to port (see switchdev_obj).
106  *
107  * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj).
108  *
109  * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj).
110  */
111 struct switchdev_ops {
112 	int	(*switchdev_port_attr_get)(struct net_device *dev,
113 					   struct switchdev_attr *attr);
114 	int	(*switchdev_port_attr_set)(struct net_device *dev,
115 					   struct switchdev_attr *attr,
116 					   struct switchdev_trans *trans);
117 	int	(*switchdev_port_obj_add)(struct net_device *dev,
118 					  struct switchdev_obj *obj,
119 					  struct switchdev_trans *trans);
120 	int	(*switchdev_port_obj_del)(struct net_device *dev,
121 					  struct switchdev_obj *obj);
122 	int	(*switchdev_port_obj_dump)(struct net_device *dev,
123 					  struct switchdev_obj *obj);
124 };
125 
126 enum switchdev_notifier_type {
127 	SWITCHDEV_FDB_ADD = 1,
128 	SWITCHDEV_FDB_DEL,
129 };
130 
131 struct switchdev_notifier_info {
132 	struct net_device *dev;
133 };
134 
135 struct switchdev_notifier_fdb_info {
136 	struct switchdev_notifier_info info; /* must be first */
137 	const unsigned char *addr;
138 	u16 vid;
139 };
140 
141 static inline struct net_device *
142 switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
143 {
144 	return info->dev;
145 }
146 
147 #ifdef CONFIG_NET_SWITCHDEV
148 
149 int switchdev_port_attr_get(struct net_device *dev,
150 			    struct switchdev_attr *attr);
151 int switchdev_port_attr_set(struct net_device *dev,
152 			    struct switchdev_attr *attr);
153 int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj);
154 int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj);
155 int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj);
156 int register_switchdev_notifier(struct notifier_block *nb);
157 int unregister_switchdev_notifier(struct notifier_block *nb);
158 int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
159 			     struct switchdev_notifier_info *info);
160 int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
161 				  struct net_device *dev, u32 filter_mask,
162 				  int nlflags);
163 int switchdev_port_bridge_setlink(struct net_device *dev,
164 				  struct nlmsghdr *nlh, u16 flags);
165 int switchdev_port_bridge_dellink(struct net_device *dev,
166 				  struct nlmsghdr *nlh, u16 flags);
167 int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
168 			   u8 tos, u8 type, u32 nlflags, u32 tb_id);
169 int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
170 			   u8 tos, u8 type, u32 tb_id);
171 void switchdev_fib_ipv4_abort(struct fib_info *fi);
172 int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
173 			   struct net_device *dev, const unsigned char *addr,
174 			   u16 vid, u16 nlm_flags);
175 int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
176 			   struct net_device *dev, const unsigned char *addr,
177 			   u16 vid);
178 int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
179 			    struct net_device *dev,
180 			    struct net_device *filter_dev, int idx);
181 void switchdev_port_fwd_mark_set(struct net_device *dev,
182 				 struct net_device *group_dev,
183 				 bool joining);
184 
185 #else
186 
187 static inline int switchdev_port_attr_get(struct net_device *dev,
188 					  struct switchdev_attr *attr)
189 {
190 	return -EOPNOTSUPP;
191 }
192 
193 static inline int switchdev_port_attr_set(struct net_device *dev,
194 					  struct switchdev_attr *attr)
195 {
196 	return -EOPNOTSUPP;
197 }
198 
199 static inline int switchdev_port_obj_add(struct net_device *dev,
200 					 struct switchdev_obj *obj)
201 {
202 	return -EOPNOTSUPP;
203 }
204 
205 static inline int switchdev_port_obj_del(struct net_device *dev,
206 					 struct switchdev_obj *obj)
207 {
208 	return -EOPNOTSUPP;
209 }
210 
211 static inline int switchdev_port_obj_dump(struct net_device *dev,
212 					  struct switchdev_obj *obj)
213 {
214 	return -EOPNOTSUPP;
215 }
216 
217 static inline int register_switchdev_notifier(struct notifier_block *nb)
218 {
219 	return 0;
220 }
221 
222 static inline int unregister_switchdev_notifier(struct notifier_block *nb)
223 {
224 	return 0;
225 }
226 
227 static inline int call_switchdev_notifiers(unsigned long val,
228 					   struct net_device *dev,
229 					   struct switchdev_notifier_info *info)
230 {
231 	return NOTIFY_DONE;
232 }
233 
234 static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid,
235 					    u32 seq, struct net_device *dev,
236 					    u32 filter_mask, int nlflags)
237 {
238 	return -EOPNOTSUPP;
239 }
240 
241 static inline int switchdev_port_bridge_setlink(struct net_device *dev,
242 						struct nlmsghdr *nlh,
243 						u16 flags)
244 {
245 	return -EOPNOTSUPP;
246 }
247 
248 static inline int switchdev_port_bridge_dellink(struct net_device *dev,
249 						struct nlmsghdr *nlh,
250 						u16 flags)
251 {
252 	return -EOPNOTSUPP;
253 }
254 
255 static inline int switchdev_fib_ipv4_add(u32 dst, int dst_len,
256 					 struct fib_info *fi,
257 					 u8 tos, u8 type,
258 					 u32 nlflags, u32 tb_id)
259 {
260 	return 0;
261 }
262 
263 static inline int switchdev_fib_ipv4_del(u32 dst, int dst_len,
264 					 struct fib_info *fi,
265 					 u8 tos, u8 type, u32 tb_id)
266 {
267 	return 0;
268 }
269 
270 static inline void switchdev_fib_ipv4_abort(struct fib_info *fi)
271 {
272 }
273 
274 static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
275 					 struct net_device *dev,
276 					 const unsigned char *addr,
277 					 u16 vid, u16 nlm_flags)
278 {
279 	return -EOPNOTSUPP;
280 }
281 
282 static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
283 					 struct net_device *dev,
284 					 const unsigned char *addr, u16 vid)
285 {
286 	return -EOPNOTSUPP;
287 }
288 
289 static inline int switchdev_port_fdb_dump(struct sk_buff *skb,
290 					  struct netlink_callback *cb,
291 					  struct net_device *dev,
292 					  struct net_device *filter_dev,
293 					  int idx)
294 {
295 	return -EOPNOTSUPP;
296 }
297 
298 static inline void switchdev_port_fwd_mark_set(struct net_device *dev,
299 					       struct net_device *group_dev,
300 					       bool joining)
301 {
302 }
303 
304 #endif
305 
306 #endif /* _LINUX_SWITCHDEV_H_ */
307