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 #include <net/ip_fib.h> 18 19 #define SWITCHDEV_F_NO_RECURSE BIT(0) 20 #define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1) 21 #define SWITCHDEV_F_DEFER BIT(2) 22 23 struct switchdev_trans_item { 24 struct list_head list; 25 void *data; 26 void (*destructor)(const void *data); 27 }; 28 29 struct switchdev_trans { 30 struct list_head item_list; 31 bool ph_prepare; 32 }; 33 34 static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans) 35 { 36 return trans && trans->ph_prepare; 37 } 38 39 static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans) 40 { 41 return trans && !trans->ph_prepare; 42 } 43 44 enum switchdev_attr_id { 45 SWITCHDEV_ATTR_ID_UNDEFINED, 46 SWITCHDEV_ATTR_ID_PORT_PARENT_ID, 47 SWITCHDEV_ATTR_ID_PORT_STP_STATE, 48 SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, 49 SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME, 50 SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING, 51 }; 52 53 struct switchdev_attr { 54 struct net_device *orig_dev; 55 enum switchdev_attr_id id; 56 u32 flags; 57 void *complete_priv; 58 void (*complete)(struct net_device *dev, int err, void *priv); 59 union { 60 struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ 61 u8 stp_state; /* PORT_STP_STATE */ 62 unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */ 63 clock_t ageing_time; /* BRIDGE_AGEING_TIME */ 64 bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */ 65 } u; 66 }; 67 68 enum switchdev_obj_id { 69 SWITCHDEV_OBJ_ID_UNDEFINED, 70 SWITCHDEV_OBJ_ID_PORT_VLAN, 71 SWITCHDEV_OBJ_ID_IPV4_FIB, 72 SWITCHDEV_OBJ_ID_PORT_FDB, 73 SWITCHDEV_OBJ_ID_PORT_MDB, 74 }; 75 76 struct switchdev_obj { 77 struct net_device *orig_dev; 78 enum switchdev_obj_id id; 79 u32 flags; 80 void *complete_priv; 81 void (*complete)(struct net_device *dev, int err, void *priv); 82 }; 83 84 /* SWITCHDEV_OBJ_ID_PORT_VLAN */ 85 struct switchdev_obj_port_vlan { 86 struct switchdev_obj obj; 87 u16 flags; 88 u16 vid_begin; 89 u16 vid_end; 90 }; 91 92 #define SWITCHDEV_OBJ_PORT_VLAN(obj) \ 93 container_of(obj, struct switchdev_obj_port_vlan, obj) 94 95 /* SWITCHDEV_OBJ_ID_IPV4_FIB */ 96 struct switchdev_obj_ipv4_fib { 97 struct switchdev_obj obj; 98 u32 dst; 99 int dst_len; 100 struct fib_info *fi; 101 u8 tos; 102 u8 type; 103 u32 nlflags; 104 u32 tb_id; 105 }; 106 107 #define SWITCHDEV_OBJ_IPV4_FIB(obj) \ 108 container_of(obj, struct switchdev_obj_ipv4_fib, obj) 109 110 /* SWITCHDEV_OBJ_ID_PORT_FDB */ 111 struct switchdev_obj_port_fdb { 112 struct switchdev_obj obj; 113 unsigned char addr[ETH_ALEN]; 114 u16 vid; 115 u16 ndm_state; 116 }; 117 118 #define SWITCHDEV_OBJ_PORT_FDB(obj) \ 119 container_of(obj, struct switchdev_obj_port_fdb, obj) 120 121 /* SWITCHDEV_OBJ_ID_PORT_MDB */ 122 struct switchdev_obj_port_mdb { 123 struct switchdev_obj obj; 124 unsigned char addr[ETH_ALEN]; 125 u16 vid; 126 }; 127 128 #define SWITCHDEV_OBJ_PORT_MDB(obj) \ 129 container_of(obj, struct switchdev_obj_port_mdb, obj) 130 131 void switchdev_trans_item_enqueue(struct switchdev_trans *trans, 132 void *data, void (*destructor)(void const *), 133 struct switchdev_trans_item *tritem); 134 void *switchdev_trans_item_dequeue(struct switchdev_trans *trans); 135 136 typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj); 137 138 /** 139 * struct switchdev_ops - switchdev operations 140 * 141 * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr). 142 * 143 * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr). 144 * 145 * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*). 146 * 147 * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*). 148 * 149 * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*). 150 */ 151 struct switchdev_ops { 152 int (*switchdev_port_attr_get)(struct net_device *dev, 153 struct switchdev_attr *attr); 154 int (*switchdev_port_attr_set)(struct net_device *dev, 155 const struct switchdev_attr *attr, 156 struct switchdev_trans *trans); 157 int (*switchdev_port_obj_add)(struct net_device *dev, 158 const struct switchdev_obj *obj, 159 struct switchdev_trans *trans); 160 int (*switchdev_port_obj_del)(struct net_device *dev, 161 const struct switchdev_obj *obj); 162 int (*switchdev_port_obj_dump)(struct net_device *dev, 163 struct switchdev_obj *obj, 164 switchdev_obj_dump_cb_t *cb); 165 }; 166 167 enum switchdev_notifier_type { 168 SWITCHDEV_FDB_ADD = 1, 169 SWITCHDEV_FDB_DEL, 170 }; 171 172 struct switchdev_notifier_info { 173 struct net_device *dev; 174 }; 175 176 struct switchdev_notifier_fdb_info { 177 struct switchdev_notifier_info info; /* must be first */ 178 const unsigned char *addr; 179 u16 vid; 180 }; 181 182 static inline struct net_device * 183 switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info) 184 { 185 return info->dev; 186 } 187 188 #ifdef CONFIG_NET_SWITCHDEV 189 190 void switchdev_deferred_process(void); 191 int switchdev_port_attr_get(struct net_device *dev, 192 struct switchdev_attr *attr); 193 int switchdev_port_attr_set(struct net_device *dev, 194 const struct switchdev_attr *attr); 195 int switchdev_port_obj_add(struct net_device *dev, 196 const struct switchdev_obj *obj); 197 int switchdev_port_obj_del(struct net_device *dev, 198 const struct switchdev_obj *obj); 199 int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, 200 switchdev_obj_dump_cb_t *cb); 201 int register_switchdev_notifier(struct notifier_block *nb); 202 int unregister_switchdev_notifier(struct notifier_block *nb); 203 int call_switchdev_notifiers(unsigned long val, struct net_device *dev, 204 struct switchdev_notifier_info *info); 205 int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, 206 struct net_device *dev, u32 filter_mask, 207 int nlflags); 208 int switchdev_port_bridge_setlink(struct net_device *dev, 209 struct nlmsghdr *nlh, u16 flags); 210 int switchdev_port_bridge_dellink(struct net_device *dev, 211 struct nlmsghdr *nlh, u16 flags); 212 int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, 213 u8 tos, u8 type, u32 nlflags, u32 tb_id); 214 int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, 215 u8 tos, u8 type, u32 tb_id); 216 void switchdev_fib_ipv4_abort(struct fib_info *fi); 217 int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 218 struct net_device *dev, const unsigned char *addr, 219 u16 vid, u16 nlm_flags); 220 int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], 221 struct net_device *dev, const unsigned char *addr, 222 u16 vid); 223 int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, 224 struct net_device *dev, 225 struct net_device *filter_dev, int idx); 226 void switchdev_port_fwd_mark_set(struct net_device *dev, 227 struct net_device *group_dev, 228 bool joining); 229 230 bool switchdev_port_same_parent_id(struct net_device *a, 231 struct net_device *b); 232 #else 233 234 static inline void switchdev_deferred_process(void) 235 { 236 } 237 238 static inline int switchdev_port_attr_get(struct net_device *dev, 239 struct switchdev_attr *attr) 240 { 241 return -EOPNOTSUPP; 242 } 243 244 static inline int switchdev_port_attr_set(struct net_device *dev, 245 const struct switchdev_attr *attr) 246 { 247 return -EOPNOTSUPP; 248 } 249 250 static inline int switchdev_port_obj_add(struct net_device *dev, 251 const struct switchdev_obj *obj) 252 { 253 return -EOPNOTSUPP; 254 } 255 256 static inline int switchdev_port_obj_del(struct net_device *dev, 257 const struct switchdev_obj *obj) 258 { 259 return -EOPNOTSUPP; 260 } 261 262 static inline int switchdev_port_obj_dump(struct net_device *dev, 263 const struct switchdev_obj *obj, 264 switchdev_obj_dump_cb_t *cb) 265 { 266 return -EOPNOTSUPP; 267 } 268 269 static inline int register_switchdev_notifier(struct notifier_block *nb) 270 { 271 return 0; 272 } 273 274 static inline int unregister_switchdev_notifier(struct notifier_block *nb) 275 { 276 return 0; 277 } 278 279 static inline int call_switchdev_notifiers(unsigned long val, 280 struct net_device *dev, 281 struct switchdev_notifier_info *info) 282 { 283 return NOTIFY_DONE; 284 } 285 286 static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, 287 u32 seq, struct net_device *dev, 288 u32 filter_mask, int nlflags) 289 { 290 return -EOPNOTSUPP; 291 } 292 293 static inline int switchdev_port_bridge_setlink(struct net_device *dev, 294 struct nlmsghdr *nlh, 295 u16 flags) 296 { 297 return -EOPNOTSUPP; 298 } 299 300 static inline int switchdev_port_bridge_dellink(struct net_device *dev, 301 struct nlmsghdr *nlh, 302 u16 flags) 303 { 304 return -EOPNOTSUPP; 305 } 306 307 static inline int switchdev_fib_ipv4_add(u32 dst, int dst_len, 308 struct fib_info *fi, 309 u8 tos, u8 type, 310 u32 nlflags, u32 tb_id) 311 { 312 return 0; 313 } 314 315 static inline int switchdev_fib_ipv4_del(u32 dst, int dst_len, 316 struct fib_info *fi, 317 u8 tos, u8 type, u32 tb_id) 318 { 319 return 0; 320 } 321 322 static inline void switchdev_fib_ipv4_abort(struct fib_info *fi) 323 { 324 } 325 326 static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 327 struct net_device *dev, 328 const unsigned char *addr, 329 u16 vid, u16 nlm_flags) 330 { 331 return -EOPNOTSUPP; 332 } 333 334 static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], 335 struct net_device *dev, 336 const unsigned char *addr, u16 vid) 337 { 338 return -EOPNOTSUPP; 339 } 340 341 static inline int switchdev_port_fdb_dump(struct sk_buff *skb, 342 struct netlink_callback *cb, 343 struct net_device *dev, 344 struct net_device *filter_dev, 345 int idx) 346 { 347 return idx; 348 } 349 350 static inline void switchdev_port_fwd_mark_set(struct net_device *dev, 351 struct net_device *group_dev, 352 bool joining) 353 { 354 } 355 356 static inline bool switchdev_port_same_parent_id(struct net_device *a, 357 struct net_device *b) 358 { 359 return false; 360 } 361 362 #endif 363 364 #endif /* _LINUX_SWITCHDEV_H_ */ 365