1 /* 2 * include/net/switchdev.h - Switch device API 3 * Copyright (c) 2014 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 17 #define SWITCHDEV_F_NO_RECURSE BIT(0) 18 19 enum switchdev_trans { 20 SWITCHDEV_TRANS_NONE, 21 SWITCHDEV_TRANS_PREPARE, 22 SWITCHDEV_TRANS_ABORT, 23 SWITCHDEV_TRANS_COMMIT, 24 }; 25 26 enum switchdev_attr_id { 27 SWITCHDEV_ATTR_UNDEFINED, 28 SWITCHDEV_ATTR_PORT_PARENT_ID, 29 SWITCHDEV_ATTR_PORT_STP_STATE, 30 SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS, 31 }; 32 33 struct switchdev_attr { 34 enum switchdev_attr_id id; 35 enum switchdev_trans trans; 36 u32 flags; 37 union { 38 struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ 39 u8 stp_state; /* PORT_STP_STATE */ 40 unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */ 41 } u; 42 }; 43 44 struct fib_info; 45 46 enum switchdev_obj_id { 47 SWITCHDEV_OBJ_UNDEFINED, 48 SWITCHDEV_OBJ_PORT_VLAN, 49 SWITCHDEV_OBJ_IPV4_FIB, 50 SWITCHDEV_OBJ_PORT_FDB, 51 }; 52 53 struct switchdev_obj { 54 enum switchdev_obj_id id; 55 enum switchdev_trans trans; 56 int (*cb)(struct net_device *dev, struct switchdev_obj *obj); 57 union { 58 struct switchdev_obj_vlan { /* PORT_VLAN */ 59 u16 flags; 60 u16 vid_begin; 61 u16 vid_end; 62 } vlan; 63 struct switchdev_obj_ipv4_fib { /* IPV4_FIB */ 64 u32 dst; 65 int dst_len; 66 struct fib_info *fi; 67 u8 tos; 68 u8 type; 69 u32 nlflags; 70 u32 tb_id; 71 } ipv4_fib; 72 struct switchdev_obj_fdb { /* PORT_FDB */ 73 const unsigned char *addr; 74 u16 vid; 75 u16 ndm_state; 76 } fdb; 77 } u; 78 }; 79 80 /** 81 * struct switchdev_ops - switchdev operations 82 * 83 * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr). 84 * 85 * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr). 86 * 87 * @switchdev_port_obj_add: Add an object to port (see switchdev_obj). 88 * 89 * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj). 90 * 91 * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj). 92 */ 93 struct switchdev_ops { 94 int (*switchdev_port_attr_get)(struct net_device *dev, 95 struct switchdev_attr *attr); 96 int (*switchdev_port_attr_set)(struct net_device *dev, 97 struct switchdev_attr *attr); 98 int (*switchdev_port_obj_add)(struct net_device *dev, 99 struct switchdev_obj *obj); 100 int (*switchdev_port_obj_del)(struct net_device *dev, 101 struct switchdev_obj *obj); 102 int (*switchdev_port_obj_dump)(struct net_device *dev, 103 struct switchdev_obj *obj); 104 }; 105 106 enum switchdev_notifier_type { 107 SWITCHDEV_FDB_ADD = 1, 108 SWITCHDEV_FDB_DEL, 109 }; 110 111 struct switchdev_notifier_info { 112 struct net_device *dev; 113 }; 114 115 struct switchdev_notifier_fdb_info { 116 struct switchdev_notifier_info info; /* must be first */ 117 const unsigned char *addr; 118 u16 vid; 119 }; 120 121 static inline struct net_device * 122 switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info) 123 { 124 return info->dev; 125 } 126 127 #ifdef CONFIG_NET_SWITCHDEV 128 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 struct switchdev_attr *attr); 133 int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj); 134 int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj); 135 int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj); 136 int register_switchdev_notifier(struct notifier_block *nb); 137 int unregister_switchdev_notifier(struct notifier_block *nb); 138 int call_switchdev_notifiers(unsigned long val, struct net_device *dev, 139 struct switchdev_notifier_info *info); 140 int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, 141 struct net_device *dev, u32 filter_mask, 142 int nlflags); 143 int switchdev_port_bridge_setlink(struct net_device *dev, 144 struct nlmsghdr *nlh, u16 flags); 145 int switchdev_port_bridge_dellink(struct net_device *dev, 146 struct nlmsghdr *nlh, u16 flags); 147 int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, 148 u8 tos, u8 type, u32 nlflags, u32 tb_id); 149 int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, 150 u8 tos, u8 type, u32 tb_id); 151 void switchdev_fib_ipv4_abort(struct fib_info *fi); 152 int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 153 struct net_device *dev, const unsigned char *addr, 154 u16 vid, u16 nlm_flags); 155 int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], 156 struct net_device *dev, const unsigned char *addr, 157 u16 vid); 158 int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, 159 struct net_device *dev, 160 struct net_device *filter_dev, int idx); 161 void switchdev_port_fwd_mark_set(struct net_device *dev, 162 struct net_device *group_dev, 163 bool joining); 164 165 #else 166 167 static inline int switchdev_port_attr_get(struct net_device *dev, 168 struct switchdev_attr *attr) 169 { 170 return -EOPNOTSUPP; 171 } 172 173 static inline int switchdev_port_attr_set(struct net_device *dev, 174 struct switchdev_attr *attr) 175 { 176 return -EOPNOTSUPP; 177 } 178 179 static inline int switchdev_port_obj_add(struct net_device *dev, 180 struct switchdev_obj *obj) 181 { 182 return -EOPNOTSUPP; 183 } 184 185 static inline int switchdev_port_obj_del(struct net_device *dev, 186 struct switchdev_obj *obj) 187 { 188 return -EOPNOTSUPP; 189 } 190 191 static inline int switchdev_port_obj_dump(struct net_device *dev, 192 struct switchdev_obj *obj) 193 { 194 return -EOPNOTSUPP; 195 } 196 197 static inline int register_switchdev_notifier(struct notifier_block *nb) 198 { 199 return 0; 200 } 201 202 static inline int unregister_switchdev_notifier(struct notifier_block *nb) 203 { 204 return 0; 205 } 206 207 static inline int call_switchdev_notifiers(unsigned long val, 208 struct net_device *dev, 209 struct switchdev_notifier_info *info) 210 { 211 return NOTIFY_DONE; 212 } 213 214 static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, 215 u32 seq, struct net_device *dev, 216 u32 filter_mask, int nlflags) 217 { 218 return -EOPNOTSUPP; 219 } 220 221 static inline int switchdev_port_bridge_setlink(struct net_device *dev, 222 struct nlmsghdr *nlh, 223 u16 flags) 224 { 225 return -EOPNOTSUPP; 226 } 227 228 static inline int switchdev_port_bridge_dellink(struct net_device *dev, 229 struct nlmsghdr *nlh, 230 u16 flags) 231 { 232 return -EOPNOTSUPP; 233 } 234 235 static inline int switchdev_fib_ipv4_add(u32 dst, int dst_len, 236 struct fib_info *fi, 237 u8 tos, u8 type, 238 u32 nlflags, u32 tb_id) 239 { 240 return 0; 241 } 242 243 static inline int switchdev_fib_ipv4_del(u32 dst, int dst_len, 244 struct fib_info *fi, 245 u8 tos, u8 type, u32 tb_id) 246 { 247 return 0; 248 } 249 250 static inline void switchdev_fib_ipv4_abort(struct fib_info *fi) 251 { 252 } 253 254 static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], 255 struct net_device *dev, 256 const unsigned char *addr, 257 u16 vid, u16 nlm_flags) 258 { 259 return -EOPNOTSUPP; 260 } 261 262 static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], 263 struct net_device *dev, 264 const unsigned char *addr, u16 vid) 265 { 266 return -EOPNOTSUPP; 267 } 268 269 static inline int switchdev_port_fdb_dump(struct sk_buff *skb, 270 struct netlink_callback *cb, 271 struct net_device *dev, 272 struct net_device *filter_dev, 273 int idx) 274 { 275 return -EOPNOTSUPP; 276 } 277 278 static inline void switchdev_port_fwd_mark_set(struct net_device *dev, 279 struct net_device *group_dev, 280 bool joining) 281 { 282 } 283 284 #endif 285 286 #endif /* _LINUX_SWITCHDEV_H_ */ 287