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