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