[RFC PATCH net-next v2] ppp: use IFF_NO_QUEUE in virtual interfaces

Qingfang Deng posted 1 patch 11 months, 2 weeks ago
There is a newer version of this series
drivers/net/ppp/ppp_generic.c | 4 ++++
drivers/net/ppp/pppoe.c       | 1 +
drivers/net/ppp/pptp.c        | 1 +
include/linux/ppp_channel.h   | 1 +
net/l2tp/l2tp_ppp.c           | 1 +
5 files changed, 8 insertions(+)
[RFC PATCH net-next v2] ppp: use IFF_NO_QUEUE in virtual interfaces
Posted by Qingfang Deng 11 months, 2 weeks ago
For PPPoE, PPTP, and PPPoL2TP, the start_xmit() function directly
forwards packets to the underlying network stack and never returns
anything other than 1. So these interfaces do not require a qdisc,
and the IFF_NO_QUEUE flag should be set.

Introduces a direct_xmit flag in struct ppp_channel to indicate when
IFF_NO_QUEUE should be applied. The flag is set in ppp_connect_channel()
for relevant protocols.

Signed-off-by: Qingfang Deng <dqfext@gmail.com>
---
RFC v1 -> v2: Conditionally set the flag for relevant protocols.

I'm not sure if ppp_connect_channel can be invoked while the device
is still up. As a qdisc is attached in dev_activate() called by
dev_open(), setting the IFF_NO_QUEUE flag on a running device will have
no effect.

 drivers/net/ppp/ppp_generic.c | 4 ++++
 drivers/net/ppp/pppoe.c       | 1 +
 drivers/net/ppp/pptp.c        | 1 +
 include/linux/ppp_channel.h   | 1 +
 net/l2tp/l2tp_ppp.c           | 1 +
 5 files changed, 8 insertions(+)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 6220866258fc..815108c98b78 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -3493,6 +3493,10 @@ ppp_connect_channel(struct channel *pch, int unit)
 		ret = -ENOTCONN;
 		goto outl;
 	}
+	if (pch->chan->direct_xmit)
+		ppp->dev->priv_flags |= IFF_NO_QUEUE;
+	else
+		ppp->dev->priv_flags &= ~IFF_NO_QUEUE;
 	spin_unlock_bh(&pch->downl);
 	if (pch->file.hdrlen > ppp->file.hdrlen)
 		ppp->file.hdrlen = pch->file.hdrlen;
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 2ea4f4890d23..68e631718ab0 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -693,6 +693,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
 		po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2;
 		po->chan.private = sk;
 		po->chan.ops = &pppoe_chan_ops;
+		po->chan.direct_xmit = true;
 
 		error = ppp_register_net_channel(dev_net(dev), &po->chan);
 		if (error) {
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index 689687bd2574..5feaa70b5f47 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -465,6 +465,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
 	po->chan.mtu -= PPTP_HEADER_OVERHEAD;
 
 	po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header);
+	po->chan.direct_xmit = true;
 	error = ppp_register_channel(&po->chan);
 	if (error) {
 		pr_err("PPTP: failed to register PPP channel (%d)\n", error);
diff --git a/include/linux/ppp_channel.h b/include/linux/ppp_channel.h
index 45e6e427ceb8..3b50802d66fc 100644
--- a/include/linux/ppp_channel.h
+++ b/include/linux/ppp_channel.h
@@ -44,6 +44,7 @@ struct ppp_channel {
 	int		speed;		/* transfer rate (bytes/second) */
 	/* the following is not used at present */
 	int		latency;	/* overhead time in milliseconds */
+	bool		direct_xmit;	/* no qdisc, xmit directly */
 };
 
 #ifdef __KERNEL__
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 53baf2dd5d5d..fc5c2fd8f34c 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -806,6 +806,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
 	po->chan.private = sk;
 	po->chan.ops	 = &pppol2tp_chan_ops;
 	po->chan.mtu	 = pppol2tp_tunnel_mtu(tunnel);
+	po->chan.direct_xmit	= true;
 
 	error = ppp_register_net_channel(sock_net(sk), &po->chan);
 	if (error) {
-- 
2.43.0
Re: [RFC PATCH net-next v2] ppp: use IFF_NO_QUEUE in virtual interfaces
Posted by Toke Høiland-Jørgensen 11 months, 2 weeks ago
Qingfang Deng <dqfext@gmail.com> writes:

> For PPPoE, PPTP, and PPPoL2TP, the start_xmit() function directly
> forwards packets to the underlying network stack and never returns
> anything other than 1. So these interfaces do not require a qdisc,
> and the IFF_NO_QUEUE flag should be set.
>
> Introduces a direct_xmit flag in struct ppp_channel to indicate when
> IFF_NO_QUEUE should be applied. The flag is set in ppp_connect_channel()
> for relevant protocols.
>
> Signed-off-by: Qingfang Deng <dqfext@gmail.com>
> ---
> RFC v1 -> v2: Conditionally set the flag for relevant protocols.
>
> I'm not sure if ppp_connect_channel can be invoked while the device
> is still up. As a qdisc is attached in dev_activate() called by
> dev_open(), setting the IFF_NO_QUEUE flag on a running device will have
> no effect.

No idea either. I don't think there's anything on the kernel side
preventing it, but it would make the most sense if the interface isn't
brought up before the underlying transport is established?

Anyway, assuming this is the case, I think this approach is better, so:

Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>