| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * L2TPv3 IP encapsulation support |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 2 | +/* L2TPv3 IP encapsulation support |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Copyright (c) 2008,2009,2010 Katalix Systems Ltd |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 5 | */ |
|---|
| 11 | 6 | |
|---|
| 12 | 7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 123 | 118 | struct l2tp_session *session; |
|---|
| 124 | 119 | struct l2tp_tunnel *tunnel = NULL; |
|---|
| 125 | 120 | struct iphdr *iph; |
|---|
| 126 | | - int length; |
|---|
| 127 | 121 | |
|---|
| 128 | 122 | if (!pskb_may_pull(skb, 4)) |
|---|
| 129 | 123 | goto discard; |
|---|
| 130 | 124 | |
|---|
| 131 | 125 | /* Point to L2TP header */ |
|---|
| 132 | | - optr = ptr = skb->data; |
|---|
| 133 | | - session_id = ntohl(*((__be32 *) ptr)); |
|---|
| 126 | + optr = skb->data; |
|---|
| 127 | + ptr = skb->data; |
|---|
| 128 | + session_id = ntohl(*((__be32 *)ptr)); |
|---|
| 134 | 129 | ptr += 4; |
|---|
| 135 | 130 | |
|---|
| 136 | 131 | /* RFC3931: L2TP/IP packets have the first 4 bytes containing |
|---|
| .. | .. |
|---|
| 151 | 146 | if (!tunnel) |
|---|
| 152 | 147 | goto discard_sess; |
|---|
| 153 | 148 | |
|---|
| 154 | | - /* Trace packet contents, if enabled */ |
|---|
| 155 | | - if (tunnel->debug & L2TP_MSG_DATA) { |
|---|
| 156 | | - length = min(32u, skb->len); |
|---|
| 157 | | - if (!pskb_may_pull(skb, length)) |
|---|
| 158 | | - goto discard_sess; |
|---|
| 159 | | - |
|---|
| 160 | | - /* Point to L2TP header */ |
|---|
| 161 | | - optr = ptr = skb->data; |
|---|
| 162 | | - ptr += 4; |
|---|
| 163 | | - pr_debug("%s: ip recv\n", tunnel->name); |
|---|
| 164 | | - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
|---|
| 165 | | - } |
|---|
| 166 | | - |
|---|
| 167 | 149 | if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) |
|---|
| 168 | 150 | goto discard_sess; |
|---|
| 169 | 151 | |
|---|
| .. | .. |
|---|
| 180 | 162 | if ((skb->data[0] & 0xc0) != 0xc0) |
|---|
| 181 | 163 | goto discard; |
|---|
| 182 | 164 | |
|---|
| 183 | | - tunnel_id = ntohl(*(__be32 *) &skb->data[4]); |
|---|
| 165 | + tunnel_id = ntohl(*(__be32 *)&skb->data[4]); |
|---|
| 184 | 166 | iph = (struct iphdr *)skb_network_header(skb); |
|---|
| 185 | 167 | |
|---|
| 186 | 168 | read_lock_bh(&l2tp_ip_lock); |
|---|
| .. | .. |
|---|
| 196 | 178 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) |
|---|
| 197 | 179 | goto discard_put; |
|---|
| 198 | 180 | |
|---|
| 199 | | - nf_reset(skb); |
|---|
| 181 | + nf_reset_ct(skb); |
|---|
| 200 | 182 | |
|---|
| 201 | 183 | return sk_receive_skb(sk, skb, 1); |
|---|
| 202 | 184 | |
|---|
| .. | .. |
|---|
| 251 | 233 | |
|---|
| 252 | 234 | static void l2tp_ip_destroy_sock(struct sock *sk) |
|---|
| 253 | 235 | { |
|---|
| 236 | + struct l2tp_tunnel *tunnel = l2tp_sk_to_tunnel(sk); |
|---|
| 254 | 237 | struct sk_buff *skb; |
|---|
| 255 | | - struct l2tp_tunnel *tunnel = sk->sk_user_data; |
|---|
| 256 | 238 | |
|---|
| 257 | 239 | while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) |
|---|
| 258 | 240 | kfree_skb(skb); |
|---|
| .. | .. |
|---|
| 264 | 246 | static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
|---|
| 265 | 247 | { |
|---|
| 266 | 248 | struct inet_sock *inet = inet_sk(sk); |
|---|
| 267 | | - struct sockaddr_l2tpip *addr = (struct sockaddr_l2tpip *) uaddr; |
|---|
| 249 | + struct sockaddr_l2tpip *addr = (struct sockaddr_l2tpip *)uaddr; |
|---|
| 268 | 250 | struct net *net = sock_net(sk); |
|---|
| 269 | 251 | int ret; |
|---|
| 270 | 252 | int chk_addr_ret; |
|---|
| .. | .. |
|---|
| 289 | 271 | chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) |
|---|
| 290 | 272 | goto out; |
|---|
| 291 | 273 | |
|---|
| 292 | | - if (addr->l2tp_addr.s_addr) |
|---|
| 293 | | - inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; |
|---|
| 274 | + if (addr->l2tp_addr.s_addr) { |
|---|
| 275 | + inet->inet_rcv_saddr = addr->l2tp_addr.s_addr; |
|---|
| 276 | + inet->inet_saddr = addr->l2tp_addr.s_addr; |
|---|
| 277 | + } |
|---|
| 294 | 278 | if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) |
|---|
| 295 | 279 | inet->inet_saddr = 0; /* Use device */ |
|---|
| 296 | 280 | |
|---|
| .. | .. |
|---|
| 320 | 304 | |
|---|
| 321 | 305 | static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
|---|
| 322 | 306 | { |
|---|
| 323 | | - struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr; |
|---|
| 307 | + struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *)uaddr; |
|---|
| 324 | 308 | int rc; |
|---|
| 325 | 309 | |
|---|
| 326 | 310 | if (addr_len < sizeof(*lsa)) |
|---|
| .. | .. |
|---|
| 379 | 363 | lsa->l2tp_addr.s_addr = inet->inet_daddr; |
|---|
| 380 | 364 | } else { |
|---|
| 381 | 365 | __be32 addr = inet->inet_rcv_saddr; |
|---|
| 366 | + |
|---|
| 382 | 367 | if (!addr) |
|---|
| 383 | 368 | addr = inet->inet_saddr; |
|---|
| 384 | 369 | lsa->l2tp_conn_id = lsk->conn_id; |
|---|
| .. | .. |
|---|
| 426 | 411 | /* Get and verify the address. */ |
|---|
| 427 | 412 | if (msg->msg_name) { |
|---|
| 428 | 413 | DECLARE_SOCKADDR(struct sockaddr_l2tpip *, lip, msg->msg_name); |
|---|
| 414 | + |
|---|
| 429 | 415 | rc = -EINVAL; |
|---|
| 430 | 416 | if (msg->msg_namelen < sizeof(*lip)) |
|---|
| 431 | 417 | goto out; |
|---|
| .. | .. |
|---|
| 460 | 446 | skb_reset_transport_header(skb); |
|---|
| 461 | 447 | |
|---|
| 462 | 448 | /* Insert 0 session_id */ |
|---|
| 463 | | - *((__be32 *) skb_put(skb, 4)) = 0; |
|---|
| 449 | + *((__be32 *)skb_put(skb, 4)) = 0; |
|---|
| 464 | 450 | |
|---|
| 465 | 451 | /* Copy user data into skb */ |
|---|
| 466 | 452 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
|---|
| .. | .. |
|---|
| 471 | 457 | |
|---|
| 472 | 458 | fl4 = &inet->cork.fl.u.ip4; |
|---|
| 473 | 459 | if (connected) |
|---|
| 474 | | - rt = (struct rtable *) __sk_dst_check(sk, 0); |
|---|
| 460 | + rt = (struct rtable *)__sk_dst_check(sk, 0); |
|---|
| 475 | 461 | |
|---|
| 476 | 462 | rcu_read_lock(); |
|---|
| 477 | | - if (rt == NULL) { |
|---|
| 463 | + if (!rt) { |
|---|
| 478 | 464 | const struct ip_options_rcu *inet_opt; |
|---|
| 479 | 465 | |
|---|
| 480 | 466 | inet_opt = rcu_dereference(inet->inet_opt); |
|---|
| .. | .. |
|---|
| 596 | 582 | |
|---|
| 597 | 583 | return put_user(amount, (int __user *)arg); |
|---|
| 598 | 584 | } |
|---|
| 599 | | -EXPORT_SYMBOL(l2tp_ioctl); |
|---|
| 585 | +EXPORT_SYMBOL_GPL(l2tp_ioctl); |
|---|
| 600 | 586 | |
|---|
| 601 | 587 | static struct proto l2tp_ip_prot = { |
|---|
| 602 | 588 | .name = "L2TP/IP", |
|---|
| .. | .. |
|---|
| 616 | 602 | .hash = l2tp_ip_hash, |
|---|
| 617 | 603 | .unhash = l2tp_ip_unhash, |
|---|
| 618 | 604 | .obj_size = sizeof(struct l2tp_ip_sock), |
|---|
| 619 | | -#ifdef CONFIG_COMPAT |
|---|
| 620 | | - .compat_setsockopt = compat_ip_setsockopt, |
|---|
| 621 | | - .compat_getsockopt = compat_ip_getsockopt, |
|---|
| 622 | | -#endif |
|---|
| 623 | 605 | }; |
|---|
| 624 | 606 | |
|---|
| 625 | 607 | static const struct proto_ops l2tp_ip_ops = { |
|---|
| .. | .. |
|---|
| 633 | 615 | .getname = l2tp_ip_getname, |
|---|
| 634 | 616 | .poll = datagram_poll, |
|---|
| 635 | 617 | .ioctl = inet_ioctl, |
|---|
| 618 | + .gettstamp = sock_gettstamp, |
|---|
| 636 | 619 | .listen = sock_no_listen, |
|---|
| 637 | 620 | .shutdown = inet_shutdown, |
|---|
| 638 | 621 | .setsockopt = sock_common_setsockopt, |
|---|
| .. | .. |
|---|
| 641 | 624 | .recvmsg = sock_common_recvmsg, |
|---|
| 642 | 625 | .mmap = sock_no_mmap, |
|---|
| 643 | 626 | .sendpage = sock_no_sendpage, |
|---|
| 644 | | -#ifdef CONFIG_COMPAT |
|---|
| 645 | | - .compat_setsockopt = compat_sock_common_setsockopt, |
|---|
| 646 | | - .compat_getsockopt = compat_sock_common_getsockopt, |
|---|
| 647 | | -#endif |
|---|
| 648 | 627 | }; |
|---|
| 649 | 628 | |
|---|
| 650 | 629 | static struct inet_protosw l2tp_ip_protosw = { |
|---|