| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /***************************************************************************** |
|---|
| 2 | 3 | * Linux PPP over L2TP (PPPoX/PPPoL2TP) Sockets |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 11 | 12 | * Based on original work by Martijn van Oosterhout <kleptog@svana.org> |
|---|
| 12 | 13 | * |
|---|
| 13 | 14 | * License: |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or |
|---|
| 15 | | - * modify it under the terms of the GNU General Public License |
|---|
| 16 | | - * as published by the Free Software Foundation; either version |
|---|
| 17 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 18 | | - * |
|---|
| 19 | 15 | */ |
|---|
| 20 | 16 | |
|---|
| 21 | 17 | /* This driver handles only L2TP data frames; control frames are handled by a |
|---|
| .. | .. |
|---|
| 121 | 117 | int owner; /* pid that opened the socket */ |
|---|
| 122 | 118 | |
|---|
| 123 | 119 | struct mutex sk_lock; /* Protects .sk */ |
|---|
| 124 | | - struct sock __rcu *sk; /* Pointer to the session |
|---|
| 125 | | - * PPPoX socket */ |
|---|
| 120 | + struct sock __rcu *sk; /* Pointer to the session PPPoX socket */ |
|---|
| 126 | 121 | struct sock *__sk; /* Copy of .sk, for cleanup */ |
|---|
| 127 | 122 | struct rcu_head rcu; /* For asynchronous release */ |
|---|
| 128 | 123 | }; |
|---|
| .. | .. |
|---|
| 159 | 154 | { |
|---|
| 160 | 155 | struct l2tp_session *session; |
|---|
| 161 | 156 | |
|---|
| 162 | | - if (sk == NULL) |
|---|
| 157 | + if (!sk) |
|---|
| 163 | 158 | return NULL; |
|---|
| 164 | 159 | |
|---|
| 165 | 160 | sock_hold(sk); |
|---|
| 166 | 161 | session = (struct l2tp_session *)(sk->sk_user_data); |
|---|
| 167 | | - if (session == NULL) { |
|---|
| 162 | + if (!session) { |
|---|
| 168 | 163 | sock_put(sk); |
|---|
| 169 | 164 | goto out; |
|---|
| 170 | 165 | } |
|---|
| 171 | | - |
|---|
| 172 | | - BUG_ON(session->magic != L2TP_SESSION_MAGIC); |
|---|
| 166 | + if (WARN_ON(session->magic != L2TP_SESSION_MAGIC)) { |
|---|
| 167 | + session = NULL; |
|---|
| 168 | + sock_put(sk); |
|---|
| 169 | + goto out; |
|---|
| 170 | + } |
|---|
| 173 | 171 | |
|---|
| 174 | 172 | out: |
|---|
| 175 | 173 | return session; |
|---|
| .. | .. |
|---|
| 222 | 220 | */ |
|---|
| 223 | 221 | rcu_read_lock(); |
|---|
| 224 | 222 | sk = rcu_dereference(ps->sk); |
|---|
| 225 | | - if (sk == NULL) |
|---|
| 223 | + if (!sk) |
|---|
| 226 | 224 | goto no_sock; |
|---|
| 227 | 225 | |
|---|
| 228 | 226 | /* If the first two bytes are 0xFF03, consider that it is the PPP's |
|---|
| .. | .. |
|---|
| 239 | 237 | if (sk->sk_state & PPPOX_BOUND) { |
|---|
| 240 | 238 | struct pppox_sock *po; |
|---|
| 241 | 239 | |
|---|
| 242 | | - l2tp_dbg(session, L2TP_MSG_DATA, |
|---|
| 243 | | - "%s: recv %d byte data frame, passing to ppp\n", |
|---|
| 244 | | - session->name, data_len); |
|---|
| 245 | | - |
|---|
| 246 | 240 | po = pppox_sk(sk); |
|---|
| 247 | 241 | ppp_input(&po->chan, skb); |
|---|
| 248 | 242 | } else { |
|---|
| 249 | | - l2tp_dbg(session, L2TP_MSG_DATA, |
|---|
| 250 | | - "%s: recv %d byte data frame, passing to L2TP socket\n", |
|---|
| 251 | | - session->name, data_len); |
|---|
| 252 | | - |
|---|
| 253 | 243 | if (sock_queue_rcv_skb(sk, skb) < 0) { |
|---|
| 254 | 244 | atomic_long_inc(&session->stats.rx_errors); |
|---|
| 255 | 245 | kfree_skb(skb); |
|---|
| .. | .. |
|---|
| 261 | 251 | |
|---|
| 262 | 252 | no_sock: |
|---|
| 263 | 253 | rcu_read_unlock(); |
|---|
| 264 | | - l2tp_info(session, L2TP_MSG_DATA, "%s: no socket\n", session->name); |
|---|
| 254 | + pr_warn_ratelimited("%s: no socket in recv\n", session->name); |
|---|
| 265 | 255 | kfree_skb(skb); |
|---|
| 266 | 256 | } |
|---|
| 267 | 257 | |
|---|
| .. | .. |
|---|
| 290 | 280 | /* Get session and tunnel contexts */ |
|---|
| 291 | 281 | error = -EBADF; |
|---|
| 292 | 282 | session = pppol2tp_sock_to_session(sk); |
|---|
| 293 | | - if (session == NULL) |
|---|
| 283 | + if (!session) |
|---|
| 294 | 284 | goto error; |
|---|
| 295 | 285 | |
|---|
| 296 | 286 | tunnel = session->tunnel; |
|---|
| .. | .. |
|---|
| 326 | 316 | } |
|---|
| 327 | 317 | |
|---|
| 328 | 318 | local_bh_disable(); |
|---|
| 329 | | - l2tp_xmit_skb(session, skb, session->hdr_len); |
|---|
| 319 | + l2tp_xmit_skb(session, skb); |
|---|
| 330 | 320 | local_bh_enable(); |
|---|
| 331 | 321 | |
|---|
| 332 | 322 | sock_put(sk); |
|---|
| .. | .. |
|---|
| 355 | 345 | */ |
|---|
| 356 | 346 | static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) |
|---|
| 357 | 347 | { |
|---|
| 358 | | - struct sock *sk = (struct sock *) chan->private; |
|---|
| 348 | + struct sock *sk = (struct sock *)chan->private; |
|---|
| 359 | 349 | struct l2tp_session *session; |
|---|
| 360 | 350 | struct l2tp_tunnel *tunnel; |
|---|
| 361 | 351 | int uhlen, headroom; |
|---|
| .. | .. |
|---|
| 365 | 355 | |
|---|
| 366 | 356 | /* Get session and tunnel contexts from the socket */ |
|---|
| 367 | 357 | session = pppol2tp_sock_to_session(sk); |
|---|
| 368 | | - if (session == NULL) |
|---|
| 358 | + if (!session) |
|---|
| 369 | 359 | goto abort; |
|---|
| 370 | 360 | |
|---|
| 371 | 361 | tunnel = session->tunnel; |
|---|
| .. | .. |
|---|
| 385 | 375 | skb->data[1] = PPP_UI; |
|---|
| 386 | 376 | |
|---|
| 387 | 377 | local_bh_disable(); |
|---|
| 388 | | - l2tp_xmit_skb(session, skb, session->hdr_len); |
|---|
| 378 | + l2tp_xmit_skb(session, skb); |
|---|
| 389 | 379 | local_bh_enable(); |
|---|
| 390 | 380 | |
|---|
| 391 | 381 | sock_put(sk); |
|---|
| .. | .. |
|---|
| 424 | 414 | |
|---|
| 425 | 415 | if (session) { |
|---|
| 426 | 416 | sk->sk_user_data = NULL; |
|---|
| 427 | | - BUG_ON(session->magic != L2TP_SESSION_MAGIC); |
|---|
| 417 | + if (WARN_ON(session->magic != L2TP_SESSION_MAGIC)) |
|---|
| 418 | + return; |
|---|
| 428 | 419 | l2tp_session_dec_refcount(session); |
|---|
| 429 | 420 | } |
|---|
| 430 | 421 | } |
|---|
| .. | .. |
|---|
| 660 | 651 | return mtu - PPPOL2TP_HEADER_OVERHEAD; |
|---|
| 661 | 652 | } |
|---|
| 662 | 653 | |
|---|
| 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 | + |
|---|
| 663 | 713 | /* connect() handler. Attach a PPPoX socket to a tunnel UDP socket |
|---|
| 664 | 714 | */ |
|---|
| 665 | 715 | static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, |
|---|
| .. | .. |
|---|
| 673 | 723 | struct pppol2tp_session *ps; |
|---|
| 674 | 724 | struct l2tp_session_cfg cfg = { 0, }; |
|---|
| 675 | 725 | bool drop_refcnt = false; |
|---|
| 676 | | - bool drop_tunnel = false; |
|---|
| 677 | 726 | bool new_session = false; |
|---|
| 678 | 727 | bool new_tunnel = false; |
|---|
| 679 | 728 | int error; |
|---|
| .. | .. |
|---|
| 681 | 730 | error = pppol2tp_sockaddr_get_info(uservaddr, sockaddr_len, &info); |
|---|
| 682 | 731 | if (error < 0) |
|---|
| 683 | 732 | 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); |
|---|
| 684 | 741 | |
|---|
| 685 | 742 | lock_sock(sk); |
|---|
| 686 | 743 | |
|---|
| .. | .. |
|---|
| 693 | 750 | error = -EALREADY; |
|---|
| 694 | 751 | if (sk->sk_user_data) |
|---|
| 695 | 752 | goto end; /* socket is already attached */ |
|---|
| 696 | | - |
|---|
| 697 | | - /* Don't bind if tunnel_id is 0 */ |
|---|
| 698 | | - error = -EINVAL; |
|---|
| 699 | | - if (!info.tunnel_id) |
|---|
| 700 | | - goto end; |
|---|
| 701 | | - |
|---|
| 702 | | - tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id); |
|---|
| 703 | | - if (tunnel) |
|---|
| 704 | | - drop_tunnel = true; |
|---|
| 705 | | - |
|---|
| 706 | | - /* Special case: create tunnel context if session_id and |
|---|
| 707 | | - * peer_session_id is 0. Otherwise look up tunnel using supplied |
|---|
| 708 | | - * tunnel id. |
|---|
| 709 | | - */ |
|---|
| 710 | | - if (!info.session_id && !info.peer_session_id) { |
|---|
| 711 | | - if (tunnel == NULL) { |
|---|
| 712 | | - struct l2tp_tunnel_cfg tcfg = { |
|---|
| 713 | | - .encap = L2TP_ENCAPTYPE_UDP, |
|---|
| 714 | | - .debug = 0, |
|---|
| 715 | | - }; |
|---|
| 716 | | - |
|---|
| 717 | | - /* Prevent l2tp_tunnel_register() from trying to set up |
|---|
| 718 | | - * a kernel socket. |
|---|
| 719 | | - */ |
|---|
| 720 | | - if (info.fd < 0) { |
|---|
| 721 | | - error = -EBADF; |
|---|
| 722 | | - goto end; |
|---|
| 723 | | - } |
|---|
| 724 | | - |
|---|
| 725 | | - error = l2tp_tunnel_create(sock_net(sk), info.fd, |
|---|
| 726 | | - info.version, |
|---|
| 727 | | - info.tunnel_id, |
|---|
| 728 | | - info.peer_tunnel_id, &tcfg, |
|---|
| 729 | | - &tunnel); |
|---|
| 730 | | - if (error < 0) |
|---|
| 731 | | - goto end; |
|---|
| 732 | | - |
|---|
| 733 | | - l2tp_tunnel_inc_refcount(tunnel); |
|---|
| 734 | | - error = l2tp_tunnel_register(tunnel, sock_net(sk), |
|---|
| 735 | | - &tcfg); |
|---|
| 736 | | - if (error < 0) { |
|---|
| 737 | | - kfree(tunnel); |
|---|
| 738 | | - goto end; |
|---|
| 739 | | - } |
|---|
| 740 | | - drop_tunnel = true; |
|---|
| 741 | | - new_tunnel = true; |
|---|
| 742 | | - } |
|---|
| 743 | | - } else { |
|---|
| 744 | | - /* Error if we can't find the tunnel */ |
|---|
| 745 | | - error = -ENOENT; |
|---|
| 746 | | - if (tunnel == NULL) |
|---|
| 747 | | - goto end; |
|---|
| 748 | | - |
|---|
| 749 | | - /* Error if socket is not prepped */ |
|---|
| 750 | | - if (tunnel->sock == NULL) |
|---|
| 751 | | - goto end; |
|---|
| 752 | | - } |
|---|
| 753 | 753 | |
|---|
| 754 | 754 | if (tunnel->peer_tunnel_id == 0) |
|---|
| 755 | 755 | tunnel->peer_tunnel_id = info.peer_tunnel_id; |
|---|
| .. | .. |
|---|
| 807 | 807 | * the internal context for use by ioctl() and sockopt() |
|---|
| 808 | 808 | * handlers. |
|---|
| 809 | 809 | */ |
|---|
| 810 | | - if ((session->session_id == 0) && |
|---|
| 811 | | - (session->peer_session_id == 0)) { |
|---|
| 810 | + if (session->session_id == 0 && session->peer_session_id == 0) { |
|---|
| 812 | 811 | error = 0; |
|---|
| 813 | 812 | goto out_no_ppp; |
|---|
| 814 | 813 | } |
|---|
| .. | .. |
|---|
| 842 | 841 | drop_refcnt = false; |
|---|
| 843 | 842 | |
|---|
| 844 | 843 | sk->sk_state = PPPOX_CONNECTED; |
|---|
| 845 | | - l2tp_info(session, L2TP_MSG_CONTROL, "%s: created\n", |
|---|
| 846 | | - session->name); |
|---|
| 847 | 844 | |
|---|
| 848 | 845 | end: |
|---|
| 849 | 846 | if (error) { |
|---|
| .. | .. |
|---|
| 854 | 851 | } |
|---|
| 855 | 852 | if (drop_refcnt) |
|---|
| 856 | 853 | l2tp_session_dec_refcount(session); |
|---|
| 857 | | - if (drop_tunnel) |
|---|
| 858 | | - l2tp_tunnel_dec_refcount(tunnel); |
|---|
| 854 | + l2tp_tunnel_dec_refcount(tunnel); |
|---|
| 859 | 855 | release_sock(sk); |
|---|
| 860 | 856 | |
|---|
| 861 | 857 | return error; |
|---|
| .. | .. |
|---|
| 916 | 912 | struct pppol2tp_session *pls; |
|---|
| 917 | 913 | |
|---|
| 918 | 914 | error = -ENOTCONN; |
|---|
| 919 | | - if (sk == NULL) |
|---|
| 915 | + if (!sk) |
|---|
| 920 | 916 | goto end; |
|---|
| 921 | 917 | if (!(sk->sk_state & PPPOX_CONNECTED)) |
|---|
| 922 | 918 | goto end; |
|---|
| 923 | 919 | |
|---|
| 924 | 920 | error = -EBADF; |
|---|
| 925 | 921 | session = pppol2tp_sock_to_session(sk); |
|---|
| 926 | | - if (session == NULL) |
|---|
| 922 | + if (!session) |
|---|
| 927 | 923 | goto end; |
|---|
| 928 | 924 | |
|---|
| 929 | 925 | pls = l2tp_session_priv(session); |
|---|
| 930 | 926 | tunnel = session->tunnel; |
|---|
| 931 | 927 | |
|---|
| 932 | 928 | inet = inet_sk(tunnel->sock); |
|---|
| 933 | | - if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) { |
|---|
| 929 | + if (tunnel->version == 2 && tunnel->sock->sk_family == AF_INET) { |
|---|
| 934 | 930 | struct sockaddr_pppol2tp sp; |
|---|
| 931 | + |
|---|
| 935 | 932 | len = sizeof(sp); |
|---|
| 936 | 933 | memset(&sp, 0, len); |
|---|
| 937 | 934 | sp.sa_family = AF_PPPOX; |
|---|
| .. | .. |
|---|
| 947 | 944 | sp.pppol2tp.addr.sin_addr.s_addr = inet->inet_daddr; |
|---|
| 948 | 945 | memcpy(uaddr, &sp, len); |
|---|
| 949 | 946 | #if IS_ENABLED(CONFIG_IPV6) |
|---|
| 950 | | - } else if ((tunnel->version == 2) && |
|---|
| 951 | | - (tunnel->sock->sk_family == AF_INET6)) { |
|---|
| 947 | + } else if (tunnel->version == 2 && tunnel->sock->sk_family == AF_INET6) { |
|---|
| 952 | 948 | struct sockaddr_pppol2tpin6 sp; |
|---|
| 953 | 949 | |
|---|
| 954 | 950 | len = sizeof(sp); |
|---|
| .. | .. |
|---|
| 966 | 962 | memcpy(&sp.pppol2tp.addr.sin6_addr, &tunnel->sock->sk_v6_daddr, |
|---|
| 967 | 963 | sizeof(tunnel->sock->sk_v6_daddr)); |
|---|
| 968 | 964 | memcpy(uaddr, &sp, len); |
|---|
| 969 | | - } else if ((tunnel->version == 3) && |
|---|
| 970 | | - (tunnel->sock->sk_family == AF_INET6)) { |
|---|
| 965 | + } else if (tunnel->version == 3 && tunnel->sock->sk_family == AF_INET6) { |
|---|
| 971 | 966 | struct sockaddr_pppol2tpv3in6 sp; |
|---|
| 972 | 967 | |
|---|
| 973 | 968 | len = sizeof(sp); |
|---|
| .. | .. |
|---|
| 988 | 983 | #endif |
|---|
| 989 | 984 | } else if (tunnel->version == 3) { |
|---|
| 990 | 985 | struct sockaddr_pppol2tpv3 sp; |
|---|
| 986 | + |
|---|
| 991 | 987 | len = sizeof(sp); |
|---|
| 992 | 988 | memset(&sp, 0, len); |
|---|
| 993 | 989 | sp.sa_family = AF_PPPOX; |
|---|
| .. | .. |
|---|
| 1070 | 1066 | { |
|---|
| 1071 | 1067 | struct pppol2tp_ioc_stats stats; |
|---|
| 1072 | 1068 | struct l2tp_session *session; |
|---|
| 1073 | | - int val; |
|---|
| 1074 | 1069 | |
|---|
| 1075 | 1070 | switch (cmd) { |
|---|
| 1076 | 1071 | case PPPIOCGMRU: |
|---|
| .. | .. |
|---|
| 1078 | 1073 | session = sock->sk->sk_user_data; |
|---|
| 1079 | 1074 | if (!session) |
|---|
| 1080 | 1075 | return -ENOTCONN; |
|---|
| 1076 | + |
|---|
| 1077 | + if (WARN_ON(session->magic != L2TP_SESSION_MAGIC)) |
|---|
| 1078 | + return -EBADF; |
|---|
| 1081 | 1079 | |
|---|
| 1082 | 1080 | /* Not defined for tunnels */ |
|---|
| 1083 | 1081 | if (!session->session_id && !session->peer_session_id) |
|---|
| .. | .. |
|---|
| 1093 | 1091 | if (!session) |
|---|
| 1094 | 1092 | return -ENOTCONN; |
|---|
| 1095 | 1093 | |
|---|
| 1094 | + if (WARN_ON(session->magic != L2TP_SESSION_MAGIC)) |
|---|
| 1095 | + return -EBADF; |
|---|
| 1096 | + |
|---|
| 1096 | 1097 | /* Not defined for tunnels */ |
|---|
| 1097 | 1098 | if (!session->session_id && !session->peer_session_id) |
|---|
| 1098 | 1099 | return -ENOSYS; |
|---|
| 1099 | 1100 | |
|---|
| 1100 | | - if (get_user(val, (int __user *)arg)) |
|---|
| 1101 | + if (!access_ok((int __user *)arg, sizeof(int))) |
|---|
| 1101 | 1102 | return -EFAULT; |
|---|
| 1102 | 1103 | break; |
|---|
| 1103 | 1104 | |
|---|
| .. | .. |
|---|
| 1105 | 1106 | session = sock->sk->sk_user_data; |
|---|
| 1106 | 1107 | if (!session) |
|---|
| 1107 | 1108 | return -ENOTCONN; |
|---|
| 1109 | + |
|---|
| 1110 | + if (WARN_ON(session->magic != L2TP_SESSION_MAGIC)) |
|---|
| 1111 | + return -EBADF; |
|---|
| 1108 | 1112 | |
|---|
| 1109 | 1113 | /* Session 0 represents the parent tunnel */ |
|---|
| 1110 | 1114 | if (!session->session_id && !session->peer_session_id) { |
|---|
| .. | .. |
|---|
| 1160 | 1164 | |
|---|
| 1161 | 1165 | switch (optname) { |
|---|
| 1162 | 1166 | case PPPOL2TP_SO_DEBUG: |
|---|
| 1163 | | - tunnel->debug = val; |
|---|
| 1164 | | - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: set debug=%x\n", |
|---|
| 1165 | | - tunnel->name, tunnel->debug); |
|---|
| 1167 | + /* Tunnel debug flags option is deprecated */ |
|---|
| 1166 | 1168 | break; |
|---|
| 1167 | 1169 | |
|---|
| 1168 | 1170 | default: |
|---|
| .. | .. |
|---|
| 1183 | 1185 | |
|---|
| 1184 | 1186 | switch (optname) { |
|---|
| 1185 | 1187 | case PPPOL2TP_SO_RECVSEQ: |
|---|
| 1186 | | - if ((val != 0) && (val != 1)) { |
|---|
| 1188 | + if (val != 0 && val != 1) { |
|---|
| 1187 | 1189 | err = -EINVAL; |
|---|
| 1188 | 1190 | break; |
|---|
| 1189 | 1191 | } |
|---|
| 1190 | 1192 | session->recv_seq = !!val; |
|---|
| 1191 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1192 | | - "%s: set recv_seq=%d\n", |
|---|
| 1193 | | - session->name, session->recv_seq); |
|---|
| 1194 | 1193 | break; |
|---|
| 1195 | 1194 | |
|---|
| 1196 | 1195 | case PPPOL2TP_SO_SENDSEQ: |
|---|
| 1197 | | - if ((val != 0) && (val != 1)) { |
|---|
| 1196 | + if (val != 0 && val != 1) { |
|---|
| 1198 | 1197 | err = -EINVAL; |
|---|
| 1199 | 1198 | break; |
|---|
| 1200 | 1199 | } |
|---|
| .. | .. |
|---|
| 1206 | 1205 | PPPOL2TP_L2TP_HDR_SIZE_NOSEQ; |
|---|
| 1207 | 1206 | } |
|---|
| 1208 | 1207 | l2tp_session_set_header_len(session, session->tunnel->version); |
|---|
| 1209 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1210 | | - "%s: set send_seq=%d\n", |
|---|
| 1211 | | - session->name, session->send_seq); |
|---|
| 1212 | 1208 | break; |
|---|
| 1213 | 1209 | |
|---|
| 1214 | 1210 | case PPPOL2TP_SO_LNSMODE: |
|---|
| 1215 | | - if ((val != 0) && (val != 1)) { |
|---|
| 1211 | + if (val != 0 && val != 1) { |
|---|
| 1216 | 1212 | err = -EINVAL; |
|---|
| 1217 | 1213 | break; |
|---|
| 1218 | 1214 | } |
|---|
| 1219 | 1215 | session->lns_mode = !!val; |
|---|
| 1220 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1221 | | - "%s: set lns_mode=%d\n", |
|---|
| 1222 | | - session->name, session->lns_mode); |
|---|
| 1223 | 1216 | break; |
|---|
| 1224 | 1217 | |
|---|
| 1225 | 1218 | case PPPOL2TP_SO_DEBUG: |
|---|
| 1226 | | - session->debug = val; |
|---|
| 1227 | | - l2tp_info(session, L2TP_MSG_CONTROL, "%s: set debug=%x\n", |
|---|
| 1228 | | - session->name, session->debug); |
|---|
| 1219 | + /* Session debug flags option is deprecated */ |
|---|
| 1229 | 1220 | break; |
|---|
| 1230 | 1221 | |
|---|
| 1231 | 1222 | case PPPOL2TP_SO_REORDERTO: |
|---|
| 1232 | 1223 | session->reorder_timeout = msecs_to_jiffies(val); |
|---|
| 1233 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1234 | | - "%s: set reorder_timeout=%d\n", |
|---|
| 1235 | | - session->name, session->reorder_timeout); |
|---|
| 1236 | 1224 | break; |
|---|
| 1237 | 1225 | |
|---|
| 1238 | 1226 | default: |
|---|
| .. | .. |
|---|
| 1249 | 1237 | * session or the special tunnel type. |
|---|
| 1250 | 1238 | */ |
|---|
| 1251 | 1239 | static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, |
|---|
| 1252 | | - char __user *optval, unsigned int optlen) |
|---|
| 1240 | + sockptr_t optval, unsigned int optlen) |
|---|
| 1253 | 1241 | { |
|---|
| 1254 | 1242 | struct sock *sk = sock->sk; |
|---|
| 1255 | 1243 | struct l2tp_session *session; |
|---|
| .. | .. |
|---|
| 1263 | 1251 | if (optlen < sizeof(int)) |
|---|
| 1264 | 1252 | return -EINVAL; |
|---|
| 1265 | 1253 | |
|---|
| 1266 | | - if (get_user(val, (int __user *)optval)) |
|---|
| 1254 | + if (copy_from_sockptr(&val, optval, sizeof(int))) |
|---|
| 1267 | 1255 | return -EFAULT; |
|---|
| 1268 | 1256 | |
|---|
| 1269 | 1257 | err = -ENOTCONN; |
|---|
| 1270 | | - if (sk->sk_user_data == NULL) |
|---|
| 1258 | + if (!sk->sk_user_data) |
|---|
| 1271 | 1259 | goto end; |
|---|
| 1272 | 1260 | |
|---|
| 1273 | 1261 | /* Get session context from the socket */ |
|---|
| 1274 | 1262 | err = -EBADF; |
|---|
| 1275 | 1263 | session = pppol2tp_sock_to_session(sk); |
|---|
| 1276 | | - if (session == NULL) |
|---|
| 1264 | + if (!session) |
|---|
| 1277 | 1265 | goto end; |
|---|
| 1278 | 1266 | |
|---|
| 1279 | 1267 | /* Special case: if session_id == 0x0000, treat as operation on tunnel |
|---|
| 1280 | 1268 | */ |
|---|
| 1281 | | - if ((session->session_id == 0) && |
|---|
| 1282 | | - (session->peer_session_id == 0)) { |
|---|
| 1269 | + if (session->session_id == 0 && session->peer_session_id == 0) { |
|---|
| 1283 | 1270 | tunnel = session->tunnel; |
|---|
| 1284 | 1271 | err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); |
|---|
| 1285 | 1272 | } else { |
|---|
| .. | .. |
|---|
| 1301 | 1288 | |
|---|
| 1302 | 1289 | switch (optname) { |
|---|
| 1303 | 1290 | case PPPOL2TP_SO_DEBUG: |
|---|
| 1304 | | - *val = tunnel->debug; |
|---|
| 1305 | | - l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: get debug=%x\n", |
|---|
| 1306 | | - tunnel->name, tunnel->debug); |
|---|
| 1291 | + /* Tunnel debug flags option is deprecated */ |
|---|
| 1292 | + *val = 0; |
|---|
| 1307 | 1293 | break; |
|---|
| 1308 | 1294 | |
|---|
| 1309 | 1295 | default: |
|---|
| .. | .. |
|---|
| 1325 | 1311 | switch (optname) { |
|---|
| 1326 | 1312 | case PPPOL2TP_SO_RECVSEQ: |
|---|
| 1327 | 1313 | *val = session->recv_seq; |
|---|
| 1328 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1329 | | - "%s: get recv_seq=%d\n", session->name, *val); |
|---|
| 1330 | 1314 | break; |
|---|
| 1331 | 1315 | |
|---|
| 1332 | 1316 | case PPPOL2TP_SO_SENDSEQ: |
|---|
| 1333 | 1317 | *val = session->send_seq; |
|---|
| 1334 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1335 | | - "%s: get send_seq=%d\n", session->name, *val); |
|---|
| 1336 | 1318 | break; |
|---|
| 1337 | 1319 | |
|---|
| 1338 | 1320 | case PPPOL2TP_SO_LNSMODE: |
|---|
| 1339 | 1321 | *val = session->lns_mode; |
|---|
| 1340 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1341 | | - "%s: get lns_mode=%d\n", session->name, *val); |
|---|
| 1342 | 1322 | break; |
|---|
| 1343 | 1323 | |
|---|
| 1344 | 1324 | case PPPOL2TP_SO_DEBUG: |
|---|
| 1345 | | - *val = session->debug; |
|---|
| 1346 | | - l2tp_info(session, L2TP_MSG_CONTROL, "%s: get debug=%d\n", |
|---|
| 1347 | | - session->name, *val); |
|---|
| 1325 | + /* Session debug flags option is deprecated */ |
|---|
| 1326 | + *val = 0; |
|---|
| 1348 | 1327 | break; |
|---|
| 1349 | 1328 | |
|---|
| 1350 | 1329 | case PPPOL2TP_SO_REORDERTO: |
|---|
| 1351 | | - *val = (int) jiffies_to_msecs(session->reorder_timeout); |
|---|
| 1352 | | - l2tp_info(session, L2TP_MSG_CONTROL, |
|---|
| 1353 | | - "%s: get reorder_timeout=%d\n", session->name, *val); |
|---|
| 1330 | + *val = (int)jiffies_to_msecs(session->reorder_timeout); |
|---|
| 1354 | 1331 | break; |
|---|
| 1355 | 1332 | |
|---|
| 1356 | 1333 | default: |
|---|
| .. | .. |
|---|
| 1386 | 1363 | return -EINVAL; |
|---|
| 1387 | 1364 | |
|---|
| 1388 | 1365 | err = -ENOTCONN; |
|---|
| 1389 | | - if (sk->sk_user_data == NULL) |
|---|
| 1366 | + if (!sk->sk_user_data) |
|---|
| 1390 | 1367 | goto end; |
|---|
| 1391 | 1368 | |
|---|
| 1392 | 1369 | /* Get the session context */ |
|---|
| 1393 | 1370 | err = -EBADF; |
|---|
| 1394 | 1371 | session = pppol2tp_sock_to_session(sk); |
|---|
| 1395 | | - if (session == NULL) |
|---|
| 1372 | + if (!session) |
|---|
| 1396 | 1373 | goto end; |
|---|
| 1397 | 1374 | |
|---|
| 1398 | 1375 | /* Special case: if session_id == 0x0000, treat as operation on tunnel */ |
|---|
| 1399 | | - if ((session->session_id == 0) && |
|---|
| 1400 | | - (session->peer_session_id == 0)) { |
|---|
| 1376 | + if (session->session_id == 0 && session->peer_session_id == 0) { |
|---|
| 1401 | 1377 | tunnel = session->tunnel; |
|---|
| 1402 | 1378 | err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); |
|---|
| 1403 | 1379 | if (err) |
|---|
| .. | .. |
|---|
| 1412 | 1388 | if (put_user(len, optlen)) |
|---|
| 1413 | 1389 | goto end_put_sess; |
|---|
| 1414 | 1390 | |
|---|
| 1415 | | - if (copy_to_user((void __user *) optval, &val, len)) |
|---|
| 1391 | + if (copy_to_user((void __user *)optval, &val, len)) |
|---|
| 1416 | 1392 | goto end_put_sess; |
|---|
| 1417 | 1393 | |
|---|
| 1418 | 1394 | err = 0; |
|---|
| .. | .. |
|---|
| 1468 | 1444 | pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx); |
|---|
| 1469 | 1445 | pd->session_idx++; |
|---|
| 1470 | 1446 | |
|---|
| 1471 | | - if (pd->session == NULL) { |
|---|
| 1447 | + if (!pd->session) { |
|---|
| 1472 | 1448 | pd->session_idx = 0; |
|---|
| 1473 | 1449 | pppol2tp_next_tunnel(net, pd); |
|---|
| 1474 | 1450 | } |
|---|
| .. | .. |
|---|
| 1483 | 1459 | if (!pos) |
|---|
| 1484 | 1460 | goto out; |
|---|
| 1485 | 1461 | |
|---|
| 1486 | | - BUG_ON(m->private == NULL); |
|---|
| 1462 | + if (WARN_ON(!m->private)) { |
|---|
| 1463 | + pd = NULL; |
|---|
| 1464 | + goto out; |
|---|
| 1465 | + } |
|---|
| 1466 | + |
|---|
| 1487 | 1467 | pd = m->private; |
|---|
| 1488 | 1468 | net = seq_file_net(m); |
|---|
| 1489 | 1469 | |
|---|
| 1490 | | - if (pd->tunnel == NULL) |
|---|
| 1470 | + if (!pd->tunnel) |
|---|
| 1491 | 1471 | pppol2tp_next_tunnel(net, pd); |
|---|
| 1492 | 1472 | else |
|---|
| 1493 | 1473 | pppol2tp_next_session(net, pd); |
|---|
| 1494 | 1474 | |
|---|
| 1495 | 1475 | /* NULL tunnel and session indicates end of list */ |
|---|
| 1496 | | - if ((pd->tunnel == NULL) && (pd->session == NULL)) |
|---|
| 1476 | + if (!pd->tunnel && !pd->session) |
|---|
| 1497 | 1477 | pd = NULL; |
|---|
| 1498 | 1478 | |
|---|
| 1499 | 1479 | out: |
|---|
| .. | .. |
|---|
| 1535 | 1515 | (tunnel == tunnel->sock->sk_user_data) ? 'Y' : 'N', |
|---|
| 1536 | 1516 | refcount_read(&tunnel->ref_count) - 1); |
|---|
| 1537 | 1517 | seq_printf(m, " %08x %ld/%ld/%ld %ld/%ld/%ld\n", |
|---|
| 1538 | | - tunnel->debug, |
|---|
| 1518 | + 0, |
|---|
| 1539 | 1519 | atomic_long_read(&tunnel->stats.tx_packets), |
|---|
| 1540 | 1520 | atomic_long_read(&tunnel->stats.tx_bytes), |
|---|
| 1541 | 1521 | atomic_long_read(&tunnel->stats.tx_errors), |
|---|
| .. | .. |
|---|
| 1556 | 1536 | |
|---|
| 1557 | 1537 | if (tunnel->sock) { |
|---|
| 1558 | 1538 | struct inet_sock *inet = inet_sk(tunnel->sock); |
|---|
| 1539 | + |
|---|
| 1559 | 1540 | ip = ntohl(inet->inet_saddr); |
|---|
| 1560 | 1541 | port = ntohs(inet->inet_sport); |
|---|
| 1561 | 1542 | } |
|---|
| .. | .. |
|---|
| 1569 | 1550 | user_data_ok = 'N'; |
|---|
| 1570 | 1551 | } |
|---|
| 1571 | 1552 | |
|---|
| 1572 | | - seq_printf(m, " SESSION '%s' %08X/%d %04X/%04X -> " |
|---|
| 1573 | | - "%04X/%04X %d %c\n", |
|---|
| 1553 | + seq_printf(m, " SESSION '%s' %08X/%d %04X/%04X -> %04X/%04X %d %c\n", |
|---|
| 1574 | 1554 | session->name, ip, port, |
|---|
| 1575 | 1555 | tunnel->tunnel_id, |
|---|
| 1576 | 1556 | session->session_id, |
|---|
| .. | .. |
|---|
| 1581 | 1561 | session->recv_seq ? 'R' : '-', |
|---|
| 1582 | 1562 | session->send_seq ? 'S' : '-', |
|---|
| 1583 | 1563 | session->lns_mode ? "LNS" : "LAC", |
|---|
| 1584 | | - session->debug, |
|---|
| 1564 | + 0, |
|---|
| 1585 | 1565 | jiffies_to_msecs(session->reorder_timeout)); |
|---|
| 1586 | 1566 | seq_printf(m, " %hu/%hu %ld/%ld/%ld %ld/%ld/%ld\n", |
|---|
| 1587 | 1567 | session->nr, session->ns, |
|---|
| .. | .. |
|---|
| 1609 | 1589 | seq_puts(m, "PPPoL2TP driver info, " PPPOL2TP_DRV_VERSION "\n"); |
|---|
| 1610 | 1590 | seq_puts(m, "TUNNEL name, user-data-ok session-count\n"); |
|---|
| 1611 | 1591 | seq_puts(m, " debug tx-pkts/bytes/errs rx-pkts/bytes/errs\n"); |
|---|
| 1612 | | - seq_puts(m, " SESSION name, addr/port src-tid/sid " |
|---|
| 1613 | | - "dest-tid/sid state user-data-ok\n"); |
|---|
| 1592 | + seq_puts(m, " SESSION name, addr/port src-tid/sid dest-tid/sid state user-data-ok\n"); |
|---|
| 1614 | 1593 | seq_puts(m, " mtu/mru/rcvseq/sendseq/lns debug reorderto\n"); |
|---|
| 1615 | 1594 | seq_puts(m, " nr/ns tx-pkts/bytes/errs rx-pkts/bytes/errs\n"); |
|---|
| 1616 | 1595 | goto out; |
|---|
| .. | .. |
|---|
| 1643 | 1622 | int err = 0; |
|---|
| 1644 | 1623 | |
|---|
| 1645 | 1624 | pde = proc_create_net("pppol2tp", 0444, net->proc_net, |
|---|
| 1646 | | - &pppol2tp_seq_ops, sizeof(struct pppol2tp_seq_data)); |
|---|
| 1625 | + &pppol2tp_seq_ops, sizeof(struct pppol2tp_seq_data)); |
|---|
| 1647 | 1626 | if (!pde) { |
|---|
| 1648 | 1627 | err = -ENOMEM; |
|---|
| 1649 | 1628 | goto out; |
|---|