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_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_ */ 329