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 }; 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_MDB */ 101 struct switchdev_obj_port_mdb { 102 struct switchdev_obj obj; 103 unsigned char addr[ETH_ALEN]; 104 u16 vid; 105 }; 106 107 #define SWITCHDEV_OBJ_PORT_MDB(obj) \ 108 container_of(obj, struct switchdev_obj_port_mdb, obj) 109 110 void switchdev_trans_item_enqueue(struct switchdev_trans *trans, 111 void *data, void (*destructor)(void const *), 112 struct switchdev_trans_item *tritem); 113 void *switchdev_trans_item_dequeue(struct switchdev_trans *trans); 114 115 typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj); 116 117 /** 118 * struct switchdev_ops - switchdev operations 119 * 120 * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr). 121 * 122 * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr). 123 * 124 * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*). 125 * 126 * @switchdev_port_obj_del: Delete an object from port (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 const 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 }; 140 141 enum switchdev_notifier_type { 142 SWITCHDEV_FDB_ADD_TO_BRIDGE = 1, 143 SWITCHDEV_FDB_DEL_TO_BRIDGE, 144 SWITCHDEV_FDB_ADD_TO_DEVICE, 145 SWITCHDEV_FDB_DEL_TO_DEVICE, 146 SWITCHDEV_FDB_OFFLOADED, 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 void switchdev_deferred_process(void); 168 int switchdev_port_attr_get(struct net_device *dev, 169 struct switchdev_attr *attr); 170 int switchdev_port_attr_set(struct net_device *dev, 171 const struct switchdev_attr *attr); 172 int switchdev_port_obj_add(struct net_device *dev, 173 const struct switchdev_obj *obj); 174 int switchdev_port_obj_del(struct net_device *dev, 175 const struct switchdev_obj *obj); 176 int register_switchdev_notifier(struct notifier_block *nb); 177 int unregister_switchdev_notifier(struct notifier_block *nb); 178 int call_switchdev_notifiers(unsigned long val, struct net_device *dev, 179 struct switchdev_notifier_info *info); 180 void switchdev_port_fwd_mark_set(struct net_device *dev, 181 struct net_device *group_dev, 182 bool joining); 183 184 bool switchdev_port_same_parent_id(struct net_device *a, 185 struct net_device *b); 186 187 #define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops)) 188 #else 189 190 static inline void switchdev_deferred_process(void) 191 { 192 } 193 194 static inline int switchdev_port_attr_get(struct net_device *dev, 195 struct switchdev_attr *attr) 196 { 197 return -EOPNOTSUPP; 198 } 199 200 static inline int switchdev_port_attr_set(struct net_device *dev, 201 const struct switchdev_attr *attr) 202 { 203 return -EOPNOTSUPP; 204 } 205 206 static inline int switchdev_port_obj_add(struct net_device *dev, 207 const struct switchdev_obj *obj) 208 { 209 return -EOPNOTSUPP; 210 } 211 212 static inline int switchdev_port_obj_del(struct net_device *dev, 213 const struct switchdev_obj *obj) 214 { 215 return -EOPNOTSUPP; 216 } 217 218 static inline int register_switchdev_notifier(struct notifier_block *nb) 219 { 220 return 0; 221 } 222 223 static inline int unregister_switchdev_notifier(struct notifier_block *nb) 224 { 225 return 0; 226 } 227 228 static inline int call_switchdev_notifiers(unsigned long val, 229 struct net_device *dev, 230 struct switchdev_notifier_info *info) 231 { 232 return NOTIFY_DONE; 233 } 234 235 static inline bool switchdev_port_same_parent_id(struct net_device *a, 236 struct net_device *b) 237 { 238 return false; 239 } 240 241 #define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0) 242 243 #endif 244 245 #endif /* _LINUX_SWITCHDEV_H_ */ 246