From: James Chapman <jchapman@katalix.com>
To: Xin Long <lucien.xin@gmail.com>
Cc: network dev <netdev@vger.kernel.org>,
davem@davemloft.net, Guillaume Nault <gnault@redhat.com>
Subject: Re: [PATCH net] l2tp: remove skb_dst_set() from l2tp_xmit_skb()
Date: Tue, 7 Jul 2020 18:24:08 +0100 [thread overview]
Message-ID: <20200707172408.GA22308@katalix.com> (raw)
In-Reply-To: <57ec206296ac8049d51755667b69aa0e978e3d6e.1594058552.git.lucien.xin@gmail.com>
On Tue, Jul 07, 2020 at 02:02:32 +0800, Xin Long wrote:
> In the tx path of l2tp, l2tp_xmit_skb() calls skb_dst_set() to set
> skb's dst. However, it will eventually call inet6_csk_xmit() or
> ip_queue_xmit() where skb's dst will be overwritten by:
>
> skb_dst_set_noref(skb, dst);
>
> without releasing the old dst in skb. Then it causes dst/dev refcnt leak:
>
> unregister_netdevice: waiting for eth0 to become free. Usage count = 1
>
> This can be reproduced by simply running:
>
> # modprobe l2tp_eth && modprobe l2tp_ip
> # sh ./tools/testing/selftests/net/l2tp.sh
>
> So before going to inet6_csk_xmit() or ip_queue_xmit(), skb's dst
> should be dropped. This patch is to fix it by removing skb_dst_set()
> from l2tp_xmit_skb() and moving skb_dst_drop() into l2tp_xmit_core().
>
> Fixes: 3557baabf280 ("[L2TP]: PPP over L2TP driver core")
> Reported-by: Hangbin Liu <liuhangbin@gmail.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
> net/l2tp/l2tp_core.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
> index fcb53ed..df133c24 100644
> --- a/net/l2tp/l2tp_core.c
> +++ b/net/l2tp/l2tp_core.c
> @@ -1028,6 +1028,7 @@ static void l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
>
> /* Queue the packet to IP for output */
> skb->ignore_df = 1;
> + skb_dst_drop(skb);
> #if IS_ENABLED(CONFIG_IPV6)
> if (l2tp_sk_is_v6(tunnel->sock))
> error = inet6_csk_xmit(tunnel->sock, skb, NULL);
> @@ -1099,10 +1100,6 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
> goto out_unlock;
> }
>
> - /* Get routing info from the tunnel socket */
> - skb_dst_drop(skb);
> - skb_dst_set(skb, sk_dst_check(sk, 0));
> -
> inet = inet_sk(sk);
> fl = &inet->cork.fl;
> switch (tunnel->encap) {
> --
> 2.1.0
>
This patch doesn't seem right.
For ipv4, the skb dst is used by skb_rtable. In ip_queue_xmit, if
skb_rtable returns a route, it follows the packet_routed label and
skb_dst_set_noref isn't done. Your patch is forcing every ipv4 l2tp
packet to be routed, which isn't what we want.
I ran l2tp.sh and found that the issue happens only for l2tp tests
that use IPv6 IPSec in a routed topology.
Perhaps the real problem is that l2tp shouldn't be using
inet6_csk_xmit and should instead use ip6_xmit?
Please hold off on applying this patch while I look into it.
next prev parent reply other threads:[~2020-07-07 17:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-06 18:02 [PATCH net] l2tp: remove skb_dst_set() from l2tp_xmit_skb() Xin Long
2020-07-07 17:24 ` James Chapman [this message]
2020-07-07 20:08 ` Xin Long
2020-07-08 10:04 ` James Chapman
2020-07-08 22:25 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200707172408.GA22308@katalix.com \
--to=jchapman@katalix.com \
--cc=davem@davemloft.net \
--cc=gnault@redhat.com \
--cc=lucien.xin@gmail.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.