summaryrefslogtreecommitdiff
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_alb.c2
-rw-r--r--drivers/net/bonding/bond_debugfs.c15
-rw-r--r--drivers/net/bonding/bond_main.c139
-rw-r--r--drivers/net/bonding/bond_sysfs.c4
4 files changed, 77 insertions, 83 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index fc5da5d7744d..dc2c7b979656 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -668,7 +668,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
dev = ip_dev_find(dev_net(bond->dev), arp->ip_src);
if (dev) {
- if (netif_is_bridge_master(dev)) {
+ if (netif_is_any_bridge_master(dev)) {
dev_put(dev);
return NULL;
}
diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c
index 594094526648..b19492a7f6ad 100644
--- a/drivers/net/bonding/bond_debugfs.c
+++ b/drivers/net/bonding/bond_debugfs.c
@@ -49,9 +49,6 @@ DEFINE_SHOW_ATTRIBUTE(bond_debug_rlb_hash);
void bond_debug_register(struct bonding *bond)
{
- if (!bonding_debug_root)
- return;
-
bond->debug_dir =
debugfs_create_dir(bond->dev->name, bonding_debug_root);
@@ -61,9 +58,6 @@ void bond_debug_register(struct bonding *bond)
void bond_debug_unregister(struct bonding *bond)
{
- if (!bonding_debug_root)
- return;
-
debugfs_remove_recursive(bond->debug_dir);
}
@@ -71,9 +65,6 @@ void bond_debug_reregister(struct bonding *bond)
{
struct dentry *d;
- if (!bonding_debug_root)
- return;
-
d = debugfs_rename(bonding_debug_root, bond->debug_dir,
bonding_debug_root, bond->dev->name);
if (!IS_ERR(d)) {
@@ -84,11 +75,11 @@ void bond_debug_reregister(struct bonding *bond)
}
}
-void bond_create_debugfs(void)
+void __init bond_create_debugfs(void)
{
bonding_debug_root = debugfs_create_dir("bonding", NULL);
- if (!bonding_debug_root)
+ if (IS_ERR(bonding_debug_root))
pr_warn("Warning: Cannot create bonding directory in debugfs\n");
}
@@ -113,7 +104,7 @@ void bond_debug_reregister(struct bonding *bond)
{
}
-void bond_create_debugfs(void)
+void __init bond_create_debugfs(void)
{
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 447b06ea4fc9..ed7212e61c54 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -90,6 +90,7 @@
#include <net/tls.h>
#endif
#include <net/ip6_route.h>
+#include <net/xdp.h>
#include "bonding_priv.h"
@@ -4446,11 +4447,6 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm
{
struct bonding *bond = netdev_priv(bond_dev);
struct mii_ioctl_data *mii = NULL;
- const struct net_device_ops *ops;
- struct net_device *real_dev;
- struct hwtstamp_config cfg;
- struct ifreq ifrr;
- int res = 0;
netdev_dbg(bond_dev, "bond_eth_ioctl: cmd=%d\n", cmd);
@@ -4477,44 +4473,11 @@ static int bond_eth_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cm
}
break;
- case SIOCSHWTSTAMP:
- if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
- return -EFAULT;
-
- if (!(cfg.flags & HWTSTAMP_FLAG_BONDED_PHC_INDEX))
- return -EOPNOTSUPP;
-
- fallthrough;
- case SIOCGHWTSTAMP:
- real_dev = bond_option_active_slave_get_rcu(bond);
- if (!real_dev)
- return -EOPNOTSUPP;
-
- strscpy_pad(ifrr.ifr_name, real_dev->name, IFNAMSIZ);
- ifrr.ifr_ifru = ifr->ifr_ifru;
-
- ops = real_dev->netdev_ops;
- if (netif_device_present(real_dev) && ops->ndo_eth_ioctl) {
- res = ops->ndo_eth_ioctl(real_dev, &ifrr, cmd);
- if (res)
- return res;
-
- ifr->ifr_ifru = ifrr.ifr_ifru;
- if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
- return -EFAULT;
-
- /* Set the BOND_PHC_INDEX flag to notify user space */
- cfg.flags |= HWTSTAMP_FLAG_BONDED_PHC_INDEX;
-
- return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ?
- -EFAULT : 0;
- }
- fallthrough;
default:
- res = -EOPNOTSUPP;
+ return -EOPNOTSUPP;
}
- return res;
+ return 0;
}
static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
@@ -5083,19 +5046,7 @@ static void bond_set_slave_arr(struct bonding *bond,
static void bond_reset_slave_arr(struct bonding *bond)
{
- struct bond_up_slave *usable, *all;
-
- usable = rtnl_dereference(bond->usable_slaves);
- if (usable) {
- RCU_INIT_POINTER(bond->usable_slaves, NULL);
- kfree_rcu(usable, rcu);
- }
-
- all = rtnl_dereference(bond->all_slaves);
- if (all) {
- RCU_INIT_POINTER(bond->all_slaves, NULL);
- kfree_rcu(all, rcu);
- }
+ bond_set_slave_arr(bond, NULL, NULL);
}
/* Build the usable slaves array in control path for modes that use xmit-hash
@@ -5688,6 +5639,67 @@ static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed)
return speed;
}
+/* Set the BOND_PHC_INDEX flag to notify user space */
+static int bond_set_phc_index_flag(struct kernel_hwtstamp_config *kernel_cfg)
+{
+ struct ifreq *ifr = kernel_cfg->ifr;
+ struct hwtstamp_config cfg;
+
+ if (kernel_cfg->copied_to_user) {
+ /* Lower device has a legacy implementation */
+ if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+ return -EFAULT;
+
+ cfg.flags |= HWTSTAMP_FLAG_BONDED_PHC_INDEX;
+ if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)))
+ return -EFAULT;
+ } else {
+ kernel_cfg->flags |= HWTSTAMP_FLAG_BONDED_PHC_INDEX;
+ }
+
+ return 0;
+}
+
+static int bond_hwtstamp_get(struct net_device *dev,
+ struct kernel_hwtstamp_config *cfg)
+{
+ struct bonding *bond = netdev_priv(dev);
+ struct net_device *real_dev;
+ int err;
+
+ real_dev = bond_option_active_slave_get_rcu(bond);
+ if (!real_dev)
+ return -EOPNOTSUPP;
+
+ err = generic_hwtstamp_get_lower(real_dev, cfg);
+ if (err)
+ return err;
+
+ return bond_set_phc_index_flag(cfg);
+}
+
+static int bond_hwtstamp_set(struct net_device *dev,
+ struct kernel_hwtstamp_config *cfg,
+ struct netlink_ext_ack *extack)
+{
+ struct bonding *bond = netdev_priv(dev);
+ struct net_device *real_dev;
+ int err;
+
+ if (!(cfg->flags & HWTSTAMP_FLAG_BONDED_PHC_INDEX))
+ return -EOPNOTSUPP;
+
+ real_dev = bond_option_active_slave_get_rcu(bond);
+ if (!real_dev)
+ return -EOPNOTSUPP;
+
+ err = generic_hwtstamp_set_lower(real_dev, cfg, extack);
+ if (err)
+ return err;
+
+ return bond_set_phc_index_flag(cfg);
+}
+
static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
struct ethtool_link_ksettings *cmd)
{
@@ -5706,6 +5718,7 @@ static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
*/
bond_for_each_slave(bond, slave, iter) {
if (bond_slave_can_tx(slave)) {
+ bond_update_speed_duplex(slave);
if (slave->speed != SPEED_UNKNOWN) {
if (BOND_MODE(bond) == BOND_MODE_BROADCAST)
speed = bond_mode_bcast_speed(slave,
@@ -5836,6 +5849,8 @@ static const struct net_device_ops bond_netdev_ops = {
.ndo_bpf = bond_xdp,
.ndo_xdp_xmit = bond_xdp_xmit,
.ndo_xdp_get_xmit_slave = bond_xdp_get_xmit_slave,
+ .ndo_hwtstamp_get = bond_hwtstamp_get,
+ .ndo_hwtstamp_set = bond_hwtstamp_set,
};
static const struct device_type bond_type = {
@@ -5849,8 +5864,7 @@ static void bond_destructor(struct net_device *bond_dev)
if (bond->wq)
destroy_workqueue(bond->wq);
- if (bond->rr_tx_counter)
- free_percpu(bond->rr_tx_counter);
+ free_percpu(bond->rr_tx_counter);
}
void bond_setup(struct net_device *bond_dev)
@@ -5925,7 +5939,6 @@ void bond_setup(struct net_device *bond_dev)
static void bond_uninit(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- struct bond_up_slave *usable, *all;
struct list_head *iter;
struct slave *slave;
@@ -5936,17 +5949,7 @@ static void bond_uninit(struct net_device *bond_dev)
__bond_release_one(bond_dev, slave->dev, true, true);
netdev_info(bond_dev, "Released all slaves\n");
- usable = rtnl_dereference(bond->usable_slaves);
- if (usable) {
- RCU_INIT_POINTER(bond->usable_slaves, NULL);
- kfree_rcu(usable, rcu);
- }
-
- all = rtnl_dereference(bond->all_slaves);
- if (all) {
- RCU_INIT_POINTER(bond->all_slaves, NULL);
- kfree_rcu(all, rcu);
- }
+ bond_set_slave_arr(bond, NULL, NULL);
list_del(&bond->bond_list);
@@ -5955,7 +5958,7 @@ static void bond_uninit(struct net_device *bond_dev)
/*------------------------- Module initialization ---------------------------*/
-static int bond_check_params(struct bond_params *params)
+static int __init bond_check_params(struct bond_params *params)
{
int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
struct bond_opt_value newval;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 0bb59da24922..2805135a7205 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -803,7 +803,7 @@ static const struct attribute_group bonding_group = {
/* Initialize sysfs. This sets up the bonding_masters file in
* /sys/class/net.
*/
-int bond_create_sysfs(struct bond_net *bn)
+int __net_init bond_create_sysfs(struct bond_net *bn)
{
int ret;
@@ -836,7 +836,7 @@ int bond_create_sysfs(struct bond_net *bn)
}
/* Remove /sys/class/net/bonding_masters. */
-void bond_destroy_sysfs(struct bond_net *bn)
+void __net_exit bond_destroy_sysfs(struct bond_net *bn)
{
netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
}