1 /* 2 * net/switchdev/switchdev.c - 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 12 #include <linux/kernel.h> 13 #include <linux/types.h> 14 #include <linux/init.h> 15 #include <linux/mutex.h> 16 #include <linux/notifier.h> 17 #include <linux/netdevice.h> 18 #include <net/ip_fib.h> 19 #include <net/switchdev.h> 20 21 /** 22 * netdev_switch_parent_id_get - Get ID of a switch 23 * @dev: port device 24 * @psid: switch ID 25 * 26 * Get ID of a switch this port is part of. 27 */ 28 int netdev_switch_parent_id_get(struct net_device *dev, 29 struct netdev_phys_item_id *psid) 30 { 31 const struct swdev_ops *ops = dev->swdev_ops; 32 33 if (!ops || !ops->swdev_parent_id_get) 34 return -EOPNOTSUPP; 35 return ops->swdev_parent_id_get(dev, psid); 36 } 37 EXPORT_SYMBOL_GPL(netdev_switch_parent_id_get); 38 39 /** 40 * netdev_switch_port_stp_update - Notify switch device port of STP 41 * state change 42 * @dev: port device 43 * @state: port STP state 44 * 45 * Notify switch device port of bridge port STP state change. 46 */ 47 int netdev_switch_port_stp_update(struct net_device *dev, u8 state) 48 { 49 const struct swdev_ops *ops = dev->swdev_ops; 50 struct net_device *lower_dev; 51 struct list_head *iter; 52 int err = -EOPNOTSUPP; 53 54 if (ops && ops->swdev_port_stp_update) 55 return ops->swdev_port_stp_update(dev, state); 56 57 netdev_for_each_lower_dev(dev, lower_dev, iter) { 58 err = netdev_switch_port_stp_update(lower_dev, state); 59 if (err && err != -EOPNOTSUPP) 60 return err; 61 } 62 63 return err; 64 } 65 EXPORT_SYMBOL_GPL(netdev_switch_port_stp_update); 66 67 static DEFINE_MUTEX(netdev_switch_mutex); 68 static RAW_NOTIFIER_HEAD(netdev_switch_notif_chain); 69 70 /** 71 * register_netdev_switch_notifier - Register notifier 72 * @nb: notifier_block 73 * 74 * Register switch device notifier. This should be used by code 75 * which needs to monitor events happening in particular device. 76 * Return values are same as for atomic_notifier_chain_register(). 77 */ 78 int register_netdev_switch_notifier(struct notifier_block *nb) 79 { 80 int err; 81 82 mutex_lock(&netdev_switch_mutex); 83 err = raw_notifier_chain_register(&netdev_switch_notif_chain, nb); 84 mutex_unlock(&netdev_switch_mutex); 85 return err; 86 } 87 EXPORT_SYMBOL_GPL(register_netdev_switch_notifier); 88 89 /** 90 * unregister_netdev_switch_notifier - Unregister notifier 91 * @nb: notifier_block 92 * 93 * Unregister switch device notifier. 94 * Return values are same as for atomic_notifier_chain_unregister(). 95 */ 96 int unregister_netdev_switch_notifier(struct notifier_block *nb) 97 { 98 int err; 99 100 mutex_lock(&netdev_switch_mutex); 101 err = raw_notifier_chain_unregister(&netdev_switch_notif_chain, nb); 102 mutex_unlock(&netdev_switch_mutex); 103 return err; 104 } 105 EXPORT_SYMBOL_GPL(unregister_netdev_switch_notifier); 106 107 /** 108 * call_netdev_switch_notifiers - Call notifiers 109 * @val: value passed unmodified to notifier function 110 * @dev: port device 111 * @info: notifier information data 112 * 113 * Call all network notifier blocks. This should be called by driver 114 * when it needs to propagate hardware event. 115 * Return values are same as for atomic_notifier_call_chain(). 116 */ 117 int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev, 118 struct netdev_switch_notifier_info *info) 119 { 120 int err; 121 122 info->dev = dev; 123 mutex_lock(&netdev_switch_mutex); 124 err = raw_notifier_call_chain(&netdev_switch_notif_chain, val, info); 125 mutex_unlock(&netdev_switch_mutex); 126 return err; 127 } 128 EXPORT_SYMBOL_GPL(call_netdev_switch_notifiers); 129 130 /** 131 * netdev_switch_port_bridge_setlink - Notify switch device port of bridge 132 * port attributes 133 * 134 * @dev: port device 135 * @nlh: netlink msg with bridge port attributes 136 * @flags: bridge setlink flags 137 * 138 * Notify switch device port of bridge port attributes 139 */ 140 int netdev_switch_port_bridge_setlink(struct net_device *dev, 141 struct nlmsghdr *nlh, u16 flags) 142 { 143 const struct net_device_ops *ops = dev->netdev_ops; 144 145 if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD)) 146 return 0; 147 148 if (!ops->ndo_bridge_setlink) 149 return -EOPNOTSUPP; 150 151 return ops->ndo_bridge_setlink(dev, nlh, flags); 152 } 153 EXPORT_SYMBOL_GPL(netdev_switch_port_bridge_setlink); 154 155 /** 156 * netdev_switch_port_bridge_dellink - Notify switch device port of bridge 157 * port attribute delete 158 * 159 * @dev: port device 160 * @nlh: netlink msg with bridge port attributes 161 * @flags: bridge setlink flags 162 * 163 * Notify switch device port of bridge port attribute delete 164 */ 165 int netdev_switch_port_bridge_dellink(struct net_device *dev, 166 struct nlmsghdr *nlh, u16 flags) 167 { 168 const struct net_device_ops *ops = dev->netdev_ops; 169 170 if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD)) 171 return 0; 172 173 if (!ops->ndo_bridge_dellink) 174 return -EOPNOTSUPP; 175 176 return ops->ndo_bridge_dellink(dev, nlh, flags); 177 } 178 EXPORT_SYMBOL_GPL(netdev_switch_port_bridge_dellink); 179 180 /** 181 * ndo_dflt_netdev_switch_port_bridge_setlink - default ndo bridge setlink 182 * op for master devices 183 * 184 * @dev: port device 185 * @nlh: netlink msg with bridge port attributes 186 * @flags: bridge setlink flags 187 * 188 * Notify master device slaves of bridge port attributes 189 */ 190 int ndo_dflt_netdev_switch_port_bridge_setlink(struct net_device *dev, 191 struct nlmsghdr *nlh, u16 flags) 192 { 193 struct net_device *lower_dev; 194 struct list_head *iter; 195 int ret = 0, err = 0; 196 197 if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD)) 198 return ret; 199 200 netdev_for_each_lower_dev(dev, lower_dev, iter) { 201 err = netdev_switch_port_bridge_setlink(lower_dev, nlh, flags); 202 if (err && err != -EOPNOTSUPP) 203 ret = err; 204 } 205 206 return ret; 207 } 208 EXPORT_SYMBOL_GPL(ndo_dflt_netdev_switch_port_bridge_setlink); 209 210 /** 211 * ndo_dflt_netdev_switch_port_bridge_dellink - default ndo bridge dellink 212 * op for master devices 213 * 214 * @dev: port device 215 * @nlh: netlink msg with bridge port attributes 216 * @flags: bridge dellink flags 217 * 218 * Notify master device slaves of bridge port attribute deletes 219 */ 220 int ndo_dflt_netdev_switch_port_bridge_dellink(struct net_device *dev, 221 struct nlmsghdr *nlh, u16 flags) 222 { 223 struct net_device *lower_dev; 224 struct list_head *iter; 225 int ret = 0, err = 0; 226 227 if (!(dev->features & NETIF_F_HW_SWITCH_OFFLOAD)) 228 return ret; 229 230 netdev_for_each_lower_dev(dev, lower_dev, iter) { 231 err = netdev_switch_port_bridge_dellink(lower_dev, nlh, flags); 232 if (err && err != -EOPNOTSUPP) 233 ret = err; 234 } 235 236 return ret; 237 } 238 EXPORT_SYMBOL_GPL(ndo_dflt_netdev_switch_port_bridge_dellink); 239 240 static struct net_device *netdev_switch_get_lowest_dev(struct net_device *dev) 241 { 242 const struct swdev_ops *ops = dev->swdev_ops; 243 struct net_device *lower_dev; 244 struct net_device *port_dev; 245 struct list_head *iter; 246 247 /* Recusively search down until we find a sw port dev. 248 * (A sw port dev supports swdev_parent_id_get). 249 */ 250 251 if (dev->features & NETIF_F_HW_SWITCH_OFFLOAD && 252 ops && ops->swdev_parent_id_get) 253 return dev; 254 255 netdev_for_each_lower_dev(dev, lower_dev, iter) { 256 port_dev = netdev_switch_get_lowest_dev(lower_dev); 257 if (port_dev) 258 return port_dev; 259 } 260 261 return NULL; 262 } 263 264 static struct net_device *netdev_switch_get_dev_by_nhs(struct fib_info *fi) 265 { 266 struct netdev_phys_item_id psid; 267 struct netdev_phys_item_id prev_psid; 268 struct net_device *dev = NULL; 269 int nhsel; 270 271 /* For this route, all nexthop devs must be on the same switch. */ 272 273 for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { 274 const struct fib_nh *nh = &fi->fib_nh[nhsel]; 275 276 if (!nh->nh_dev) 277 return NULL; 278 279 dev = netdev_switch_get_lowest_dev(nh->nh_dev); 280 if (!dev) 281 return NULL; 282 283 if (netdev_switch_parent_id_get(dev, &psid)) 284 return NULL; 285 286 if (nhsel > 0) { 287 if (prev_psid.id_len != psid.id_len) 288 return NULL; 289 if (memcmp(prev_psid.id, psid.id, psid.id_len)) 290 return NULL; 291 } 292 293 prev_psid = psid; 294 } 295 296 return dev; 297 } 298 299 /** 300 * netdev_switch_fib_ipv4_add - Add IPv4 route entry to switch 301 * 302 * @dst: route's IPv4 destination address 303 * @dst_len: destination address length (prefix length) 304 * @fi: route FIB info structure 305 * @tos: route TOS 306 * @type: route type 307 * @nlflags: netlink flags passed in (NLM_F_*) 308 * @tb_id: route table ID 309 * 310 * Add IPv4 route entry to switch device. 311 */ 312 int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi, 313 u8 tos, u8 type, u32 nlflags, u32 tb_id) 314 { 315 struct net_device *dev; 316 const struct swdev_ops *ops; 317 int err = 0; 318 319 /* Don't offload route if using custom ip rules or if 320 * IPv4 FIB offloading has been disabled completely. 321 */ 322 323 #ifdef CONFIG_IP_MULTIPLE_TABLES 324 if (fi->fib_net->ipv4.fib_has_custom_rules) 325 return 0; 326 #endif 327 328 if (fi->fib_net->ipv4.fib_offload_disabled) 329 return 0; 330 331 dev = netdev_switch_get_dev_by_nhs(fi); 332 if (!dev) 333 return 0; 334 ops = dev->swdev_ops; 335 336 if (ops->swdev_fib_ipv4_add) { 337 err = ops->swdev_fib_ipv4_add(dev, htonl(dst), dst_len, 338 fi, tos, type, nlflags, 339 tb_id); 340 if (!err) 341 fi->fib_flags |= RTNH_F_EXTERNAL; 342 } 343 344 return err; 345 } 346 EXPORT_SYMBOL_GPL(netdev_switch_fib_ipv4_add); 347 348 /** 349 * netdev_switch_fib_ipv4_del - Delete IPv4 route entry from switch 350 * 351 * @dst: route's IPv4 destination address 352 * @dst_len: destination address length (prefix length) 353 * @fi: route FIB info structure 354 * @tos: route TOS 355 * @type: route type 356 * @tb_id: route table ID 357 * 358 * Delete IPv4 route entry from switch device. 359 */ 360 int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi, 361 u8 tos, u8 type, u32 tb_id) 362 { 363 struct net_device *dev; 364 const struct swdev_ops *ops; 365 int err = 0; 366 367 if (!(fi->fib_flags & RTNH_F_EXTERNAL)) 368 return 0; 369 370 dev = netdev_switch_get_dev_by_nhs(fi); 371 if (!dev) 372 return 0; 373 ops = dev->swdev_ops; 374 375 if (ops->swdev_fib_ipv4_del) { 376 err = ops->swdev_fib_ipv4_del(dev, htonl(dst), dst_len, 377 fi, tos, type, tb_id); 378 if (!err) 379 fi->fib_flags &= ~RTNH_F_EXTERNAL; 380 } 381 382 return err; 383 } 384 EXPORT_SYMBOL_GPL(netdev_switch_fib_ipv4_del); 385 386 /** 387 * netdev_switch_fib_ipv4_abort - Abort an IPv4 FIB operation 388 * 389 * @fi: route FIB info structure 390 */ 391 void netdev_switch_fib_ipv4_abort(struct fib_info *fi) 392 { 393 /* There was a problem installing this route to the offload 394 * device. For now, until we come up with more refined 395 * policy handling, abruptly end IPv4 fib offloading for 396 * for entire net by flushing offload device(s) of all 397 * IPv4 routes, and mark IPv4 fib offloading broken from 398 * this point forward. 399 */ 400 401 fib_flush_external(fi->fib_net); 402 fi->fib_net->ipv4.fib_offload_disabled = true; 403 } 404 EXPORT_SYMBOL_GPL(netdev_switch_fib_ipv4_abort); 405