[PATCH net-next] pppoe: optional deactivation of PADT packet handling

Subsystems: networking drivers, ppp over ethernet, the rest

STALE3925d

4 messages, 3 authors, 2015-12-16 · open the first message on its own page

[PATCH net-next] pppoe: optional deactivation of PADT packet handling

From: Guillaume Nault <hidden>
Date: 2015-12-15 16:06:43

Kernel space shouldn't handle PADT packets since PADT belongs to
PPPoE's control plane.
With "handle_padt" module option, user space can now decide to avoid
kernel interpretation of PADT packets and be responsible for session
disconnection.

Signed-off-by: Guillaume Nault <redacted>
---
The two open-source PPPoE programs I know of are accel-ppp and pppd
(with the rp-pppoe plugin). Accel-ppp already handles PADT, while
pppd + rp-pppoe doesn't (seems like it doesn't even listen to its
PPPoE Discovery socket once session is established).


 drivers/net/ppp/pppoe.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index b8da2ea..1846c3a 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -109,6 +109,18 @@ struct pppoe_net {
 	rwlock_t hash_lock;
 };
 
+/* PADT packets belong to PPPoE's discovery stage (i.e. control plane)
+ * and should be handled by user space. Unfortunately, some programs
+ * don't listen out for PADT packets and rely on pppoe module for
+ * closing session after reception of PADT.
+ *
+ * This option can be deactivated when PPPoE discovery is handled by
+ * a PADT aware program.
+ */
+static bool handle_padt __read_mostly = true;
+module_param(handle_padt, bool, 0444);
+MODULE_PARM_DESC(handle_padt, "Let kernel interpret incoming PADT");
+
 /*
  * PPPoE could be in the following stages:
  * 1) Discovery stage (to obtain remote MAC and Session ID)
@@ -1173,7 +1185,8 @@ static int __init pppoe_init(void)
 		goto out_unregister_pppoe_proto;
 
 	dev_add_pack(&pppoes_ptype);
-	dev_add_pack(&pppoed_ptype);
+	if (handle_padt)
+		dev_add_pack(&pppoed_ptype);
 	register_netdevice_notifier(&pppoe_notifier);
 
 	return 0;
@@ -1189,7 +1202,8 @@ out:
 static void __exit pppoe_exit(void)
 {
 	unregister_netdevice_notifier(&pppoe_notifier);
-	dev_remove_pack(&pppoed_ptype);
+	if (handle_padt)
+		dev_remove_pack(&pppoed_ptype);
 	dev_remove_pack(&pppoes_ptype);
 	unregister_pppox_proto(PX_PROTO_OE);
 	proto_unregister(&pppoe_sk_proto);
-- 
2.6.4

Re: [PATCH net-next] pppoe: optional deactivation of PADT packet handling

From: Dan Williams <hidden>
Date: 2015-12-15 16:50:05

On Tue, 2015-12-15 at 17:06 +0100, Guillaume Nault wrote:
Kernel space shouldn't handle PADT packets since PADT belongs to
PPPoE's control plane.
With "handle_padt" module option, user space can now decide to avoid
kernel interpretation of PADT packets and be responsible for session
disconnection.
In general, module options like this kinda suck.  How about a new PPPoE
ioctl so the option can be toggled for a given socket/session instead? 
 Then at least you're not locked into a specific PPPoE implementation
for all sessions on the machine.

Dan
quoted hunk
Signed-off-by: Guillaume Nault <redacted>
---
The two open-source PPPoE programs I know of are accel-ppp and pppd
(with the rp-pppoe plugin). Accel-ppp already handles PADT, while
pppd + rp-pppoe doesn't (seems like it doesn't even listen to its
PPPoE Discovery socket once session is established).


 drivers/net/ppp/pppoe.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index b8da2ea..1846c3a 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -109,6 +109,18 @@ struct pppoe_net {
 	rwlock_t hash_lock;
 };
 
+/* PADT packets belong to PPPoE's discovery stage (i.e. control
plane)
+ * and should be handled by user space. Unfortunately, some programs
+ * don't listen out for PADT packets and rely on pppoe module for
+ * closing session after reception of PADT.
+ *
+ * This option can be deactivated when PPPoE discovery is handled by
+ * a PADT aware program.
+ */
+static bool handle_padt __read_mostly = true;
+module_param(handle_padt, bool, 0444);
+MODULE_PARM_DESC(handle_padt, "Let kernel interpret incoming PADT");
+
 /*
  * PPPoE could be in the following stages:
  * 1) Discovery stage (to obtain remote MAC and Session ID)
@@ -1173,7 +1185,8 @@ static int __init pppoe_init(void)
 		goto out_unregister_pppoe_proto;
 
 	dev_add_pack(&pppoes_ptype);
-	dev_add_pack(&pppoed_ptype);
+	if (handle_padt)
+		dev_add_pack(&pppoed_ptype);
 	register_netdevice_notifier(&pppoe_notifier);
 
 	return 0;
@@ -1189,7 +1202,8 @@ out:
 static void __exit pppoe_exit(void)
 {
 	unregister_netdevice_notifier(&pppoe_notifier);
-	dev_remove_pack(&pppoed_ptype);
+	if (handle_padt)
+		dev_remove_pack(&pppoed_ptype);
 	dev_remove_pack(&pppoes_ptype);
 	unregister_pppox_proto(PX_PROTO_OE);
 	proto_unregister(&pppoe_sk_proto);

Re: [PATCH net-next] pppoe: optional deactivation of PADT packet handling

From: David Miller <davem@davemloft.net>
Date: 2015-12-15 18:15:14

From: Guillaume Nault <redacted>
Date: Tue, 15 Dec 2015 17:06:39 +0100
quoted hunk
@@ -109,6 +109,18 @@ struct pppoe_net {
 	rwlock_t hash_lock;
 };
 
+/* PADT packets belong to PPPoE's discovery stage (i.e. control plane)
+ * and should be handled by user space. Unfortunately, some programs
+ * don't listen out for PADT packets and rely on pppoe module for
+ * closing session after reception of PADT.
+ *
+ * This option can be deactivated when PPPoE discovery is handled by
+ * a PADT aware program.
+ */
+static bool handle_padt __read_mostly = true;
+module_param(handle_padt, bool, 0444);
+MODULE_PARM_DESC(handle_padt, "Let kernel interpret incoming PADT");
No module options, please.

