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