Skip to content

Commit

Permalink
Merge branch 'netconsole-allow-selection-of-egress-interface-via-mac-…
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
Paolo Abeni committed Mar 19, 2025
2 parents 34e5ede + f8a10be commit 8904eeb
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 22 deletions.
6 changes: 5 additions & 1 deletion Documentation/networking/netconsole.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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::
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/netconsole.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion drivers/nvmem/brcm_nvram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion drivers/nvmem/layouts/u-boot-env.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 3 additions & 0 deletions include/linux/if_ether.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions include/linux/netpoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 1 addition & 3 deletions lib/net_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
51 changes: 39 additions & 12 deletions net/core/netpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -695,35 +703,54 @@ 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;
}

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);

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions net/mac80211/debugfs_sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 8904eeb

Please sign in to comment.