diff options
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 3fb0ed5e4789..372fdc5381a9 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -562,10 +562,12 @@ static int __udp4_lib_err_encap_no_sk(struct sk_buff *skb, u32 info) | |||
562 | 562 | ||
563 | for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) { | 563 | for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) { |
564 | int (*handler)(struct sk_buff *skb, u32 info); | 564 | int (*handler)(struct sk_buff *skb, u32 info); |
565 | const struct ip_tunnel_encap_ops *encap; | ||
565 | 566 | ||
566 | if (!iptun_encaps[i]) | 567 | encap = rcu_dereference(iptun_encaps[i]); |
568 | if (!encap) | ||
567 | continue; | 569 | continue; |
568 | handler = rcu_dereference(iptun_encaps[i]->err_handler); | 570 | handler = encap->err_handler; |
569 | if (handler && !handler(skb, info)) | 571 | if (handler && !handler(skb, info)) |
570 | return 0; | 572 | return 0; |
571 | } | 573 | } |
@@ -847,15 +849,23 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4, | |||
847 | const int hlen = skb_network_header_len(skb) + | 849 | const int hlen = skb_network_header_len(skb) + |
848 | sizeof(struct udphdr); | 850 | sizeof(struct udphdr); |
849 | 851 | ||
850 | if (hlen + cork->gso_size > cork->fragsize) | 852 | if (hlen + cork->gso_size > cork->fragsize) { |
853 | kfree_skb(skb); | ||
851 | return -EINVAL; | 854 | return -EINVAL; |
852 | if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) | 855 | } |
856 | if (skb->len > cork->gso_size * UDP_MAX_SEGMENTS) { | ||
857 | kfree_skb(skb); | ||
853 | return -EINVAL; | 858 | return -EINVAL; |
854 | if (sk->sk_no_check_tx) | 859 | } |
860 | if (sk->sk_no_check_tx) { | ||
861 | kfree_skb(skb); | ||
855 | return -EINVAL; | 862 | return -EINVAL; |
863 | } | ||
856 | if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite || | 864 | if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite || |
857 | dst_xfrm(skb_dst(skb))) | 865 | dst_xfrm(skb_dst(skb))) { |
866 | kfree_skb(skb); | ||
858 | return -EIO; | 867 | return -EIO; |
868 | } | ||
859 | 869 | ||
860 | skb_shinfo(skb)->gso_size = cork->gso_size; | 870 | skb_shinfo(skb)->gso_size = cork->gso_size; |
861 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; | 871 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4; |
@@ -1918,7 +1928,7 @@ void udp_lib_rehash(struct sock *sk, u16 newhash) | |||
1918 | } | 1928 | } |
1919 | EXPORT_SYMBOL(udp_lib_rehash); | 1929 | EXPORT_SYMBOL(udp_lib_rehash); |
1920 | 1930 | ||
1921 | static void udp_v4_rehash(struct sock *sk) | 1931 | void udp_v4_rehash(struct sock *sk) |
1922 | { | 1932 | { |
1923 | u16 new_hash = ipv4_portaddr_hash(sock_net(sk), | 1933 | u16 new_hash = ipv4_portaddr_hash(sock_net(sk), |
1924 | inet_sk(sk)->inet_rcv_saddr, | 1934 | inet_sk(sk)->inet_rcv_saddr, |