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