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 '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>

+61 -22
+5 -1
Documentation/networking/netconsole.rst
··· 47 47 r if present, prepend kernel version (release) to the message 48 48 src-port source for UDP packets (defaults to 6665) 49 49 src-ip source IP to use (interface address) 50 - dev network interface (eth0) 50 + dev network interface name (eth0) or MAC address 51 51 tgt-port port for logging agent (6666) 52 52 tgt-ip IP address for logging agent 53 53 tgt-macaddr ethernet MAC address for logging agent (broadcast) ··· 63 63 or using IPv6:: 64 64 65 65 insmod netconsole netconsole=@/,@fd00:1:2:3::1/ 66 + 67 + or using a MAC address to select the egress interface:: 68 + 69 + linux netconsole=4444@10.0.0.1/22:33:44:55:66:77,9353@10.0.0.2/12:34:56:78:9a:bc 66 70 67 71 It also supports logging to multiple remote agents by specifying 68 72 parameters for the multiple agents separated by semicolons and the
+1 -1
drivers/net/netconsole.c
··· 739 739 740 740 if (!mac_pton(buf, remote_mac)) 741 741 goto out_unlock; 742 - if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') 742 + if (buf[MAC_ADDR_STR_LEN] && buf[MAC_ADDR_STR_LEN] != '\n') 743 743 goto out_unlock; 744 744 memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); 745 745
+1 -1
drivers/nvmem/brcm_nvram.c
··· 100 100 { 101 101 u8 mac[ETH_ALEN]; 102 102 103 - if (bytes != 3 * ETH_ALEN - 1) 103 + if (bytes != MAC_ADDR_STR_LEN) 104 104 return -EINVAL; 105 105 106 106 if (!mac_pton(buf, mac))
+1 -1
drivers/nvmem/layouts/u-boot-env.c
··· 37 37 { 38 38 u8 mac[ETH_ALEN]; 39 39 40 - if (bytes != 3 * ETH_ALEN - 1) 40 + if (bytes != MAC_ADDR_STR_LEN) 41 41 return -EINVAL; 42 42 43 43 if (!mac_pton(buf, mac))
+3
include/linux/if_ether.h
··· 19 19 #include <linux/skbuff.h> 20 20 #include <uapi/linux/if_ether.h> 21 21 22 + /* XX:XX:XX:XX:XX:XX */ 23 + #define MAC_ADDR_STR_LEN (3 * ETH_ALEN - 1) 24 + 22 25 static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) 23 26 { 24 27 return (struct ethhdr *)skb_mac_header(skb);
+6
include/linux/netpoll.h
··· 25 25 struct netpoll { 26 26 struct net_device *dev; 27 27 netdevice_tracker dev_tracker; 28 + /* 29 + * Either dev_name or dev_mac can be used to specify the local 30 + * interface - dev_name is used if it is a nonempty string, else 31 + * dev_mac is used. 32 + */ 28 33 char dev_name[IFNAMSIZ]; 34 + u8 dev_mac[ETH_ALEN]; 29 35 const char *name; 30 36 31 37 union inet_addr local_ip, remote_ip;
+1 -3
lib/net_utils.c
··· 7 7 8 8 bool mac_pton(const char *s, u8 *mac) 9 9 { 10 - size_t maxlen = 3 * ETH_ALEN - 1; 11 10 int i; 12 11 13 - /* XX:XX:XX:XX:XX:XX */ 14 - if (strnlen(s, maxlen) < maxlen) 12 + if (strnlen(s, MAC_ADDR_STR_LEN) < MAC_ADDR_STR_LEN) 15 13 return false; 16 14 17 15 /* Don't dirty result unless string is valid MAC. */
+39 -12
net/core/netpoll.c
··· 507 507 np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6); 508 508 else 509 509 np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip); 510 - np_info(np, "interface '%s'\n", np->dev_name); 510 + np_info(np, "interface name '%s'\n", np->dev_name); 511 + np_info(np, "local ethernet address '%pM'\n", np->dev_mac); 511 512 np_info(np, "remote port %d\n", np->remote_port); 512 513 if (np->ipv6) 513 514 np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6); ··· 578 577 cur++; 579 578 580 579 if (*cur != ',') { 581 - /* parse out dev name */ 580 + /* parse out dev_name or dev_mac */ 582 581 if ((delim = strchr(cur, ',')) == NULL) 583 582 goto parse_failed; 584 583 *delim = 0; 585 - strscpy(np->dev_name, cur, sizeof(np->dev_name)); 584 + 585 + np->dev_name[0] = '\0'; 586 + eth_broadcast_addr(np->dev_mac); 587 + if (!strchr(cur, ':')) 588 + strscpy(np->dev_name, cur, sizeof(np->dev_name)); 589 + else if (!mac_pton(cur, np->dev_mac)) 590 + goto parse_failed; 591 + 586 592 cur = delim; 587 593 } 588 594 cur++; ··· 703 695 } 704 696 EXPORT_SYMBOL_GPL(__netpoll_setup); 705 697 698 + /* 699 + * Returns a pointer to a string representation of the identifier used 700 + * to select the egress interface for the given netpoll instance. buf 701 + * must be a buffer of length at least MAC_ADDR_STR_LEN + 1. 702 + */ 703 + static char *egress_dev(struct netpoll *np, char *buf) 704 + { 705 + if (np->dev_name[0]) 706 + return np->dev_name; 707 + 708 + snprintf(buf, MAC_ADDR_STR_LEN, "%pM", np->dev_mac); 709 + return buf; 710 + } 711 + 706 712 int netpoll_setup(struct netpoll *np) 707 713 { 714 + struct net *net = current->nsproxy->net_ns; 715 + char buf[MAC_ADDR_STR_LEN + 1]; 708 716 struct net_device *ndev = NULL; 709 717 bool ip_overwritten = false; 710 718 struct in_device *in_dev; 711 719 int err; 712 720 713 721 rtnl_lock(); 714 - if (np->dev_name[0]) { 715 - struct net *net = current->nsproxy->net_ns; 722 + if (np->dev_name[0]) 716 723 ndev = __dev_get_by_name(net, np->dev_name); 717 - } 724 + else if (is_valid_ether_addr(np->dev_mac)) 725 + ndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np->dev_mac); 726 + 718 727 if (!ndev) { 719 - np_err(np, "%s doesn't exist, aborting\n", np->dev_name); 728 + np_err(np, "%s doesn't exist, aborting\n", egress_dev(np, buf)); 720 729 err = -ENODEV; 721 730 goto unlock; 722 731 } 723 732 netdev_hold(ndev, &np->dev_tracker, GFP_KERNEL); 724 733 725 734 if (netdev_master_upper_dev_get(ndev)) { 726 - np_err(np, "%s is a slave device, aborting\n", np->dev_name); 735 + np_err(np, "%s is a slave device, aborting\n", 736 + egress_dev(np, buf)); 727 737 err = -EBUSY; 728 738 goto put; 729 739 } ··· 749 723 if (!netif_running(ndev)) { 750 724 unsigned long atmost; 751 725 752 - np_info(np, "device %s not up yet, forcing it\n", np->dev_name); 726 + np_info(np, "device %s not up yet, forcing it\n", 727 + egress_dev(np, buf)); 753 728 754 729 err = dev_open(ndev, NULL); 755 730 ··· 784 757 if (!ifa) { 785 758 put_noaddr: 786 759 np_err(np, "no IP address for %s, aborting\n", 787 - np->dev_name); 760 + egress_dev(np, buf)); 788 761 err = -EDESTADDRREQ; 789 762 goto put; 790 763 } ··· 815 788 } 816 789 if (err) { 817 790 np_err(np, "no IPv6 address for %s, aborting\n", 818 - np->dev_name); 791 + egress_dev(np, buf)); 819 792 goto put; 820 793 } else 821 794 np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6); 822 795 #else 823 796 np_err(np, "IPv6 is not supported %s, aborting\n", 824 - np->dev_name); 797 + egress_dev(np, buf)); 825 798 err = -EINVAL; 826 799 goto put; 827 800 #endif
+4 -3
net/mac80211/debugfs_sta.c
··· 457 457 size_t count, loff_t *ppos) 458 458 { 459 459 struct link_sta_info *link_sta = file->private_data; 460 - u8 mac[3 * ETH_ALEN + 1]; 460 + u8 mac[MAC_ADDR_STR_LEN + 2]; 461 461 462 462 snprintf(mac, sizeof(mac), "%pM\n", link_sta->pub->addr); 463 463 464 - return simple_read_from_buffer(userbuf, count, ppos, mac, 3 * ETH_ALEN); 464 + return simple_read_from_buffer(userbuf, count, ppos, mac, 465 + MAC_ADDR_STR_LEN + 1); 465 466 } 466 467 467 468 LINK_STA_OPS(addr); ··· 1241 1240 struct ieee80211_local *local = sta->local; 1242 1241 struct ieee80211_sub_if_data *sdata = sta->sdata; 1243 1242 struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations; 1244 - u8 mac[3*ETH_ALEN]; 1243 + u8 mac[MAC_ADDR_STR_LEN + 1]; 1245 1244 1246 1245 if (!stations_dir) 1247 1246 return;