mirror of
https://github.com/torvalds/linux.git
synced 2026-10-04 02:09:03 +02:00
pppox: drain queued packets on channel handoff
PPPIOCGCHAN both returns the channel index and marks a PPPOX socket as
bound to generic PPP, despite its getter semantic. Packets received
before that transition are queued on sk_receive_queue, but a bound
socket is no longer readable. Such packets therefore remain queued until
the socket is destroyed.
After marking a socket bound, wait for receive paths that observed the
old state to finish queueing packets, and then drain the queue into
generic PPP.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Link: https://patch.msgid.link/20260811035314.302878-1-qingfang.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
4f1d06cf8a
commit
92c1bf630a
|
|
@ -74,7 +74,9 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||
|
||||
switch (cmd) {
|
||||
case PPPIOCGCHAN: {
|
||||
struct sk_buff *skb;
|
||||
int index;
|
||||
|
||||
rc = -ENOTCONN;
|
||||
if (!(sk->sk_state & PPPOX_CONNECTED))
|
||||
break;
|
||||
|
|
@ -85,7 +87,22 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
|
||||
rc = 0;
|
||||
/* PPPIOCGCHAN historically marks the userspace handoff to
|
||||
* generic PPP; pppd then attaches the returned channel to
|
||||
* /dev/ppp.
|
||||
*/
|
||||
sk->sk_state |= PPPOX_BOUND;
|
||||
/* Let lockless receive paths finish queueing against the old
|
||||
* state.
|
||||
*/
|
||||
synchronize_net();
|
||||
/* Drain packets queued before the handoff because a bound
|
||||
* socket is no longer readable.
|
||||
*/
|
||||
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
|
||||
skb_orphan(skb);
|
||||
ppp_input(&po->chan, skb);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user