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