From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
kernel/drivers/net/team/team.c | 123 +++++++++++++++++++++++++++-------------
1 files changed, 82 insertions(+), 41 deletions(-)
diff --git a/kernel/drivers/net/team/team.c b/kernel/drivers/net/team/team.c
index 8a1e9db..7117d55 100644
--- a/kernel/drivers/net/team/team.c
+++ b/kernel/drivers/net/team/team.c
@@ -1,11 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* drivers/net/team/team.c - Network team device driver
* Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
#include <linux/kernel.h>
@@ -28,7 +24,6 @@
#include <net/genetlink.h>
#include <net/netlink.h>
#include <net/sch_generic.h>
-#include <net/switchdev.h>
#include <generated/utsrelease.h>
#include <linux/if_team.h>
@@ -39,13 +34,11 @@
* Helpers
**********/
-#define team_port_exists(dev) (dev->priv_flags & IFF_TEAM_PORT)
-
static struct team_port *team_port_get_rtnl(const struct net_device *dev)
{
struct team_port *port = rtnl_dereference(dev->rx_handler_data);
- return team_port_exists(dev) ? port : NULL;
+ return netif_is_team_port(dev) ? port : NULL;
}
/*
@@ -59,7 +52,7 @@
memcpy(addr.__data, dev_addr, port_dev->addr_len);
addr.ss_family = port_dev->type;
- return dev_set_mac_address(port_dev, (struct sockaddr *)&addr);
+ return dev_set_mac_address(port_dev, (struct sockaddr *)&addr, NULL);
}
static int team_port_set_orig_dev_addr(struct team_port *port)
@@ -1097,10 +1090,7 @@
return;
port->np = NULL;
- /* Wait for transmitting packets to finish before freeing. */
- synchronize_rcu_bh();
- __netpoll_cleanup(np);
- kfree(np);
+ __netpoll_free(np);
}
#else
static int team_port_enable_netpoll(struct team_port *port)
@@ -1153,7 +1143,7 @@
return -EINVAL;
}
- if (team_port_exists(port_dev)) {
+ if (netif_is_team_port(port_dev)) {
NL_SET_ERR_MSG(extack, "Device is already a port of a team device");
netdev_err(dev, "Device %s is already a port "
"of a team device\n", portname);
@@ -1217,7 +1207,7 @@
goto err_port_enter;
}
- err = dev_open(port_dev);
+ err = dev_open(port_dev, extack);
if (err) {
netdev_dbg(dev, "Device %s opening failed\n",
portname);
@@ -1280,10 +1270,12 @@
}
}
- netif_addr_lock_bh(dev);
- dev_uc_sync_multiple(port_dev, dev);
- dev_mc_sync_multiple(port_dev, dev);
- netif_addr_unlock_bh(dev);
+ if (dev->flags & IFF_UP) {
+ netif_addr_lock_bh(dev);
+ dev_uc_sync_multiple(port_dev, dev);
+ dev_mc_sync_multiple(port_dev, dev);
+ netif_addr_unlock_bh(dev);
+ }
port->index = -1;
list_add_tail_rcu(&port->list, &team->port_list);
@@ -1354,8 +1346,10 @@
netdev_rx_handler_unregister(port_dev);
team_port_disable_netpoll(port);
vlan_vids_del_by_dev(port_dev, dev);
- dev_uc_unsync(port_dev, dev);
- dev_mc_unsync(port_dev, dev);
+ if (dev->flags & IFF_UP) {
+ dev_uc_unsync(port_dev, dev);
+ dev_mc_unsync(port_dev, dev);
+ }
dev_close(port_dev);
team_port_leave(team, port);
@@ -1629,7 +1623,6 @@
int err;
team->dev = dev;
- mutex_init(&team->lock);
team_set_no_mode(team);
team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats);
@@ -1656,6 +1649,8 @@
goto err_options_register;
netif_carrier_off(dev);
+ lockdep_register_key(&team->team_lock_key);
+ __mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key);
netdev_lockdep_set_classes(dev);
return 0;
@@ -1687,6 +1682,7 @@
team_queue_override_fini(team);
mutex_unlock(&team->lock);
netdev_change_features(dev);
+ lockdep_unregister_key(&team->team_lock_key);
}
static void team_destructor(struct net_device *dev)
@@ -1703,6 +1699,14 @@
static int team_close(struct net_device *dev)
{
+ struct team *team = netdev_priv(dev);
+ struct team_port *port;
+
+ list_for_each_entry(port, &team->port_list, list) {
+ dev_uc_unsync(port->dev, dev);
+ dev_mc_unsync(port->dev, dev);
+ }
+
return 0;
}
@@ -1734,8 +1738,7 @@
}
static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb,
- struct net_device *sb_dev,
- select_queue_fallback_t fallback)
+ struct net_device *sb_dev)
{
/*
* This helper function exists to help dev_pick_tx get the correct
@@ -1991,8 +1994,15 @@
err = team_port_del(team, port_dev);
mutex_unlock(&team->lock);
- if (!err)
- netdev_change_features(dev);
+ if (err)
+ return err;
+
+ if (netif_is_team_master(port_dev)) {
+ lockdep_unregister_key(&team->team_lock_key);
+ lockdep_register_key(&team->team_lock_key);
+ lockdep_set_class(&team->lock, &team->team_lock_key);
+ }
+ netdev_change_features(dev);
return err;
}
@@ -2071,9 +2081,37 @@
strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
}
+static int team_ethtool_get_link_ksettings(struct net_device *dev,
+ struct ethtool_link_ksettings *cmd)
+{
+ struct team *team= netdev_priv(dev);
+ unsigned long speed = 0;
+ struct team_port *port;
+
+ cmd->base.duplex = DUPLEX_UNKNOWN;
+ cmd->base.port = PORT_OTHER;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(port, &team->port_list, list) {
+ if (team_port_txable(port)) {
+ if (port->state.speed != SPEED_UNKNOWN)
+ speed += port->state.speed;
+ if (cmd->base.duplex == DUPLEX_UNKNOWN &&
+ port->state.duplex != DUPLEX_UNKNOWN)
+ cmd->base.duplex = port->state.duplex;
+ }
+ }
+ rcu_read_unlock();
+
+ cmd->base.speed = speed ? : SPEED_UNKNOWN;
+
+ return 0;
+}
+
static const struct ethtool_ops team_ethtool_ops = {
.get_drvinfo = team_ethtool_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_link_ksettings = team_ethtool_get_link_ksettings,
};
/***********************
@@ -2306,7 +2344,7 @@
if (err)
return err;
- option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
+ option_item = nla_nest_start_noflag(skb, TEAM_ATTR_ITEM_OPTION);
if (!option_item)
return -EMSGSIZE;
@@ -2420,7 +2458,7 @@
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
- option_list = nla_nest_start(skb, TEAM_ATTR_LIST_OPTION);
+ option_list = nla_nest_start_noflag(skb, TEAM_ATTR_LIST_OPTION);
if (!option_list)
goto nla_put_failure;
@@ -2526,9 +2564,11 @@
err = -EINVAL;
goto team_put;
}
- err = nla_parse_nested(opt_attrs, TEAM_ATTR_OPTION_MAX,
- nl_option, team_nl_option_policy,
- info->extack);
+ err = nla_parse_nested_deprecated(opt_attrs,
+ TEAM_ATTR_OPTION_MAX,
+ nl_option,
+ team_nl_option_policy,
+ info->extack);
if (err)
goto team_put;
if (!opt_attrs[TEAM_ATTR_OPTION_NAME] ||
@@ -2642,7 +2682,7 @@
{
struct nlattr *port_item;
- port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_PORT);
+ port_item = nla_nest_start_noflag(skb, TEAM_ATTR_ITEM_PORT);
if (!port_item)
goto nest_cancel;
if (nla_put_u32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex))
@@ -2697,7 +2737,7 @@
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
- port_list = nla_nest_start(skb, TEAM_ATTR_LIST_PORT);
+ port_list = nla_nest_start_noflag(skb, TEAM_ATTR_LIST_PORT);
if (!port_list)
goto nla_put_failure;
@@ -2768,28 +2808,28 @@
return err;
}
-static const struct genl_ops team_nl_ops[] = {
+static const struct genl_small_ops team_nl_ops[] = {
{
.cmd = TEAM_CMD_NOOP,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = team_nl_cmd_noop,
- .policy = team_nl_policy,
},
{
.cmd = TEAM_CMD_OPTIONS_SET,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = team_nl_cmd_options_set,
- .policy = team_nl_policy,
.flags = GENL_ADMIN_PERM,
},
{
.cmd = TEAM_CMD_OPTIONS_GET,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = team_nl_cmd_options_get,
- .policy = team_nl_policy,
.flags = GENL_ADMIN_PERM,
},
{
.cmd = TEAM_CMD_PORT_LIST_GET,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = team_nl_cmd_port_list_get,
- .policy = team_nl_policy,
.flags = GENL_ADMIN_PERM,
},
};
@@ -2802,10 +2842,11 @@
.name = TEAM_GENL_NAME,
.version = TEAM_GENL_VERSION,
.maxattr = TEAM_ATTR_MAX,
+ .policy = team_nl_policy,
.netnsok = true,
.module = THIS_MODULE,
- .ops = team_nl_ops,
- .n_ops = ARRAY_SIZE(team_nl_ops),
+ .small_ops = team_nl_ops,
+ .n_small_ops = ARRAY_SIZE(team_nl_ops),
.mcgrps = team_nl_mcgrps,
.n_mcgrps = ARRAY_SIZE(team_nl_mcgrps),
};
--
Gitblit v1.6.2