aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c135
1 files changed, 89 insertions, 46 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 4468e1adc094..185ed3e59802 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -246,7 +246,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
246 do { 246 do {
247 if (low <= snum && snum <= high && 247 if (low <= snum && snum <= high &&
248 !test_bit(snum >> udptable->log, bitmap) && 248 !test_bit(snum >> udptable->log, bitmap) &&
249 !inet_is_reserved_local_port(snum)) 249 !inet_is_local_reserved_port(net, snum))
250 goto found; 250 goto found;
251 snum += rand; 251 snum += rand;
252 } while (snum != first); 252 } while (snum != first);
@@ -727,13 +727,12 @@ EXPORT_SYMBOL(udp_flush_pending_frames);
727void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst) 727void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
728{ 728{
729 struct udphdr *uh = udp_hdr(skb); 729 struct udphdr *uh = udp_hdr(skb);
730 struct sk_buff *frags = skb_shinfo(skb)->frag_list;
731 int offset = skb_transport_offset(skb); 730 int offset = skb_transport_offset(skb);
732 int len = skb->len - offset; 731 int len = skb->len - offset;
733 int hlen = len; 732 int hlen = len;
734 __wsum csum = 0; 733 __wsum csum = 0;
735 734
736 if (!frags) { 735 if (!skb_has_frag_list(skb)) {
737 /* 736 /*
738 * Only one fragment on the socket. 737 * Only one fragment on the socket.
739 */ 738 */
@@ -742,15 +741,17 @@ void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
742 uh->check = ~csum_tcpudp_magic(src, dst, len, 741 uh->check = ~csum_tcpudp_magic(src, dst, len,
743 IPPROTO_UDP, 0); 742 IPPROTO_UDP, 0);
744 } else { 743 } else {
744 struct sk_buff *frags;
745
745 /* 746 /*
746 * HW-checksum won't work as there are two or more 747 * HW-checksum won't work as there are two or more
747 * fragments on the socket so that all csums of sk_buffs 748 * fragments on the socket so that all csums of sk_buffs
748 * should be together 749 * should be together
749 */ 750 */
750 do { 751 skb_walk_frags(skb, frags) {
751 csum = csum_add(csum, frags->csum); 752 csum = csum_add(csum, frags->csum);
752 hlen -= frags->len; 753 hlen -= frags->len;
753 } while ((frags = frags->next)); 754 }
754 755
755 csum = skb_checksum(skb, offset, hlen, csum); 756 csum = skb_checksum(skb, offset, hlen, csum);
756 skb->ip_summed = CHECKSUM_NONE; 757 skb->ip_summed = CHECKSUM_NONE;
@@ -762,6 +763,43 @@ void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
762} 763}
763EXPORT_SYMBOL_GPL(udp4_hwcsum); 764EXPORT_SYMBOL_GPL(udp4_hwcsum);
764 765
766/* Function to set UDP checksum for an IPv4 UDP packet. This is intended
767 * for the simple case like when setting the checksum for a UDP tunnel.
768 */
769void udp_set_csum(bool nocheck, struct sk_buff *skb,
770 __be32 saddr, __be32 daddr, int len)
771{
772 struct udphdr *uh = udp_hdr(skb);
773
774 if (nocheck)
775 uh->check = 0;
776 else if (skb_is_gso(skb))
777 uh->check = ~udp_v4_check(len, saddr, daddr, 0);
778 else if (skb_dst(skb) && skb_dst(skb)->dev &&
779 (skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
780
781 BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
782
783 skb->ip_summed = CHECKSUM_PARTIAL;
784 skb->csum_start = skb_transport_header(skb) - skb->head;
785 skb->csum_offset = offsetof(struct udphdr, check);
786 uh->check = ~udp_v4_check(len, saddr, daddr, 0);
787 } else {
788 __wsum csum;
789
790 BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
791
792 uh->check = 0;
793 csum = skb_checksum(skb, 0, len, 0);
794 uh->check = udp_v4_check(len, saddr, daddr, csum);
795 if (uh->check == 0)
796 uh->check = CSUM_MANGLED_0;
797
798 skb->ip_summed = CHECKSUM_UNNECESSARY;
799 }
800}
801EXPORT_SYMBOL(udp_set_csum);
802
765static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4) 803static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
766{ 804{
767 struct sock *sk = skb->sk; 805 struct sock *sk = skb->sk;
@@ -785,7 +823,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
785 if (is_udplite) /* UDP-Lite */ 823 if (is_udplite) /* UDP-Lite */
786 csum = udplite_csum(skb); 824 csum = udplite_csum(skb);
787 825
788 else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */ 826 else if (sk->sk_no_check_tx) { /* UDP csum disabled */
789 827
790 skb->ip_summed = CHECKSUM_NONE; 828 skb->ip_summed = CHECKSUM_NONE;
791 goto send; 829 goto send;
@@ -1495,6 +1533,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1495 if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) { 1533 if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {
1496 int ret; 1534 int ret;
1497 1535
1536 /* Verify checksum before giving to encap */
1537 if (udp_lib_checksum_complete(skb))
1538 goto csum_error;
1539
1498 ret = encap_rcv(sk, skb); 1540 ret = encap_rcv(sk, skb);
1499 if (ret <= 0) { 1541 if (ret <= 0) {
1500 UDP_INC_STATS_BH(sock_net(sk), 1542 UDP_INC_STATS_BH(sock_net(sk),
@@ -1672,7 +1714,6 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
1672static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh, 1714static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
1673 int proto) 1715 int proto)
1674{ 1716{
1675 const struct iphdr *iph;
1676 int err; 1717 int err;
1677 1718
1678 UDP_SKB_CB(skb)->partial_cov = 0; 1719 UDP_SKB_CB(skb)->partial_cov = 0;
@@ -1684,22 +1725,8 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
1684 return err; 1725 return err;
1685 } 1726 }
1686 1727
1687 iph = ip_hdr(skb); 1728 return skb_checksum_init_zero_check(skb, proto, uh->check,
1688 if (uh->check == 0) { 1729 inet_compute_pseudo);
1689 skb->ip_summed = CHECKSUM_UNNECESSARY;
1690 } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
1691 if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
1692 proto, skb->csum))
1693 skb->ip_summed = CHECKSUM_UNNECESSARY;
1694 }
1695 if (!skb_csum_unnecessary(skb))
1696 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
1697 skb->len, proto, 0);
1698 /* Probably, we should checksum udp header (it should be in cache
1699 * in any case) and data in tiny packets (< rx copybreak).
1700 */
1701
1702 return 0;
1703} 1730}
1704 1731
1705/* 1732/*
@@ -1886,7 +1913,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
1886 unsigned int hash2 = udp4_portaddr_hash(net, loc_addr, hnum); 1913 unsigned int hash2 = udp4_portaddr_hash(net, loc_addr, hnum);
1887 unsigned int slot2 = hash2 & udp_table.mask; 1914 unsigned int slot2 = hash2 & udp_table.mask;
1888 struct udp_hslot *hslot2 = &udp_table.hash2[slot2]; 1915 struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
1889 INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr) 1916 INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr);
1890 const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum); 1917 const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
1891 1918
1892 rcu_read_lock(); 1919 rcu_read_lock();
@@ -1979,7 +2006,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1979 int (*push_pending_frames)(struct sock *)) 2006 int (*push_pending_frames)(struct sock *))
1980{ 2007{
1981 struct udp_sock *up = udp_sk(sk); 2008 struct udp_sock *up = udp_sk(sk);
1982 int val; 2009 int val, valbool;
1983 int err = 0; 2010 int err = 0;
1984 int is_udplite = IS_UDPLITE(sk); 2011 int is_udplite = IS_UDPLITE(sk);
1985 2012
@@ -1989,6 +2016,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1989 if (get_user(val, (int __user *)optval)) 2016 if (get_user(val, (int __user *)optval))
1990 return -EFAULT; 2017 return -EFAULT;
1991 2018
2019 valbool = val ? 1 : 0;
2020
1992 switch (optname) { 2021 switch (optname) {
1993 case UDP_CORK: 2022 case UDP_CORK:
1994 if (val != 0) { 2023 if (val != 0) {
@@ -2018,6 +2047,14 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
2018 } 2047 }
2019 break; 2048 break;
2020 2049
2050 case UDP_NO_CHECK6_TX:
2051 up->no_check6_tx = valbool;
2052 break;
2053
2054 case UDP_NO_CHECK6_RX:
2055 up->no_check6_rx = valbool;
2056 break;
2057
2021 /* 2058 /*
2022 * UDP-Lite's partial checksum coverage (RFC 3828). 2059 * UDP-Lite's partial checksum coverage (RFC 3828).
2023 */ 2060 */
@@ -2100,6 +2137,14 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
2100 val = up->encap_type; 2137 val = up->encap_type;
2101 break; 2138 break;
2102 2139
2140 case UDP_NO_CHECK6_TX:
2141 val = up->no_check6_tx;
2142 break;
2143
2144 case UDP_NO_CHECK6_RX:
2145 val = up->no_check6_rx;
2146 break;
2147
2103 /* The following two cannot be changed on UDP sockets, the return is 2148 /* The following two cannot be changed on UDP sockets, the return is
2104 * always 0 (which corresponds to the full checksum coverage of UDP). */ 2149 * always 0 (which corresponds to the full checksum coverage of UDP). */
2105 case UDPLITE_SEND_CSCOV: 2150 case UDPLITE_SEND_CSCOV:
@@ -2484,7 +2529,11 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2484 int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); 2529 int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
2485 __be16 protocol = skb->protocol; 2530 __be16 protocol = skb->protocol;
2486 netdev_features_t enc_features; 2531 netdev_features_t enc_features;
2487 int outer_hlen; 2532 int udp_offset, outer_hlen;
2533 unsigned int oldlen;
2534 bool need_csum;
2535
2536 oldlen = (u16)~skb->len;
2488 2537
2489 if (unlikely(!pskb_may_pull(skb, tnl_hlen))) 2538 if (unlikely(!pskb_may_pull(skb, tnl_hlen)))
2490 goto out; 2539 goto out;
@@ -2496,6 +2545,10 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2496 skb->mac_len = skb_inner_network_offset(skb); 2545 skb->mac_len = skb_inner_network_offset(skb);
2497 skb->protocol = htons(ETH_P_TEB); 2546 skb->protocol = htons(ETH_P_TEB);
2498 2547
2548 need_csum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM);
2549 if (need_csum)
2550 skb->encap_hdr_csum = 1;
2551
2499 /* segment inner packet. */ 2552 /* segment inner packet. */
2500 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); 2553 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
2501 segs = skb_mac_gso_segment(skb, enc_features); 2554 segs = skb_mac_gso_segment(skb, enc_features);
@@ -2506,10 +2559,11 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2506 } 2559 }
2507 2560
2508 outer_hlen = skb_tnl_header_len(skb); 2561 outer_hlen = skb_tnl_header_len(skb);
2562 udp_offset = outer_hlen - tnl_hlen;
2509 skb = segs; 2563 skb = segs;
2510 do { 2564 do {
2511 struct udphdr *uh; 2565 struct udphdr *uh;
2512 int udp_offset = outer_hlen - tnl_hlen; 2566 int len;
2513 2567
2514 skb_reset_inner_headers(skb); 2568 skb_reset_inner_headers(skb);
2515 skb->encapsulation = 1; 2569 skb->encapsulation = 1;
@@ -2520,31 +2574,20 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2520 skb_reset_mac_header(skb); 2574 skb_reset_mac_header(skb);
2521 skb_set_network_header(skb, mac_len); 2575 skb_set_network_header(skb, mac_len);
2522 skb_set_transport_header(skb, udp_offset); 2576 skb_set_transport_header(skb, udp_offset);
2577 len = skb->len - udp_offset;
2523 uh = udp_hdr(skb); 2578 uh = udp_hdr(skb);
2524 uh->len = htons(skb->len - udp_offset); 2579 uh->len = htons(len);
2525
2526 /* csum segment if tunnel sets skb with csum. */
2527 if (protocol == htons(ETH_P_IP) && unlikely(uh->check)) {
2528 struct iphdr *iph = ip_hdr(skb);
2529 2580
2530 uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 2581 if (need_csum) {
2531 skb->len - udp_offset, 2582 __be32 delta = htonl(oldlen + len);
2532 IPPROTO_UDP, 0);
2533 uh->check = csum_fold(skb_checksum(skb, udp_offset,
2534 skb->len - udp_offset, 0));
2535 if (uh->check == 0)
2536 uh->check = CSUM_MANGLED_0;
2537 2583
2538 } else if (protocol == htons(ETH_P_IPV6)) { 2584 uh->check = ~csum_fold((__force __wsum)
2539 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 2585 ((__force u32)uh->check +
2540 u32 len = skb->len - udp_offset; 2586 (__force u32)delta));
2587 uh->check = gso_make_checksum(skb, ~uh->check);
2541 2588
2542 uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
2543 len, IPPROTO_UDP, 0);
2544 uh->check = csum_fold(skb_checksum(skb, udp_offset, len, 0));
2545 if (uh->check == 0) 2589 if (uh->check == 0)
2546 uh->check = CSUM_MANGLED_0; 2590 uh->check = CSUM_MANGLED_0;
2547 skb->ip_summed = CHECKSUM_NONE;
2548 } 2591 }
2549 2592
2550 skb->protocol = protocol; 2593 skb->protocol = protocol;