| .. | .. |
|---|
| 1 | | -/* |
|---|
| 2 | | - * L2TPv3 IP encapsulation support for IPv6 |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 2 | +/* L2TPv3 IP encapsulation support for IPv6 |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Copyright (c) 2012 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 |
|---|
| .. | .. |
|---|
| 42 | 37 | u32 peer_conn_id; |
|---|
| 43 | 38 | |
|---|
| 44 | 39 | /* ipv6_pinfo has to be the last member of l2tp_ip6_sock, see |
|---|
| 45 | | - inet6_sk_generic */ |
|---|
| 40 | + * inet6_sk_generic |
|---|
| 41 | + */ |
|---|
| 46 | 42 | struct ipv6_pinfo inet6; |
|---|
| 47 | 43 | }; |
|---|
| 48 | 44 | |
|---|
| .. | .. |
|---|
| 135 | 131 | struct l2tp_session *session; |
|---|
| 136 | 132 | struct l2tp_tunnel *tunnel = NULL; |
|---|
| 137 | 133 | struct ipv6hdr *iph; |
|---|
| 138 | | - int length; |
|---|
| 139 | 134 | |
|---|
| 140 | 135 | if (!pskb_may_pull(skb, 4)) |
|---|
| 141 | 136 | goto discard; |
|---|
| 142 | 137 | |
|---|
| 143 | 138 | /* Point to L2TP header */ |
|---|
| 144 | | - optr = ptr = skb->data; |
|---|
| 145 | | - session_id = ntohl(*((__be32 *) ptr)); |
|---|
| 139 | + optr = skb->data; |
|---|
| 140 | + ptr = skb->data; |
|---|
| 141 | + session_id = ntohl(*((__be32 *)ptr)); |
|---|
| 146 | 142 | ptr += 4; |
|---|
| 147 | 143 | |
|---|
| 148 | 144 | /* RFC3931: L2TP/IP packets have the first 4 bytes containing |
|---|
| .. | .. |
|---|
| 163 | 159 | if (!tunnel) |
|---|
| 164 | 160 | goto discard_sess; |
|---|
| 165 | 161 | |
|---|
| 166 | | - /* Trace packet contents, if enabled */ |
|---|
| 167 | | - if (tunnel->debug & L2TP_MSG_DATA) { |
|---|
| 168 | | - length = min(32u, skb->len); |
|---|
| 169 | | - if (!pskb_may_pull(skb, length)) |
|---|
| 170 | | - goto discard_sess; |
|---|
| 171 | | - |
|---|
| 172 | | - /* Point to L2TP header */ |
|---|
| 173 | | - optr = ptr = skb->data; |
|---|
| 174 | | - ptr += 4; |
|---|
| 175 | | - pr_debug("%s: ip recv\n", tunnel->name); |
|---|
| 176 | | - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
|---|
| 177 | | - } |
|---|
| 178 | | - |
|---|
| 179 | 162 | if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) |
|---|
| 180 | 163 | goto discard_sess; |
|---|
| 181 | 164 | |
|---|
| .. | .. |
|---|
| 192 | 175 | if ((skb->data[0] & 0xc0) != 0xc0) |
|---|
| 193 | 176 | goto discard; |
|---|
| 194 | 177 | |
|---|
| 195 | | - tunnel_id = ntohl(*(__be32 *) &skb->data[4]); |
|---|
| 178 | + tunnel_id = ntohl(*(__be32 *)&skb->data[4]); |
|---|
| 196 | 179 | iph = ipv6_hdr(skb); |
|---|
| 197 | 180 | |
|---|
| 198 | 181 | read_lock_bh(&l2tp_ip6_lock); |
|---|
| .. | .. |
|---|
| 208 | 191 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
|---|
| 209 | 192 | goto discard_put; |
|---|
| 210 | 193 | |
|---|
| 211 | | - nf_reset(skb); |
|---|
| 194 | + nf_reset_ct(skb); |
|---|
| 212 | 195 | |
|---|
| 213 | 196 | return sk_receive_skb(sk, skb, 1); |
|---|
| 214 | 197 | |
|---|
| .. | .. |
|---|
| 264 | 247 | |
|---|
| 265 | 248 | static void l2tp_ip6_destroy_sock(struct sock *sk) |
|---|
| 266 | 249 | { |
|---|
| 267 | | - struct l2tp_tunnel *tunnel = sk->sk_user_data; |
|---|
| 250 | + struct l2tp_tunnel *tunnel = l2tp_sk_to_tunnel(sk); |
|---|
| 268 | 251 | |
|---|
| 269 | 252 | lock_sock(sk); |
|---|
| 270 | 253 | ip6_flush_pending_frames(sk); |
|---|
| .. | .. |
|---|
| 280 | 263 | { |
|---|
| 281 | 264 | struct inet_sock *inet = inet_sk(sk); |
|---|
| 282 | 265 | struct ipv6_pinfo *np = inet6_sk(sk); |
|---|
| 283 | | - struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; |
|---|
| 266 | + struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *)uaddr; |
|---|
| 284 | 267 | struct net *net = sock_net(sk); |
|---|
| 285 | 268 | __be32 v4addr = 0; |
|---|
| 286 | 269 | int bound_dev_if; |
|---|
| .. | .. |
|---|
| 379 | 362 | static int l2tp_ip6_connect(struct sock *sk, struct sockaddr *uaddr, |
|---|
| 380 | 363 | int addr_len) |
|---|
| 381 | 364 | { |
|---|
| 382 | | - struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *) uaddr; |
|---|
| 383 | | - struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
|---|
| 365 | + struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)uaddr; |
|---|
| 366 | + struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr; |
|---|
| 384 | 367 | struct in6_addr *daddr; |
|---|
| 385 | 368 | int addr_type; |
|---|
| 386 | 369 | int rc; |
|---|
| .. | .. |
|---|
| 490 | 473 | int err = 0; |
|---|
| 491 | 474 | |
|---|
| 492 | 475 | skb = skb_peek(&sk->sk_write_queue); |
|---|
| 493 | | - if (skb == NULL) |
|---|
| 476 | + if (!skb) |
|---|
| 494 | 477 | goto out; |
|---|
| 495 | 478 | |
|---|
| 496 | 479 | transhdr = (__be32 *)skb_transport_header(skb); |
|---|
| .. | .. |
|---|
| 519 | 502 | struct ipcm6_cookie ipc6; |
|---|
| 520 | 503 | int addr_len = msg->msg_namelen; |
|---|
| 521 | 504 | int transhdrlen = 4; /* zero session-id */ |
|---|
| 522 | | - int ulen = len + transhdrlen; |
|---|
| 505 | + int ulen; |
|---|
| 523 | 506 | int err; |
|---|
| 524 | 507 | |
|---|
| 525 | 508 | /* Rough check on arithmetic overflow, |
|---|
| 526 | | - better check is made in ip6_append_data(). |
|---|
| 509 | + * better check is made in ip6_append_data(). |
|---|
| 527 | 510 | */ |
|---|
| 528 | | - if (len > INT_MAX) |
|---|
| 511 | + if (len > INT_MAX - transhdrlen) |
|---|
| 529 | 512 | return -EMSGSIZE; |
|---|
| 513 | + ulen = len + transhdrlen; |
|---|
| 530 | 514 | |
|---|
| 531 | 515 | /* Mirror BSD error message compatibility */ |
|---|
| 532 | 516 | if (msg->msg_flags & MSG_OOB) |
|---|
| 533 | 517 | return -EOPNOTSUPP; |
|---|
| 534 | 518 | |
|---|
| 535 | | - /* |
|---|
| 536 | | - * Get and verify the address. |
|---|
| 537 | | - */ |
|---|
| 519 | + /* Get and verify the address */ |
|---|
| 538 | 520 | memset(&fl6, 0, sizeof(fl6)); |
|---|
| 539 | 521 | |
|---|
| 540 | 522 | fl6.flowi6_mark = sk->sk_mark; |
|---|
| .. | .. |
|---|
| 552 | 534 | daddr = &lsa->l2tp_addr; |
|---|
| 553 | 535 | if (np->sndflow) { |
|---|
| 554 | 536 | fl6.flowlabel = lsa->l2tp_flowinfo & IPV6_FLOWINFO_MASK; |
|---|
| 555 | | - if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { |
|---|
| 537 | + if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) { |
|---|
| 556 | 538 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
|---|
| 557 | | - if (flowlabel == NULL) |
|---|
| 539 | + if (IS_ERR(flowlabel)) |
|---|
| 558 | 540 | return -EINVAL; |
|---|
| 559 | 541 | } |
|---|
| 560 | 542 | } |
|---|
| 561 | 543 | |
|---|
| 562 | | - /* |
|---|
| 563 | | - * Otherwise it will be difficult to maintain |
|---|
| 544 | + /* Otherwise it will be difficult to maintain |
|---|
| 564 | 545 | * sk->sk_dst_cache. |
|---|
| 565 | 546 | */ |
|---|
| 566 | 547 | if (sk->sk_state == TCP_ESTABLISHED && |
|---|
| .. | .. |
|---|
| 595 | 576 | } |
|---|
| 596 | 577 | if ((fl6.flowlabel & IPV6_FLOWLABEL_MASK) && !flowlabel) { |
|---|
| 597 | 578 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
|---|
| 598 | | - if (flowlabel == NULL) |
|---|
| 579 | + if (IS_ERR(flowlabel)) |
|---|
| 599 | 580 | return -EINVAL; |
|---|
| 600 | 581 | } |
|---|
| 601 | | - if (!(opt->opt_nflen|opt->opt_flen)) |
|---|
| 582 | + if (!(opt->opt_nflen | opt->opt_flen)) |
|---|
| 602 | 583 | opt = NULL; |
|---|
| 603 | 584 | } |
|---|
| 604 | 585 | |
|---|
| .. | .. |
|---|
| 626 | 607 | else if (!fl6.flowi6_oif) |
|---|
| 627 | 608 | fl6.flowi6_oif = np->ucast_oif; |
|---|
| 628 | 609 | |
|---|
| 629 | | - security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
|---|
| 610 | + security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6)); |
|---|
| 630 | 611 | |
|---|
| 631 | 612 | if (ipc6.tclass < 0) |
|---|
| 632 | 613 | ipc6.tclass = np->tclass; |
|---|
| .. | .. |
|---|
| 749 | 730 | .hash = l2tp_ip6_hash, |
|---|
| 750 | 731 | .unhash = l2tp_ip6_unhash, |
|---|
| 751 | 732 | .obj_size = sizeof(struct l2tp_ip6_sock), |
|---|
| 752 | | -#ifdef CONFIG_COMPAT |
|---|
| 753 | | - .compat_setsockopt = compat_ipv6_setsockopt, |
|---|
| 754 | | - .compat_getsockopt = compat_ipv6_getsockopt, |
|---|
| 755 | | -#endif |
|---|
| 756 | 733 | }; |
|---|
| 757 | 734 | |
|---|
| 758 | 735 | static const struct proto_ops l2tp_ip6_ops = { |
|---|
| .. | .. |
|---|
| 766 | 743 | .getname = l2tp_ip6_getname, |
|---|
| 767 | 744 | .poll = datagram_poll, |
|---|
| 768 | 745 | .ioctl = inet6_ioctl, |
|---|
| 746 | + .gettstamp = sock_gettstamp, |
|---|
| 769 | 747 | .listen = sock_no_listen, |
|---|
| 770 | 748 | .shutdown = inet_shutdown, |
|---|
| 771 | 749 | .setsockopt = sock_common_setsockopt, |
|---|
| .. | .. |
|---|
| 775 | 753 | .mmap = sock_no_mmap, |
|---|
| 776 | 754 | .sendpage = sock_no_sendpage, |
|---|
| 777 | 755 | #ifdef CONFIG_COMPAT |
|---|
| 778 | | - .compat_setsockopt = compat_sock_common_setsockopt, |
|---|
| 779 | | - .compat_getsockopt = compat_sock_common_getsockopt, |
|---|
| 756 | + .compat_ioctl = inet6_compat_ioctl, |
|---|
| 780 | 757 | #endif |
|---|
| 781 | 758 | }; |
|---|
| 782 | 759 | |
|---|