During kernel startup phase, current netconsole doesn’t support VLAN since there is no VLAN interface setup already. This patch provides VLAN ID and PCP as optional boot/module parameters to support VLAN environment, thus kernel startup log can be retrieved via VLAN. Signed-off-by: Libing Zhou <libing.zhou@xxxxxxxxxxxxxxx> --- Documentation/networking/netconsole.rst | 10 ++++- drivers/net/netconsole.c | 3 +- include/linux/netpoll.h | 3 ++ net/core/netpoll.c | 58 ++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Documentation/networking/netconsole.rst b/Documentation/networking/netconsole.rst index 1f5c4a04027c..a08387fcc3f0 100644 --- a/Documentation/networking/netconsole.rst +++ b/Documentation/networking/netconsole.rst @@ -13,6 +13,8 @@ IPv6 support by Cong Wang <xiyou.wangcong@xxxxxxxxx>, Jan 1 2013 Extended console support by Tejun Heo <tj@xxxxxxxxxx>, May 1 2015 +VLAN support by Libing Zhou <libing.zhou@xxxxxxxxxxxxxxx>, Dec 8 2020 + Please send bug reports to Matt Mackall <mpm@xxxxxxxxxxx> Satyam Sharma <satyam.sharma@xxxxxxxxx>, and Cong Wang <xiyou.wangcong@xxxxxxxxx> @@ -34,7 +36,7 @@ Sender and receiver configuration: It takes a string configuration parameter "netconsole" in the following format:: - netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr] + netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr][-V<vid:pcp>] where + if present, enable extended console support @@ -44,11 +46,17 @@ following format:: tgt-port port for logging agent (6666) tgt-ip IP address for logging agent tgt-macaddr ethernet MAC address for logging agent (broadcast) + -V if present, enable VLAN support + vid:pcp VLAN identifier and priority code point Examples:: linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc +or using VLAN:: + + linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc-V100:1 + or:: insmod netconsole netconsole=@/,@10.0.0.2/ diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 92001f7af380..f0690cd6a744 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -36,7 +36,6 @@ #include <linux/inet.h> #include <linux/configfs.h> #include <linux/etherdevice.h> - MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@xxxxxxxxxxx>"); MODULE_DESCRIPTION("Console driver for network interfaces"); MODULE_LICENSE("GPL"); @@ -46,7 +45,7 @@ MODULE_LICENSE("GPL"); static char config[MAX_PARAM_LENGTH]; module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0); -MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]"); +MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr][-V<vid:pcp>]"); static bool oops_only = false; module_param(oops_only, bool, 0600); diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index e6a2d72e0dc7..8ab3f25cadae 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -31,6 +31,9 @@ struct netpoll { bool ipv6; u16 local_port, remote_port; u8 remote_mac[ETH_ALEN]; + bool vlan_present; + u16 vlan_id; + u8 pcp; }; struct netpoll_info { diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 2338753e936b..077a7aec51ae 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -478,6 +478,14 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) skb->dev = np->dev; + if (np->vlan_present) { + skb->vlan_proto = htons(ETH_P_8021Q); + + /* htons for tci is done in __vlan_insert_inner_tag, not here */ + skb->vlan_tci = (np->pcp << VLAN_PRIO_SHIFT) + (np->vlan_id & VLAN_VID_MASK); + skb->vlan_present = 1; + } + netpoll_send_skb(np, skb); } EXPORT_SYMBOL(netpoll_send_udp); @@ -496,6 +504,11 @@ void netpoll_print_options(struct netpoll *np) else np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip); np_info(np, "remote ethernet address %pM\n", np->remote_mac); + + if (np->vlan_present) { + np_info(np, "vlan id %d\n", np->vlan_id); + np_info(np, "pcp %d\n", np->pcp); + } } EXPORT_SYMBOL(netpoll_print_options); @@ -587,10 +600,46 @@ int netpoll_parse_options(struct netpoll *np, char *opt) if (*cur != 0) { /* MAC address */ - if (!mac_pton(cur, np->remote_mac)) + delim = strchr(cur, '-'); + if (delim) + *delim = 0; + if (*cur != 0) { + if (!mac_pton(cur, np->remote_mac)) + goto parse_failed; + } + if (!delim) + goto parse_done; + } + + cur = delim + 1; + if (*cur == 'V') { + /* vlan id */ + cur++; + delim = strchr(cur, ':'); + if (!delim) + goto parse_failed; + np->vlan_present = 1; + *delim = 0; + if (kstrtou16(cur, 10, &np->vlan_id)) goto parse_failed; + if (np->vlan_id > 4094) { + np_info(np, "error: set vlan id: %d is illegal, allowed range 0-4094\n", + np->vlan_id); + return -1; + } + cur = delim + 1; + + /* vlan pcp */ + if (kstrtou8(cur, 10, &np->pcp)) + goto parse_failed; + if (np->pcp > 7) { + np_info(np, "error: set pcp value: %d is illegal, allowed range 0-7\n", + np->pcp); + return -1; + } } + parse_done: netpoll_print_options(np); return 0; @@ -671,6 +720,13 @@ int netpoll_setup(struct netpoll *np) err = -ENODEV; goto unlock; } + if (is_vlan_dev(ndev) && np->vlan_present) { + np_err(np, "%s is vlan interface already, can't support with extra vlan parameter\n", + np->dev_name); + err = -ENODEV; + goto unlock; + } + dev_hold(ndev); if (netdev_master_upper_dev_get(ndev)) { -- 2.25.1