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