Re: [PATCH net-next] pppoe: optional deactivation of PADT packet handling

From: Guillaume Nault <hidden>
Date: 2015-12-16 15:39:17

On Tue, Dec 15, 2015 at 10:50:05AM -0600, Dan Williams wrote:
On Tue, 2015-12-15 at 17:06 +0100, Guillaume Nault wrote:
quoted
Kernel space shouldn't handle PADT packets since PADT belongs to
PPPoE's control plane.
With "handle_padt" module option, user space can now decide to avoid
kernel interpretation of PADT packets and be responsible for session
disconnection.
In general, module options like this kinda suck.  How about a new PPPoE
ioctl so the option can be toggled for a given socket/session instead? 
 Then at least you're not locked into a specific PPPoE implementation
for all sessions on the machine.
I've considered this approach too, but by using per session option,
we still have to register pppoed_ptype in pppoe_init() and thus call
pppoe_disc_recv() for any ETH_P_PPP_DISC frame, just in case a session
needs kernel space PADT handling. This makes the approach much less
interesting IMO, hence the original choice for module wide behaviour.
On the other hand, I understand the need for minimising module options.

Thinking a bit more about it, we could drop dev_add_pack() from
pppoe_init() and let pppoe_connect() register ETH_P_PPP_DISC when
necessary. We could even do it per device, as pppoe_connect() knows the
lower device.
The problem is to know when unregistering ETH_P_PPP_DISC. We could
probably use a reference counter, but I'd prefer to avoid complicating
pppoe's connection and disconnection code given that recent history
has shown its relative fragility.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help