diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_netlink.c | 1 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 24 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 11 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 1 | ||||
-rw-r--r-- | net/ipv4/ping.c | 14 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 5 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_offload.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_udp_tunnel.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_vti.c | 11 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 5 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 14 | ||||
-rw-r--r-- | net/packet/af_packet.c | 2 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 27 |
15 files changed, 84 insertions, 44 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 2ff9706647f2..e5ec470b851f 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -280,6 +280,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { | |||
280 | [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, | 280 | [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, |
281 | [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, | 281 | [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, |
282 | [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, | 282 | [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, |
283 | [IFLA_BRPORT_FAST_LEAVE]= { .type = NLA_U8 }, | ||
283 | [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, | 284 | [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, |
284 | [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, | 285 | [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, |
285 | }; | 286 | }; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a6882686ca3a..76321ea442c3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1498,6 +1498,7 @@ static int do_setlink(const struct sk_buff *skb, | |||
1498 | goto errout; | 1498 | goto errout; |
1499 | } | 1499 | } |
1500 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { | 1500 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { |
1501 | put_net(net); | ||
1501 | err = -EPERM; | 1502 | err = -EPERM; |
1502 | goto errout; | 1503 | goto errout; |
1503 | } | 1504 | } |
@@ -2685,13 +2686,20 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) | |||
2685 | int idx = 0; | 2686 | int idx = 0; |
2686 | u32 portid = NETLINK_CB(cb->skb).portid; | 2687 | u32 portid = NETLINK_CB(cb->skb).portid; |
2687 | u32 seq = cb->nlh->nlmsg_seq; | 2688 | u32 seq = cb->nlh->nlmsg_seq; |
2688 | struct nlattr *extfilt; | ||
2689 | u32 filter_mask = 0; | 2689 | u32 filter_mask = 0; |
2690 | 2690 | ||
2691 | extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), | 2691 | if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { |
2692 | IFLA_EXT_MASK); | 2692 | struct nlattr *extfilt; |
2693 | if (extfilt) | 2693 | |
2694 | filter_mask = nla_get_u32(extfilt); | 2694 | extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), |
2695 | IFLA_EXT_MASK); | ||
2696 | if (extfilt) { | ||
2697 | if (nla_len(extfilt) < sizeof(filter_mask)) | ||
2698 | return -EINVAL; | ||
2699 | |||
2700 | filter_mask = nla_get_u32(extfilt); | ||
2701 | } | ||
2702 | } | ||
2695 | 2703 | ||
2696 | rcu_read_lock(); | 2704 | rcu_read_lock(); |
2697 | for_each_netdev_rcu(net, dev) { | 2705 | for_each_netdev_rcu(net, dev) { |
@@ -2798,6 +2806,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2798 | if (br_spec) { | 2806 | if (br_spec) { |
2799 | nla_for_each_nested(attr, br_spec, rem) { | 2807 | nla_for_each_nested(attr, br_spec, rem) { |
2800 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { | 2808 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { |
2809 | if (nla_len(attr) < sizeof(flags)) | ||
2810 | return -EINVAL; | ||
2811 | |||
2801 | have_flags = true; | 2812 | have_flags = true; |
2802 | flags = nla_get_u16(attr); | 2813 | flags = nla_get_u16(attr); |
2803 | break; | 2814 | break; |
@@ -2868,6 +2879,9 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2868 | if (br_spec) { | 2879 | if (br_spec) { |
2869 | nla_for_each_nested(attr, br_spec, rem) { | 2880 | nla_for_each_nested(attr, br_spec, rem) { |
2870 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { | 2881 | if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { |
2882 | if (nla_len(attr) < sizeof(flags)) | ||
2883 | return -EINVAL; | ||
2884 | |||
2871 | have_flags = true; | 2885 | have_flags = true; |
2872 | flags = nla_get_u16(attr); | 2886 | flags = nla_get_u16(attr); |
2873 | break; | 2887 | break; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8b7fe5b03906..e67da4e6c324 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1386,6 +1386,17 @@ out: | |||
1386 | return pp; | 1386 | return pp; |
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | ||
1390 | { | ||
1391 | if (sk->sk_family == AF_INET) | ||
1392 | return ip_recv_error(sk, msg, len, addr_len); | ||
1393 | #if IS_ENABLED(CONFIG_IPV6) | ||
1394 | if (sk->sk_family == AF_INET6) | ||
1395 | return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len); | ||
1396 | #endif | ||
1397 | return -EINVAL; | ||
1398 | } | ||
1399 | |||
1389 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) | 1400 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) |
1390 | { | 1401 | { |
1391 | __be16 newlen = htons(skb->len - nhoff); | 1402 | __be16 newlen = htons(skb->len - nhoff); |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 3e861011e4a3..1a7e979e80ba 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -528,6 +528,7 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = { | |||
528 | .validate = vti_tunnel_validate, | 528 | .validate = vti_tunnel_validate, |
529 | .newlink = vti_newlink, | 529 | .newlink = vti_newlink, |
530 | .changelink = vti_changelink, | 530 | .changelink = vti_changelink, |
531 | .dellink = ip_tunnel_dellink, | ||
531 | .get_size = vti_get_size, | 532 | .get_size = vti_get_size, |
532 | .fill_info = vti_fill_info, | 533 | .fill_info = vti_fill_info, |
533 | }; | 534 | }; |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 57f7c9804139..5d740cccf69e 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -217,6 +217,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) | |||
217 | &ipv6_hdr(skb)->daddr)) | 217 | &ipv6_hdr(skb)->daddr)) |
218 | continue; | 218 | continue; |
219 | #endif | 219 | #endif |
220 | } else { | ||
221 | continue; | ||
220 | } | 222 | } |
221 | 223 | ||
222 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) | 224 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) |
@@ -853,16 +855,8 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
853 | if (flags & MSG_OOB) | 855 | if (flags & MSG_OOB) |
854 | goto out; | 856 | goto out; |
855 | 857 | ||
856 | if (flags & MSG_ERRQUEUE) { | 858 | if (flags & MSG_ERRQUEUE) |
857 | if (family == AF_INET) { | 859 | return inet_recv_error(sk, msg, len, addr_len); |
858 | return ip_recv_error(sk, msg, len, addr_len); | ||
859 | #if IS_ENABLED(CONFIG_IPV6) | ||
860 | } else if (family == AF_INET6) { | ||
861 | return pingv6_ops.ipv6_recv_error(sk, msg, len, | ||
862 | addr_len); | ||
863 | #endif | ||
864 | } | ||
865 | } | ||
866 | 860 | ||
867 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 861 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
868 | if (!skb) | 862 | if (!skb) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 39ec0c379545..38c2bcb8dd5d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1598,7 +1598,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1598 | u32 urg_hole = 0; | 1598 | u32 urg_hole = 0; |
1599 | 1599 | ||
1600 | if (unlikely(flags & MSG_ERRQUEUE)) | 1600 | if (unlikely(flags & MSG_ERRQUEUE)) |
1601 | return ip_recv_error(sk, msg, len, addr_len); | 1601 | return inet_recv_error(sk, msg, len, addr_len); |
1602 | 1602 | ||
1603 | if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && | 1603 | if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && |
1604 | (sk->sk_state == TCP_ESTABLISHED)) | 1604 | (sk->sk_state == TCP_ESTABLISHED)) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9c7d7621466b..147be2024290 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -598,7 +598,10 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
598 | if (th->rst) | 598 | if (th->rst) |
599 | return; | 599 | return; |
600 | 600 | ||
601 | if (skb_rtable(skb)->rt_type != RTN_LOCAL) | 601 | /* If sk not NULL, it means we did a successful lookup and incoming |
602 | * route had to be correct. prequeue might have dropped our dst. | ||
603 | */ | ||
604 | if (!sk && skb_rtable(skb)->rt_type != RTN_LOCAL) | ||
602 | return; | 605 | return; |
603 | 606 | ||
604 | /* Swap the send and the receive. */ | 607 | /* Swap the send and the receive. */ |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 4564e1fca3eb..0e32d2e1bdbf 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -502,11 +502,11 @@ static int ip6gre_rcv(struct sk_buff *skb) | |||
502 | 502 | ||
503 | skb->protocol = gre_proto; | 503 | skb->protocol = gre_proto; |
504 | /* WCCP version 1 and 2 protocol decoding. | 504 | /* WCCP version 1 and 2 protocol decoding. |
505 | * - Change protocol to IP | 505 | * - Change protocol to IPv6 |
506 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header | 506 | * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header |
507 | */ | 507 | */ |
508 | if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) { | 508 | if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) { |
509 | skb->protocol = htons(ETH_P_IP); | 509 | skb->protocol = htons(ETH_P_IPV6); |
510 | if ((*(h + offset) & 0xF0) != 0x40) | 510 | if ((*(h + offset) & 0xF0) != 0x40) |
511 | offset += 4; | 511 | offset += 4; |
512 | } | 512 | } |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index a071563a7e6e..01e12d0d8fcc 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -69,7 +69,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
69 | int nhoff; | 69 | int nhoff; |
70 | 70 | ||
71 | if (unlikely(skb_shinfo(skb)->gso_type & | 71 | if (unlikely(skb_shinfo(skb)->gso_type & |
72 | ~(SKB_GSO_UDP | | 72 | ~(SKB_GSO_TCPV4 | |
73 | SKB_GSO_UDP | | ||
73 | SKB_GSO_DODGY | | 74 | SKB_GSO_DODGY | |
74 | SKB_GSO_TCP_ECN | | 75 | SKB_GSO_TCP_ECN | |
75 | SKB_GSO_GRE | | 76 | SKB_GSO_GRE | |
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c index b04ed72c4542..8db6c98fe218 100644 --- a/net/ipv6/ip6_udp_tunnel.c +++ b/net/ipv6/ip6_udp_tunnel.c | |||
@@ -79,15 +79,13 @@ int udp_tunnel6_xmit_skb(struct socket *sock, struct dst_entry *dst, | |||
79 | uh->source = src_port; | 79 | uh->source = src_port; |
80 | 80 | ||
81 | uh->len = htons(skb->len); | 81 | uh->len = htons(skb->len); |
82 | uh->check = 0; | ||
83 | 82 | ||
84 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 83 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
85 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | 84 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
86 | | IPSKB_REROUTED); | 85 | | IPSKB_REROUTED); |
87 | skb_dst_set(skb, dst); | 86 | skb_dst_set(skb, dst); |
88 | 87 | ||
89 | udp6_set_csum(udp_get_no_check6_tx(sk), skb, &inet6_sk(sk)->saddr, | 88 | udp6_set_csum(udp_get_no_check6_tx(sk), skb, saddr, daddr, skb->len); |
90 | &sk->sk_v6_daddr, skb->len); | ||
91 | 89 | ||
92 | __skb_push(skb, sizeof(*ip6h)); | 90 | __skb_push(skb, sizeof(*ip6h)); |
93 | skb_reset_network_header(skb); | 91 | skb_reset_network_header(skb); |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 31089d153fd3..bcda14de7f84 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -905,6 +905,15 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev, | |||
905 | return vti6_tnl_create2(dev); | 905 | return vti6_tnl_create2(dev); |
906 | } | 906 | } |
907 | 907 | ||
908 | static void vti6_dellink(struct net_device *dev, struct list_head *head) | ||
909 | { | ||
910 | struct net *net = dev_net(dev); | ||
911 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); | ||
912 | |||
913 | if (dev != ip6n->fb_tnl_dev) | ||
914 | unregister_netdevice_queue(dev, head); | ||
915 | } | ||
916 | |||
908 | static int vti6_changelink(struct net_device *dev, struct nlattr *tb[], | 917 | static int vti6_changelink(struct net_device *dev, struct nlattr *tb[], |
909 | struct nlattr *data[]) | 918 | struct nlattr *data[]) |
910 | { | 919 | { |
@@ -980,6 +989,7 @@ static struct rtnl_link_ops vti6_link_ops __read_mostly = { | |||
980 | .setup = vti6_dev_setup, | 989 | .setup = vti6_dev_setup, |
981 | .validate = vti6_validate, | 990 | .validate = vti6_validate, |
982 | .newlink = vti6_newlink, | 991 | .newlink = vti6_newlink, |
992 | .dellink = vti6_dellink, | ||
983 | .changelink = vti6_changelink, | 993 | .changelink = vti6_changelink, |
984 | .get_size = vti6_get_size, | 994 | .get_size = vti6_get_size, |
985 | .fill_info = vti6_fill_info, | 995 | .fill_info = vti6_fill_info, |
@@ -1020,6 +1030,7 @@ static int __net_init vti6_init_net(struct net *net) | |||
1020 | if (!ip6n->fb_tnl_dev) | 1030 | if (!ip6n->fb_tnl_dev) |
1021 | goto err_alloc_dev; | 1031 | goto err_alloc_dev; |
1022 | dev_net_set(ip6n->fb_tnl_dev, net); | 1032 | dev_net_set(ip6n->fb_tnl_dev, net); |
1033 | ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops; | ||
1023 | 1034 | ||
1024 | err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev); | 1035 | err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev); |
1025 | if (err < 0) | 1036 | if (err < 0) |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ace29b60813c..dc495ae2ead0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -903,7 +903,10 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) | |||
903 | if (th->rst) | 903 | if (th->rst) |
904 | return; | 904 | return; |
905 | 905 | ||
906 | if (!ipv6_unicast_destination(skb)) | 906 | /* If sk not NULL, it means we did a successful lookup and incoming |
907 | * route had to be correct. prequeue might have dropped our dst. | ||
908 | */ | ||
909 | if (!sk && !ipv6_unicast_destination(skb)) | ||
907 | return; | 910 | return; |
908 | 911 | ||
909 | #ifdef CONFIG_TCP_MD5SIG | 912 | #ifdef CONFIG_TCP_MD5SIG |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 2c699757bccf..5016a6929085 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -611,16 +611,12 @@ __nf_conntrack_confirm(struct sk_buff *skb) | |||
611 | */ | 611 | */ |
612 | NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); | 612 | NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); |
613 | pr_debug("Confirming conntrack %p\n", ct); | 613 | pr_debug("Confirming conntrack %p\n", ct); |
614 | 614 | /* We have to check the DYING flag inside the lock to prevent | |
615 | /* We have to check the DYING flag after unlink to prevent | 615 | a race against nf_ct_get_next_corpse() possibly called from |
616 | * a race against nf_ct_get_next_corpse() possibly called from | 616 | user context, else we insert an already 'dead' hash, blocking |
617 | * user context, else we insert an already 'dead' hash, blocking | 617 | further use of that particular connection -JM */ |
618 | * further use of that particular connection -JM. | ||
619 | */ | ||
620 | nf_ct_del_from_dying_or_unconfirmed_list(ct); | ||
621 | 618 | ||
622 | if (unlikely(nf_ct_is_dying(ct))) { | 619 | if (unlikely(nf_ct_is_dying(ct))) { |
623 | nf_ct_add_to_dying_list(ct); | ||
624 | nf_conntrack_double_unlock(hash, reply_hash); | 620 | nf_conntrack_double_unlock(hash, reply_hash); |
625 | local_bh_enable(); | 621 | local_bh_enable(); |
626 | return NF_ACCEPT; | 622 | return NF_ACCEPT; |
@@ -640,6 +636,8 @@ __nf_conntrack_confirm(struct sk_buff *skb) | |||
640 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) | 636 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) |
641 | goto out; | 637 | goto out; |
642 | 638 | ||
639 | nf_ct_del_from_dying_or_unconfirmed_list(ct); | ||
640 | |||
643 | /* Timer relative to confirmation time, not original | 641 | /* Timer relative to confirmation time, not original |
644 | setting time, otherwise we'd get timer wrap in | 642 | setting time, otherwise we'd get timer wrap in |
645 | weird delay cases. */ | 643 | weird delay cases. */ |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 87d20f48ff06..07c04a841ba0 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -378,7 +378,7 @@ static void unregister_prot_hook(struct sock *sk, bool sync) | |||
378 | __unregister_prot_hook(sk, sync); | 378 | __unregister_prot_hook(sk, sync); |
379 | } | 379 | } |
380 | 380 | ||
381 | static inline __pure struct page *pgv_to_page(void *addr) | 381 | static inline struct page * __pure pgv_to_page(void *addr) |
382 | { | 382 | { |
383 | if (is_vmalloc_addr(addr)) | 383 | if (is_vmalloc_addr(addr)) |
384 | return vmalloc_to_page(addr); | 384 | return vmalloc_to_page(addr); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 3f959c681885..f9c052d508f0 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -1019,17 +1019,12 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
1019 | xid = *p++; | 1019 | xid = *p++; |
1020 | calldir = *p; | 1020 | calldir = *p; |
1021 | 1021 | ||
1022 | if (bc_xprt) | 1022 | if (!bc_xprt) |
1023 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1024 | |||
1025 | if (!req) { | ||
1026 | printk(KERN_NOTICE | ||
1027 | "%s: Got unrecognized reply: " | ||
1028 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1029 | __func__, ntohl(calldir), | ||
1030 | bc_xprt, ntohl(xid)); | ||
1031 | return -EAGAIN; | 1023 | return -EAGAIN; |
1032 | } | 1024 | spin_lock_bh(&bc_xprt->transport_lock); |
1025 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1026 | if (!req) | ||
1027 | goto unlock_notfound; | ||
1033 | 1028 | ||
1034 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); | 1029 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); |
1035 | /* | 1030 | /* |
@@ -1040,11 +1035,21 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
1040 | dst = &req->rq_private_buf.head[0]; | 1035 | dst = &req->rq_private_buf.head[0]; |
1041 | src = &rqstp->rq_arg.head[0]; | 1036 | src = &rqstp->rq_arg.head[0]; |
1042 | if (dst->iov_len < src->iov_len) | 1037 | if (dst->iov_len < src->iov_len) |
1043 | return -EAGAIN; /* whatever; just giving up. */ | 1038 | goto unlock_eagain; /* whatever; just giving up. */ |
1044 | memcpy(dst->iov_base, src->iov_base, src->iov_len); | 1039 | memcpy(dst->iov_base, src->iov_base, src->iov_len); |
1045 | xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); | 1040 | xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len); |
1046 | rqstp->rq_arg.len = 0; | 1041 | rqstp->rq_arg.len = 0; |
1042 | spin_unlock_bh(&bc_xprt->transport_lock); | ||
1047 | return 0; | 1043 | return 0; |
1044 | unlock_notfound: | ||
1045 | printk(KERN_NOTICE | ||
1046 | "%s: Got unrecognized reply: " | ||
1047 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1048 | __func__, ntohl(calldir), | ||
1049 | bc_xprt, ntohl(xid)); | ||
1050 | unlock_eagain: | ||
1051 | spin_unlock_bh(&bc_xprt->transport_lock); | ||
1052 | return -EAGAIN; | ||
1048 | } | 1053 | } |
1049 | 1054 | ||
1050 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) | 1055 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) |