diff mbox series

net/netconsole: Support VLAN for netconsole

Message ID 20201210100742.8874-1-libing.zhou@nokia-sbell.com
State New
Headers show
Series net/netconsole: Support VLAN for netconsole | expand

Commit Message

Libing Zhou Dec. 10, 2020, 10:07 a.m. UTC
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@nokia-sbell.com>
---
 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(-)

Comments

Vladimir Oltean Dec. 12, 2020, 2:33 p.m. UTC | #1
On Thu, Dec 10, 2020 at 09:55:16AM -0800, Florian Fainelli wrote:
> 

> 

> On 12/10/2020 2:07 AM, Libing Zhou wrote:

> > 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@nokia-sbell.com>

> > ---

> >  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@gmail.com>, Jan 1 2013

> >  

> >  Extended console support by Tejun Heo <tj@kernel.org>, May 1 2015

> >  

> > +VLAN support by Libing Zhou <libing.zhou@nokia-sbell.com>, Dec 8 2020

> > +

> >  Please send bug reports to Matt Mackall <mpm@selenic.com>

> >  Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com>

> >  

> > @@ -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@selenic.com>");

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

> > +	}

> 

> This does not seem to be the way to go around this, I would rather

> specifying eth0.<VID> on the netconsole parameters and automatically

> create a VLAN interface from that which would ensure that everything

> works properly and that the VLAN interface is linked to its lower device

> properly.

> 

> If you prefer your current syntax, that is probably fine, too but you

> should consider registering a VLAN device when you parse appropriate

> options.

> -- 

> Florian


I don't have a strong opinion, considering that I have not actually
tried this. I do tend to agree with Florian about registering an 8021q
interface, as long as there aren't any other complications associated
with it. As for the syntax, I am not sure if "eth0.<VID>" is universal
enough to make an ABI out of it.
diff mbox series

Patch

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@gmail.com>, Jan 1 2013
 
 Extended console support by Tejun Heo <tj@kernel.org>, May 1 2015
 
+VLAN support by Libing Zhou <libing.zhou@nokia-sbell.com>, Dec 8 2020
+
 Please send bug reports to Matt Mackall <mpm@selenic.com>
 Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com>
 
@@ -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@selenic.com>");
 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)) {