hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/l2tp/l2tp_ppp.c
....@@ -651,6 +651,65 @@
651651 return mtu - PPPOL2TP_HEADER_OVERHEAD;
652652 }
653653
654
+static struct l2tp_tunnel *pppol2tp_tunnel_get(struct net *net,
655
+ const struct l2tp_connect_info *info,
656
+ bool *new_tunnel)
657
+{
658
+ struct l2tp_tunnel *tunnel;
659
+ int error;
660
+
661
+ *new_tunnel = false;
662
+
663
+ tunnel = l2tp_tunnel_get(net, info->tunnel_id);
664
+
665
+ /* Special case: create tunnel context if session_id and
666
+ * peer_session_id is 0. Otherwise look up tunnel using supplied
667
+ * tunnel id.
668
+ */
669
+ if (!info->session_id && !info->peer_session_id) {
670
+ if (!tunnel) {
671
+ struct l2tp_tunnel_cfg tcfg = {
672
+ .encap = L2TP_ENCAPTYPE_UDP,
673
+ };
674
+
675
+ /* Prevent l2tp_tunnel_register() from trying to set up
676
+ * a kernel socket.
677
+ */
678
+ if (info->fd < 0)
679
+ return ERR_PTR(-EBADF);
680
+
681
+ error = l2tp_tunnel_create(info->fd,
682
+ info->version,
683
+ info->tunnel_id,
684
+ info->peer_tunnel_id, &tcfg,
685
+ &tunnel);
686
+ if (error < 0)
687
+ return ERR_PTR(error);
688
+
689
+ l2tp_tunnel_inc_refcount(tunnel);
690
+ error = l2tp_tunnel_register(tunnel, net, &tcfg);
691
+ if (error < 0) {
692
+ kfree(tunnel);
693
+ return ERR_PTR(error);
694
+ }
695
+
696
+ *new_tunnel = true;
697
+ }
698
+ } else {
699
+ /* Error if we can't find the tunnel */
700
+ if (!tunnel)
701
+ return ERR_PTR(-ENOENT);
702
+
703
+ /* Error if socket is not prepped */
704
+ if (!tunnel->sock) {
705
+ l2tp_tunnel_dec_refcount(tunnel);
706
+ return ERR_PTR(-ENOENT);
707
+ }
708
+ }
709
+
710
+ return tunnel;
711
+}
712
+
654713 /* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
655714 */
656715 static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
....@@ -664,7 +723,6 @@
664723 struct pppol2tp_session *ps;
665724 struct l2tp_session_cfg cfg = { 0, };
666725 bool drop_refcnt = false;
667
- bool drop_tunnel = false;
668726 bool new_session = false;
669727 bool new_tunnel = false;
670728 int error;
....@@ -672,6 +730,14 @@
672730 error = pppol2tp_sockaddr_get_info(uservaddr, sockaddr_len, &info);
673731 if (error < 0)
674732 return error;
733
+
734
+ /* Don't bind if tunnel_id is 0 */
735
+ if (!info.tunnel_id)
736
+ return -EINVAL;
737
+
738
+ tunnel = pppol2tp_tunnel_get(sock_net(sk), &info, &new_tunnel);
739
+ if (IS_ERR(tunnel))
740
+ return PTR_ERR(tunnel);
675741
676742 lock_sock(sk);
677743
....@@ -684,62 +750,6 @@
684750 error = -EALREADY;
685751 if (sk->sk_user_data)
686752 goto end; /* socket is already attached */
687
-
688
- /* Don't bind if tunnel_id is 0 */
689
- error = -EINVAL;
690
- if (!info.tunnel_id)
691
- goto end;
692
-
693
- tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id);
694
- if (tunnel)
695
- drop_tunnel = true;
696
-
697
- /* Special case: create tunnel context if session_id and
698
- * peer_session_id is 0. Otherwise look up tunnel using supplied
699
- * tunnel id.
700
- */
701
- if (!info.session_id && !info.peer_session_id) {
702
- if (!tunnel) {
703
- struct l2tp_tunnel_cfg tcfg = {
704
- .encap = L2TP_ENCAPTYPE_UDP,
705
- };
706
-
707
- /* Prevent l2tp_tunnel_register() from trying to set up
708
- * a kernel socket.
709
- */
710
- if (info.fd < 0) {
711
- error = -EBADF;
712
- goto end;
713
- }
714
-
715
- error = l2tp_tunnel_create(info.fd,
716
- info.version,
717
- info.tunnel_id,
718
- info.peer_tunnel_id, &tcfg,
719
- &tunnel);
720
- if (error < 0)
721
- goto end;
722
-
723
- l2tp_tunnel_inc_refcount(tunnel);
724
- error = l2tp_tunnel_register(tunnel, sock_net(sk),
725
- &tcfg);
726
- if (error < 0) {
727
- kfree(tunnel);
728
- goto end;
729
- }
730
- drop_tunnel = true;
731
- new_tunnel = true;
732
- }
733
- } else {
734
- /* Error if we can't find the tunnel */
735
- error = -ENOENT;
736
- if (!tunnel)
737
- goto end;
738
-
739
- /* Error if socket is not prepped */
740
- if (!tunnel->sock)
741
- goto end;
742
- }
743753
744754 if (tunnel->peer_tunnel_id == 0)
745755 tunnel->peer_tunnel_id = info.peer_tunnel_id;
....@@ -841,8 +851,7 @@
841851 }
842852 if (drop_refcnt)
843853 l2tp_session_dec_refcount(session);
844
- if (drop_tunnel)
845
- l2tp_tunnel_dec_refcount(tunnel);
854
+ l2tp_tunnel_dec_refcount(tunnel);
846855 release_sock(sk);
847856
848857 return error;