aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2014-05-23 11:47:32 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-23 16:28:53 -0400
commit1c19448c9ba6545b80ded18488a64a7f3d8e6998 (patch)
tree7323d68eaf334d9040a9d5a709c56caf2a7aaeeb /net/ipv6/udp.c
parent28448b80456feafe07e2d05b6363b00f61f6171e (diff)
net: Make enabling of zero UDP6 csums more restrictive
RFC 6935 permits zero checksums to be used in IPv6 however this is recommended only for certain tunnel protocols, it does not make checksums completely optional like they are in IPv4. This patch restricts the use of IPv6 zero checksums that was previously intoduced. no_check6_tx and no_check6_rx have been added to control the use of checksums in UDP6 RX and TX path. The normal sk_no_check_{rx,tx} settings are not used (this avoids ambiguity when dealing with a dual stack socket). A helper function has been added (udp_set_no_check6) which can be called by tunnel impelmentations to all zero checksums (send on the socket, and accept them as valid). Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b8db453133aa..60325236446a 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -794,10 +794,10 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
794 dif = inet6_iif(skb); 794 dif = inet6_iif(skb);
795 sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); 795 sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
796 while (sk) { 796 while (sk) {
797 /* If zero checksum and sk_no_check is not on for 797 /* If zero checksum and no_check is not on for
798 * the socket then skip it. 798 * the socket then skip it.
799 */ 799 */
800 if (uh->check || sk->sk_no_check_rx) 800 if (uh->check || udp_sk(sk)->no_check6_rx)
801 stack[count++] = sk; 801 stack[count++] = sk;
802 802
803 sk = udp_v6_mcast_next(net, sk_nulls_next(sk), uh->dest, daddr, 803 sk = udp_v6_mcast_next(net, sk_nulls_next(sk), uh->dest, daddr,
@@ -887,7 +887,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
887 if (sk != NULL) { 887 if (sk != NULL) {
888 int ret; 888 int ret;
889 889
890 if (!uh->check && !sk->sk_no_check_rx) { 890 if (!uh->check && !udp_sk(sk)->no_check6_rx) {
891 sock_put(sk); 891 sock_put(sk);
892 udp6_csum_zero_error(skb); 892 udp6_csum_zero_error(skb);
893 goto csum_error; 893 goto csum_error;
@@ -1037,7 +1037,7 @@ static int udp_v6_push_pending_frames(struct sock *sk)
1037 1037
1038 if (is_udplite) 1038 if (is_udplite)
1039 csum = udplite_csum_outgoing(sk, skb); 1039 csum = udplite_csum_outgoing(sk, skb);
1040 else if (sk->sk_no_check_tx) { /* UDP csum disabled */ 1040 else if (up->no_check6_tx) { /* UDP csum disabled */
1041 skb->ip_summed = CHECKSUM_NONE; 1041 skb->ip_summed = CHECKSUM_NONE;
1042 goto send; 1042 goto send;
1043 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ 1043 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */