Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next...
[cascardo/linux.git] / include / net / switchdev.h
1 /*
2  * include/net/switchdev.h - Switch device API
3  * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
4  * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
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_ */