From ea08eeccae9297f7aabd2ef7f0c2517ac4549acc Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:18:26 +0000
Subject: [PATCH] write in 30M
---
kernel/net/l2tp/l2tp_ppp.c | 127 ++++++++++++++++++++++-------------------
1 files changed, 68 insertions(+), 59 deletions(-)
diff --git a/kernel/net/l2tp/l2tp_ppp.c b/kernel/net/l2tp/l2tp_ppp.c
index aea85f9..5ecc0f2 100644
--- a/kernel/net/l2tp/l2tp_ppp.c
+++ b/kernel/net/l2tp/l2tp_ppp.c
@@ -651,6 +651,65 @@
return mtu - PPPOL2TP_HEADER_OVERHEAD;
}
+static struct l2tp_tunnel *pppol2tp_tunnel_get(struct net *net,
+ const struct l2tp_connect_info *info,
+ bool *new_tunnel)
+{
+ struct l2tp_tunnel *tunnel;
+ int error;
+
+ *new_tunnel = false;
+
+ tunnel = l2tp_tunnel_get(net, info->tunnel_id);
+
+ /* Special case: create tunnel context if session_id and
+ * peer_session_id is 0. Otherwise look up tunnel using supplied
+ * tunnel id.
+ */
+ if (!info->session_id && !info->peer_session_id) {
+ if (!tunnel) {
+ struct l2tp_tunnel_cfg tcfg = {
+ .encap = L2TP_ENCAPTYPE_UDP,
+ };
+
+ /* Prevent l2tp_tunnel_register() from trying to set up
+ * a kernel socket.
+ */
+ if (info->fd < 0)
+ return ERR_PTR(-EBADF);
+
+ error = l2tp_tunnel_create(info->fd,
+ info->version,
+ info->tunnel_id,
+ info->peer_tunnel_id, &tcfg,
+ &tunnel);
+ if (error < 0)
+ return ERR_PTR(error);
+
+ l2tp_tunnel_inc_refcount(tunnel);
+ error = l2tp_tunnel_register(tunnel, net, &tcfg);
+ if (error < 0) {
+ kfree(tunnel);
+ return ERR_PTR(error);
+ }
+
+ *new_tunnel = true;
+ }
+ } else {
+ /* Error if we can't find the tunnel */
+ if (!tunnel)
+ return ERR_PTR(-ENOENT);
+
+ /* Error if socket is not prepped */
+ if (!tunnel->sock) {
+ l2tp_tunnel_dec_refcount(tunnel);
+ return ERR_PTR(-ENOENT);
+ }
+ }
+
+ return tunnel;
+}
+
/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
*/
static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
@@ -664,7 +723,6 @@
struct pppol2tp_session *ps;
struct l2tp_session_cfg cfg = { 0, };
bool drop_refcnt = false;
- bool drop_tunnel = false;
bool new_session = false;
bool new_tunnel = false;
int error;
@@ -672,6 +730,14 @@
error = pppol2tp_sockaddr_get_info(uservaddr, sockaddr_len, &info);
if (error < 0)
return error;
+
+ /* Don't bind if tunnel_id is 0 */
+ if (!info.tunnel_id)
+ return -EINVAL;
+
+ tunnel = pppol2tp_tunnel_get(sock_net(sk), &info, &new_tunnel);
+ if (IS_ERR(tunnel))
+ return PTR_ERR(tunnel);
lock_sock(sk);
@@ -684,62 +750,6 @@
error = -EALREADY;
if (sk->sk_user_data)
goto end; /* socket is already attached */
-
- /* Don't bind if tunnel_id is 0 */
- error = -EINVAL;
- if (!info.tunnel_id)
- goto end;
-
- tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id);
- if (tunnel)
- drop_tunnel = true;
-
- /* Special case: create tunnel context if session_id and
- * peer_session_id is 0. Otherwise look up tunnel using supplied
- * tunnel id.
- */
- if (!info.session_id && !info.peer_session_id) {
- if (!tunnel) {
- struct l2tp_tunnel_cfg tcfg = {
- .encap = L2TP_ENCAPTYPE_UDP,
- };
-
- /* Prevent l2tp_tunnel_register() from trying to set up
- * a kernel socket.
- */
- if (info.fd < 0) {
- error = -EBADF;
- goto end;
- }
-
- error = l2tp_tunnel_create(info.fd,
- info.version,
- info.tunnel_id,
- info.peer_tunnel_id, &tcfg,
- &tunnel);
- if (error < 0)
- goto end;
-
- l2tp_tunnel_inc_refcount(tunnel);
- error = l2tp_tunnel_register(tunnel, sock_net(sk),
- &tcfg);
- if (error < 0) {
- kfree(tunnel);
- goto end;
- }
- drop_tunnel = true;
- new_tunnel = true;
- }
- } else {
- /* Error if we can't find the tunnel */
- error = -ENOENT;
- if (!tunnel)
- goto end;
-
- /* Error if socket is not prepped */
- if (!tunnel->sock)
- goto end;
- }
if (tunnel->peer_tunnel_id == 0)
tunnel->peer_tunnel_id = info.peer_tunnel_id;
@@ -841,8 +851,7 @@
}
if (drop_refcnt)
l2tp_session_dec_refcount(session);
- if (drop_tunnel)
- l2tp_tunnel_dec_refcount(tunnel);
+ l2tp_tunnel_dec_refcount(tunnel);
release_sock(sk);
return error;
--
Gitblit v1.6.2