mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 05:31:17 -04:00
Merge branch 'netconsole-allow-selection-of-egress-interface-via-mac-address'
Uday Shankar says: ==================== netconsole: allow selection of egress interface via MAC address This series adds support for selecting a netconsole egress interface by specifying the MAC address (in place of the interface name) in the boot/module parameter. Signed-off-by: Uday Shankar <ushankar@purestorage.com> ==================== Link: https://patch.msgid.link/20250312-netconsole-v6-0-3437933e79b8@purestorage.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
@@ -47,7 +47,7 @@ following format::
|
||||
r if present, prepend kernel version (release) to the message
|
||||
src-port source for UDP packets (defaults to 6665)
|
||||
src-ip source IP to use (interface address)
|
||||
dev network interface (eth0)
|
||||
dev network interface name (eth0) or MAC address
|
||||
tgt-port port for logging agent (6666)
|
||||
tgt-ip IP address for logging agent
|
||||
tgt-macaddr ethernet MAC address for logging agent (broadcast)
|
||||
@@ -64,6 +64,10 @@ or using IPv6::
|
||||
|
||||
insmod netconsole netconsole=@/,@fd00:1:2:3::1/
|
||||
|
||||
or using a MAC address to select the egress interface::
|
||||
|
||||
linux netconsole=4444@10.0.0.1/22:33:44:55:66:77,9353@10.0.0.2/12:34:56:78:9a:bc
|
||||
|
||||
It also supports logging to multiple remote agents by specifying
|
||||
parameters for the multiple agents separated by semicolons and the
|
||||
complete string enclosed in "quotes", thusly::
|
||||
|
||||
@@ -739,7 +739,7 @@ static ssize_t remote_mac_store(struct config_item *item, const char *buf,
|
||||
|
||||
if (!mac_pton(buf, remote_mac))
|
||||
goto out_unlock;
|
||||
if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
|
||||
if (buf[MAC_ADDR_STR_LEN] && buf[MAC_ADDR_STR_LEN] != '\n')
|
||||
goto out_unlock;
|
||||
memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, i
|
||||
{
|
||||
u8 mac[ETH_ALEN];
|
||||
|
||||
if (bytes != 3 * ETH_ALEN - 1)
|
||||
if (bytes != MAC_ADDR_STR_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mac_pton(buf, mac))
|
||||
|
||||
@@ -37,7 +37,7 @@ static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, i
|
||||
{
|
||||
u8 mac[ETH_ALEN];
|
||||
|
||||
if (bytes != 3 * ETH_ALEN - 1)
|
||||
if (bytes != MAC_ADDR_STR_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mac_pton(buf, mac))
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <uapi/linux/if_ether.h>
|
||||
|
||||
/* XX:XX:XX:XX:XX:XX */
|
||||
#define MAC_ADDR_STR_LEN (3 * ETH_ALEN - 1)
|
||||
|
||||
static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct ethhdr *)skb_mac_header(skb);
|
||||
|
||||
@@ -25,7 +25,13 @@ union inet_addr {
|
||||
struct netpoll {
|
||||
struct net_device *dev;
|
||||
netdevice_tracker dev_tracker;
|
||||
/*
|
||||
* Either dev_name or dev_mac can be used to specify the local
|
||||
* interface - dev_name is used if it is a nonempty string, else
|
||||
* dev_mac is used.
|
||||
*/
|
||||
char dev_name[IFNAMSIZ];
|
||||
u8 dev_mac[ETH_ALEN];
|
||||
const char *name;
|
||||
|
||||
union inet_addr local_ip, remote_ip;
|
||||
|
||||
@@ -7,11 +7,9 @@
|
||||
|
||||
bool mac_pton(const char *s, u8 *mac)
|
||||
{
|
||||
size_t maxlen = 3 * ETH_ALEN - 1;
|
||||
int i;
|
||||
|
||||
/* XX:XX:XX:XX:XX:XX */
|
||||
if (strnlen(s, maxlen) < maxlen)
|
||||
if (strnlen(s, MAC_ADDR_STR_LEN) < MAC_ADDR_STR_LEN)
|
||||
return false;
|
||||
|
||||
/* Don't dirty result unless string is valid MAC. */
|
||||
|
||||
@@ -507,7 +507,8 @@ void netpoll_print_options(struct netpoll *np)
|
||||
np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6);
|
||||
else
|
||||
np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip);
|
||||
np_info(np, "interface '%s'\n", np->dev_name);
|
||||
np_info(np, "interface name '%s'\n", np->dev_name);
|
||||
np_info(np, "local ethernet address '%pM'\n", np->dev_mac);
|
||||
np_info(np, "remote port %d\n", np->remote_port);
|
||||
if (np->ipv6)
|
||||
np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6);
|
||||
@@ -577,11 +578,18 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
|
||||
cur++;
|
||||
|
||||
if (*cur != ',') {
|
||||
/* parse out dev name */
|
||||
/* parse out dev_name or dev_mac */
|
||||
if ((delim = strchr(cur, ',')) == NULL)
|
||||
goto parse_failed;
|
||||
*delim = 0;
|
||||
strscpy(np->dev_name, cur, sizeof(np->dev_name));
|
||||
|
||||
np->dev_name[0] = '\0';
|
||||
eth_broadcast_addr(np->dev_mac);
|
||||
if (!strchr(cur, ':'))
|
||||
strscpy(np->dev_name, cur, sizeof(np->dev_name));
|
||||
else if (!mac_pton(cur, np->dev_mac))
|
||||
goto parse_failed;
|
||||
|
||||
cur = delim;
|
||||
}
|
||||
cur++;
|
||||
@@ -695,27 +703,45 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__netpoll_setup);
|
||||
|
||||
/*
|
||||
* Returns a pointer to a string representation of the identifier used
|
||||
* to select the egress interface for the given netpoll instance. buf
|
||||
* must be a buffer of length at least MAC_ADDR_STR_LEN + 1.
|
||||
*/
|
||||
static char *egress_dev(struct netpoll *np, char *buf)
|
||||
{
|
||||
if (np->dev_name[0])
|
||||
return np->dev_name;
|
||||
|
||||
snprintf(buf, MAC_ADDR_STR_LEN, "%pM", np->dev_mac);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int netpoll_setup(struct netpoll *np)
|
||||
{
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
char buf[MAC_ADDR_STR_LEN + 1];
|
||||
struct net_device *ndev = NULL;
|
||||
bool ip_overwritten = false;
|
||||
struct in_device *in_dev;
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
if (np->dev_name[0]) {
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
if (np->dev_name[0])
|
||||
ndev = __dev_get_by_name(net, np->dev_name);
|
||||
}
|
||||
else if (is_valid_ether_addr(np->dev_mac))
|
||||
ndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np->dev_mac);
|
||||
|
||||
if (!ndev) {
|
||||
np_err(np, "%s doesn't exist, aborting\n", np->dev_name);
|
||||
np_err(np, "%s doesn't exist, aborting\n", egress_dev(np, buf));
|
||||
err = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
netdev_hold(ndev, &np->dev_tracker, GFP_KERNEL);
|
||||
|
||||
if (netdev_master_upper_dev_get(ndev)) {
|
||||
np_err(np, "%s is a slave device, aborting\n", np->dev_name);
|
||||
np_err(np, "%s is a slave device, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
err = -EBUSY;
|
||||
goto put;
|
||||
}
|
||||
@@ -723,7 +749,8 @@ int netpoll_setup(struct netpoll *np)
|
||||
if (!netif_running(ndev)) {
|
||||
unsigned long atmost;
|
||||
|
||||
np_info(np, "device %s not up yet, forcing it\n", np->dev_name);
|
||||
np_info(np, "device %s not up yet, forcing it\n",
|
||||
egress_dev(np, buf));
|
||||
|
||||
err = dev_open(ndev, NULL);
|
||||
|
||||
@@ -757,7 +784,7 @@ int netpoll_setup(struct netpoll *np)
|
||||
if (!ifa) {
|
||||
put_noaddr:
|
||||
np_err(np, "no IP address for %s, aborting\n",
|
||||
np->dev_name);
|
||||
egress_dev(np, buf));
|
||||
err = -EDESTADDRREQ;
|
||||
goto put;
|
||||
}
|
||||
@@ -788,13 +815,13 @@ int netpoll_setup(struct netpoll *np)
|
||||
}
|
||||
if (err) {
|
||||
np_err(np, "no IPv6 address for %s, aborting\n",
|
||||
np->dev_name);
|
||||
egress_dev(np, buf));
|
||||
goto put;
|
||||
} else
|
||||
np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6);
|
||||
#else
|
||||
np_err(np, "IPv6 is not supported %s, aborting\n",
|
||||
np->dev_name);
|
||||
egress_dev(np, buf));
|
||||
err = -EINVAL;
|
||||
goto put;
|
||||
#endif
|
||||
|
||||
@@ -457,11 +457,12 @@ static ssize_t link_sta_addr_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct link_sta_info *link_sta = file->private_data;
|
||||
u8 mac[3 * ETH_ALEN + 1];
|
||||
u8 mac[MAC_ADDR_STR_LEN + 2];
|
||||
|
||||
snprintf(mac, sizeof(mac), "%pM\n", link_sta->pub->addr);
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos, mac, 3 * ETH_ALEN);
|
||||
return simple_read_from_buffer(userbuf, count, ppos, mac,
|
||||
MAC_ADDR_STR_LEN + 1);
|
||||
}
|
||||
|
||||
LINK_STA_OPS(addr);
|
||||
@@ -1240,7 +1241,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
||||
struct ieee80211_local *local = sta->local;
|
||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||
struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations;
|
||||
u8 mac[3*ETH_ALEN];
|
||||
u8 mac[MAC_ADDR_STR_LEN + 1];
|
||||
|
||||
if (!stations_dir)
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user