diff options
Diffstat (limited to 'net/ipv4/af_inet.c')
| -rw-r--r-- | net/ipv4/af_inet.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f71357422380..551ce564b035 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -154,7 +154,7 @@ void inet_sock_destruct(struct sock *sk) | |||
| 154 | WARN_ON(sk->sk_forward_alloc); | 154 | WARN_ON(sk->sk_forward_alloc); |
| 155 | 155 | ||
| 156 | kfree(inet->opt); | 156 | kfree(inet->opt); |
| 157 | dst_release(sk->sk_dst_cache); | 157 | dst_release(rcu_dereference_check(sk->sk_dst_cache, 1)); |
| 158 | sk_refcnt_debug_dec(sk); | 158 | sk_refcnt_debug_dec(sk); |
| 159 | } | 159 | } |
| 160 | EXPORT_SYMBOL(inet_sock_destruct); | 160 | EXPORT_SYMBOL(inet_sock_destruct); |
| @@ -419,6 +419,8 @@ int inet_release(struct socket *sock) | |||
| 419 | if (sk) { | 419 | if (sk) { |
| 420 | long timeout; | 420 | long timeout; |
| 421 | 421 | ||
| 422 | sock_rps_reset_flow(sk); | ||
| 423 | |||
| 422 | /* Applications forget to leave groups before exiting */ | 424 | /* Applications forget to leave groups before exiting */ |
| 423 | ip_mc_drop_socket(sk); | 425 | ip_mc_drop_socket(sk); |
| 424 | 426 | ||
| @@ -546,7 +548,7 @@ static long inet_wait_for_connect(struct sock *sk, long timeo) | |||
| 546 | { | 548 | { |
| 547 | DEFINE_WAIT(wait); | 549 | DEFINE_WAIT(wait); |
| 548 | 550 | ||
| 549 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 551 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
| 550 | 552 | ||
| 551 | /* Basic assumption: if someone sets sk->sk_err, he _must_ | 553 | /* Basic assumption: if someone sets sk->sk_err, he _must_ |
| 552 | * change state of the socket from TCP_SYN_*. | 554 | * change state of the socket from TCP_SYN_*. |
| @@ -559,9 +561,9 @@ static long inet_wait_for_connect(struct sock *sk, long timeo) | |||
| 559 | lock_sock(sk); | 561 | lock_sock(sk); |
| 560 | if (signal_pending(current) || !timeo) | 562 | if (signal_pending(current) || !timeo) |
| 561 | break; | 563 | break; |
| 562 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 564 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
| 563 | } | 565 | } |
| 564 | finish_wait(sk->sk_sleep, &wait); | 566 | finish_wait(sk_sleep(sk), &wait); |
| 565 | return timeo; | 567 | return timeo; |
| 566 | } | 568 | } |
| 567 | 569 | ||
| @@ -720,6 +722,8 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 720 | { | 722 | { |
| 721 | struct sock *sk = sock->sk; | 723 | struct sock *sk = sock->sk; |
| 722 | 724 | ||
| 725 | sock_rps_record_flow(sk); | ||
| 726 | |||
| 723 | /* We may need to bind the socket. */ | 727 | /* We may need to bind the socket. */ |
| 724 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 728 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) |
| 725 | return -EAGAIN; | 729 | return -EAGAIN; |
| @@ -728,12 +732,13 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 728 | } | 732 | } |
| 729 | EXPORT_SYMBOL(inet_sendmsg); | 733 | EXPORT_SYMBOL(inet_sendmsg); |
| 730 | 734 | ||
| 731 | |||
| 732 | static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | 735 | static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, |
| 733 | size_t size, int flags) | 736 | size_t size, int flags) |
| 734 | { | 737 | { |
| 735 | struct sock *sk = sock->sk; | 738 | struct sock *sk = sock->sk; |
| 736 | 739 | ||
| 740 | sock_rps_record_flow(sk); | ||
| 741 | |||
| 737 | /* We may need to bind the socket. */ | 742 | /* We may need to bind the socket. */ |
| 738 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) | 743 | if (!inet_sk(sk)->inet_num && inet_autobind(sk)) |
| 739 | return -EAGAIN; | 744 | return -EAGAIN; |
| @@ -743,6 +748,22 @@ static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | |||
| 743 | return sock_no_sendpage(sock, page, offset, size, flags); | 748 | return sock_no_sendpage(sock, page, offset, size, flags); |
| 744 | } | 749 | } |
| 745 | 750 | ||
| 751 | int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | ||
| 752 | size_t size, int flags) | ||
| 753 | { | ||
| 754 | struct sock *sk = sock->sk; | ||
| 755 | int addr_len = 0; | ||
| 756 | int err; | ||
| 757 | |||
| 758 | sock_rps_record_flow(sk); | ||
| 759 | |||
| 760 | err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT, | ||
| 761 | flags & ~MSG_DONTWAIT, &addr_len); | ||
| 762 | if (err >= 0) | ||
| 763 | msg->msg_namelen = addr_len; | ||
| 764 | return err; | ||
| 765 | } | ||
| 766 | EXPORT_SYMBOL(inet_recvmsg); | ||
| 746 | 767 | ||
| 747 | int inet_shutdown(struct socket *sock, int how) | 768 | int inet_shutdown(struct socket *sock, int how) |
| 748 | { | 769 | { |
| @@ -872,7 +893,7 @@ const struct proto_ops inet_stream_ops = { | |||
| 872 | .setsockopt = sock_common_setsockopt, | 893 | .setsockopt = sock_common_setsockopt, |
| 873 | .getsockopt = sock_common_getsockopt, | 894 | .getsockopt = sock_common_getsockopt, |
| 874 | .sendmsg = tcp_sendmsg, | 895 | .sendmsg = tcp_sendmsg, |
| 875 | .recvmsg = sock_common_recvmsg, | 896 | .recvmsg = inet_recvmsg, |
| 876 | .mmap = sock_no_mmap, | 897 | .mmap = sock_no_mmap, |
| 877 | .sendpage = tcp_sendpage, | 898 | .sendpage = tcp_sendpage, |
| 878 | .splice_read = tcp_splice_read, | 899 | .splice_read = tcp_splice_read, |
| @@ -899,7 +920,7 @@ const struct proto_ops inet_dgram_ops = { | |||
| 899 | .setsockopt = sock_common_setsockopt, | 920 | .setsockopt = sock_common_setsockopt, |
| 900 | .getsockopt = sock_common_getsockopt, | 921 | .getsockopt = sock_common_getsockopt, |
| 901 | .sendmsg = inet_sendmsg, | 922 | .sendmsg = inet_sendmsg, |
| 902 | .recvmsg = sock_common_recvmsg, | 923 | .recvmsg = inet_recvmsg, |
| 903 | .mmap = sock_no_mmap, | 924 | .mmap = sock_no_mmap, |
| 904 | .sendpage = inet_sendpage, | 925 | .sendpage = inet_sendpage, |
| 905 | #ifdef CONFIG_COMPAT | 926 | #ifdef CONFIG_COMPAT |
| @@ -929,7 +950,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
| 929 | .setsockopt = sock_common_setsockopt, | 950 | .setsockopt = sock_common_setsockopt, |
| 930 | .getsockopt = sock_common_getsockopt, | 951 | .getsockopt = sock_common_getsockopt, |
| 931 | .sendmsg = inet_sendmsg, | 952 | .sendmsg = inet_sendmsg, |
| 932 | .recvmsg = sock_common_recvmsg, | 953 | .recvmsg = inet_recvmsg, |
| 933 | .mmap = sock_no_mmap, | 954 | .mmap = sock_no_mmap, |
| 934 | .sendpage = inet_sendpage, | 955 | .sendpage = inet_sendpage, |
| 935 | #ifdef CONFIG_COMPAT | 956 | #ifdef CONFIG_COMPAT |
| @@ -1302,8 +1323,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
| 1302 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) | 1323 | if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) |
| 1303 | goto out_unlock; | 1324 | goto out_unlock; |
| 1304 | 1325 | ||
| 1305 | id = ntohl(*(u32 *)&iph->id); | 1326 | id = ntohl(*(__be32 *)&iph->id); |
| 1306 | flush = (u16)((ntohl(*(u32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); | 1327 | flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF)); |
| 1307 | id >>= 16; | 1328 | id >>= 16; |
| 1308 | 1329 | ||
| 1309 | for (p = *head; p; p = p->next) { | 1330 | for (p = *head; p; p = p->next) { |
| @@ -1316,8 +1337,8 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head, | |||
| 1316 | 1337 | ||
| 1317 | if ((iph->protocol ^ iph2->protocol) | | 1338 | if ((iph->protocol ^ iph2->protocol) | |
| 1318 | (iph->tos ^ iph2->tos) | | 1339 | (iph->tos ^ iph2->tos) | |
| 1319 | (iph->saddr ^ iph2->saddr) | | 1340 | ((__force u32)iph->saddr ^ (__force u32)iph2->saddr) | |
| 1320 | (iph->daddr ^ iph2->daddr)) { | 1341 | ((__force u32)iph->daddr ^ (__force u32)iph2->daddr)) { |
| 1321 | NAPI_GRO_CB(p)->same_flow = 0; | 1342 | NAPI_GRO_CB(p)->same_flow = 0; |
| 1322 | continue; | 1343 | continue; |
| 1323 | } | 1344 | } |
| @@ -1407,10 +1428,10 @@ EXPORT_SYMBOL_GPL(snmp_fold_field); | |||
| 1407 | int snmp_mib_init(void __percpu *ptr[2], size_t mibsize) | 1428 | int snmp_mib_init(void __percpu *ptr[2], size_t mibsize) |
| 1408 | { | 1429 | { |
| 1409 | BUG_ON(ptr == NULL); | 1430 | BUG_ON(ptr == NULL); |
| 1410 | ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); | 1431 | ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long)); |
| 1411 | if (!ptr[0]) | 1432 | if (!ptr[0]) |
| 1412 | goto err0; | 1433 | goto err0; |
| 1413 | ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long long)); | 1434 | ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long)); |
| 1414 | if (!ptr[1]) | 1435 | if (!ptr[1]) |
| 1415 | goto err1; | 1436 | goto err1; |
| 1416 | return 0; | 1437 | return 0; |
| @@ -1552,9 +1573,13 @@ static int __init inet_init(void) | |||
| 1552 | 1573 | ||
| 1553 | BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)); | 1574 | BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)); |
| 1554 | 1575 | ||
| 1576 | sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL); | ||
| 1577 | if (!sysctl_local_reserved_ports) | ||
| 1578 | goto out; | ||
| 1579 | |||
| 1555 | rc = proto_register(&tcp_prot, 1); | 1580 | rc = proto_register(&tcp_prot, 1); |
| 1556 | if (rc) | 1581 | if (rc) |
| 1557 | goto out; | 1582 | goto out_free_reserved_ports; |
| 1558 | 1583 | ||
| 1559 | rc = proto_register(&udp_prot, 1); | 1584 | rc = proto_register(&udp_prot, 1); |
| 1560 | if (rc) | 1585 | if (rc) |
| @@ -1653,6 +1678,8 @@ out_unregister_udp_proto: | |||
| 1653 | proto_unregister(&udp_prot); | 1678 | proto_unregister(&udp_prot); |
| 1654 | out_unregister_tcp_proto: | 1679 | out_unregister_tcp_proto: |
| 1655 | proto_unregister(&tcp_prot); | 1680 | proto_unregister(&tcp_prot); |
| 1681 | out_free_reserved_ports: | ||
| 1682 | kfree(sysctl_local_reserved_ports); | ||
| 1656 | goto out; | 1683 | goto out; |
| 1657 | } | 1684 | } |
| 1658 | 1685 | ||
