Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-dsa-Setup-dsa_netdev_ops'

Florian Fainelli says:

====================
net: dsa: Setup dsa_netdev_ops

This patch series addresses the overloading of a DSA CPU/management
interface's netdev_ops for the purpose of providing useful information
from the switch side.

Up until now we had duplicated the existing netdev_ops structure and
added specific function pointers to return information of interest. Here
we have a more controlled way of doing this by involving the specific
netdev_ops function pointers that we want to be patched, which is easier
for auditing code in the future. As a byproduct we can now maintain
netdev_ops pointer comparisons which would be failing before (no known
in tree problems because of that though).

Let me know if this approach looks reasonable to you and we might do the
same with our ethtool_ops overloading as well.

Changes in v2:

- use static inline int vs. static int inline (Kbuild robot)
- fixed typos in patch 4 (Andrew)
- avoid using macros (Andrew)
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+110 -47
+70 -1
include/net/dsa.h
··· 86 86 enum dsa_tag_protocol proto; 87 87 }; 88 88 89 + /* This structure defines the control interfaces that are overlayed by the 90 + * DSA layer on top of the DSA CPU/management net_device instance. This is 91 + * used by the core net_device layer while calling various net_device_ops 92 + * function pointers. 93 + */ 94 + struct dsa_netdevice_ops { 95 + int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, 96 + int cmd); 97 + int (*ndo_get_phys_port_name)(struct net_device *dev, char *name, 98 + size_t len); 99 + }; 100 + 89 101 #define DSA_TAG_DRIVER_ALIAS "dsa_tag-" 90 102 #define MODULE_ALIAS_DSA_TAG_DRIVER(__proto) \ 91 103 MODULE_ALIAS(DSA_TAG_DRIVER_ALIAS __stringify(__proto##_VALUE)) ··· 229 217 /* 230 218 * Original copy of the master netdev net_device_ops 231 219 */ 232 - const struct net_device_ops *orig_ndo_ops; 220 + const struct dsa_netdevice_ops *netdev_ops; 233 221 234 222 bool setup; 235 223 }; ··· 690 678 #endif 691 679 return false; 692 680 } 681 + 682 + #if IS_ENABLED(CONFIG_NET_DSA) 683 + static inline int __dsa_netdevice_ops_check(struct net_device *dev) 684 + { 685 + int err = -EOPNOTSUPP; 686 + 687 + if (!dev->dsa_ptr) 688 + return err; 689 + 690 + if (!dev->dsa_ptr->netdev_ops) 691 + return err; 692 + 693 + return 0; 694 + } 695 + 696 + static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, 697 + int cmd) 698 + { 699 + const struct dsa_netdevice_ops *ops; 700 + int err; 701 + 702 + err = __dsa_netdevice_ops_check(dev); 703 + if (err) 704 + return err; 705 + 706 + ops = dev->dsa_ptr->netdev_ops; 707 + 708 + return ops->ndo_do_ioctl(dev, ifr, cmd); 709 + } 710 + 711 + static inline int dsa_ndo_get_phys_port_name(struct net_device *dev, 712 + char *name, size_t len) 713 + { 714 + const struct dsa_netdevice_ops *ops; 715 + int err; 716 + 717 + err = __dsa_netdevice_ops_check(dev); 718 + if (err) 719 + return err; 720 + 721 + ops = dev->dsa_ptr->netdev_ops; 722 + 723 + return ops->ndo_get_phys_port_name(dev, name, len); 724 + } 725 + #else 726 + static inline int dsa_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, 727 + int cmd) 728 + { 729 + return -EOPNOTSUPP; 730 + } 731 + 732 + static inline int dsa_ndo_get_phys_port_name(struct net_device *dev, 733 + char *name, size_t len) 734 + { 735 + return -EOPNOTSUPP; 736 + } 737 + #endif 693 738 694 739 void dsa_unregister_switch(struct dsa_switch *ds); 695 740 int dsa_register_switch(struct dsa_switch *ds);
+5
net/core/dev.c
··· 98 98 #include <net/busy_poll.h> 99 99 #include <linux/rtnetlink.h> 100 100 #include <linux/stat.h> 101 + #include <net/dsa.h> 101 102 #include <net/dst.h> 102 103 #include <net/dst_metadata.h> 103 104 #include <net/pkt_sched.h> ··· 8602 8601 { 8603 8602 const struct net_device_ops *ops = dev->netdev_ops; 8604 8603 int err; 8604 + 8605 + err = dsa_ndo_get_phys_port_name(dev, name, len); 8606 + if (err == 0 || err != -EOPNOTSUPP) 8607 + return err; 8605 8608 8606 8609 if (ops->ndo_get_phys_port_name) { 8607 8610 err = ops->ndo_get_phys_port_name(dev, name, len);
+22 -7
net/core/dev_ioctl.c
··· 5 5 #include <linux/rtnetlink.h> 6 6 #include <linux/net_tstamp.h> 7 7 #include <linux/wireless.h> 8 + #include <net/dsa.h> 8 9 #include <net/wext.h> 9 10 10 11 /* ··· 226 225 return 0; 227 226 } 228 227 228 + static int dev_do_ioctl(struct net_device *dev, 229 + struct ifreq *ifr, unsigned int cmd) 230 + { 231 + const struct net_device_ops *ops = dev->netdev_ops; 232 + int err = -EOPNOTSUPP; 233 + 234 + err = dsa_ndo_do_ioctl(dev, ifr, cmd); 235 + if (err == 0 || err != -EOPNOTSUPP) 236 + return err; 237 + 238 + if (ops->ndo_do_ioctl) { 239 + if (netif_device_present(dev)) 240 + err = ops->ndo_do_ioctl(dev, ifr, cmd); 241 + else 242 + err = -ENODEV; 243 + } 244 + 245 + return err; 246 + } 247 + 229 248 /* 230 249 * Perform the SIOCxIFxxx calls, inside rtnl_lock() 231 250 */ ··· 344 323 cmd == SIOCSHWTSTAMP || 345 324 cmd == SIOCGHWTSTAMP || 346 325 cmd == SIOCWANDEV) { 347 - err = -EOPNOTSUPP; 348 - if (ops->ndo_do_ioctl) { 349 - if (netif_device_present(dev)) 350 - err = ops->ndo_do_ioctl(dev, ifr, cmd); 351 - else 352 - err = -ENODEV; 353 - } 326 + err = dev_do_ioctl(dev, ifr, cmd); 354 327 } else 355 328 err = -EINVAL; 356 329
+13 -39
net/dsa/master.c
··· 220 220 break; 221 221 } 222 222 223 - if (cpu_dp->orig_ndo_ops && cpu_dp->orig_ndo_ops->ndo_do_ioctl) 224 - err = cpu_dp->orig_ndo_ops->ndo_do_ioctl(dev, ifr, cmd); 223 + if (dev->netdev_ops->ndo_do_ioctl) 224 + err = dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); 225 225 226 226 return err; 227 227 } 228 + 229 + static const struct dsa_netdevice_ops dsa_netdev_ops = { 230 + .ndo_do_ioctl = dsa_master_ioctl, 231 + .ndo_get_phys_port_name = dsa_master_get_phys_port_name, 232 + }; 228 233 229 234 static int dsa_master_ethtool_setup(struct net_device *dev) 230 235 { ··· 265 260 cpu_dp->orig_ethtool_ops = NULL; 266 261 } 267 262 268 - static int dsa_master_ndo_setup(struct net_device *dev) 263 + static void dsa_netdev_ops_set(struct net_device *dev, 264 + const struct dsa_netdevice_ops *ops) 269 265 { 270 - struct dsa_port *cpu_dp = dev->dsa_ptr; 271 - struct dsa_switch *ds = cpu_dp->ds; 272 - struct net_device_ops *ops; 273 - 274 - if (dev->netdev_ops->ndo_get_phys_port_name) 275 - return 0; 276 - 277 - ops = devm_kzalloc(ds->dev, sizeof(*ops), GFP_KERNEL); 278 - if (!ops) 279 - return -ENOMEM; 280 - 281 - cpu_dp->orig_ndo_ops = dev->netdev_ops; 282 - if (cpu_dp->orig_ndo_ops) 283 - memcpy(ops, cpu_dp->orig_ndo_ops, sizeof(*ops)); 284 - 285 - ops->ndo_get_phys_port_name = dsa_master_get_phys_port_name; 286 - ops->ndo_do_ioctl = dsa_master_ioctl; 287 - 288 - dev->netdev_ops = ops; 289 - 290 - return 0; 291 - } 292 - 293 - static void dsa_master_ndo_teardown(struct net_device *dev) 294 - { 295 - struct dsa_port *cpu_dp = dev->dsa_ptr; 296 - 297 - if (cpu_dp->orig_ndo_ops) 298 - dev->netdev_ops = cpu_dp->orig_ndo_ops; 299 - cpu_dp->orig_ndo_ops = NULL; 266 + dev->dsa_ptr->netdev_ops = ops; 300 267 } 301 268 302 269 static ssize_t tagging_show(struct device *d, struct device_attribute *attr, ··· 330 353 if (ret) 331 354 return ret; 332 355 333 - ret = dsa_master_ndo_setup(dev); 334 - if (ret) 335 - goto out_err_ethtool_teardown; 356 + dsa_netdev_ops_set(dev, &dsa_netdev_ops); 336 357 337 358 ret = sysfs_create_group(&dev->dev.kobj, &dsa_group); 338 359 if (ret) ··· 339 364 return ret; 340 365 341 366 out_err_ndo_teardown: 342 - dsa_master_ndo_teardown(dev); 343 - out_err_ethtool_teardown: 367 + dsa_netdev_ops_set(dev, NULL); 344 368 dsa_master_ethtool_teardown(dev); 345 369 return ret; 346 370 } ··· 347 373 void dsa_master_teardown(struct net_device *dev) 348 374 { 349 375 sysfs_remove_group(&dev->dev.kobj, &dsa_group); 350 - dsa_master_ndo_teardown(dev); 376 + dsa_netdev_ops_set(dev, NULL); 351 377 dsa_master_ethtool_teardown(dev); 352 378 dsa_master_reset_mtu(dev); 353 379