aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-23 16:29:04 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-23 16:29:04 -0400
commit76fcee2438b90e473b67ea52b9b9e0648aa501f8 (patch)
tree842991b315c84e51fa4c2ececfba60e2992944b9
parent0c3592b821eb4069c8ab3934fc0e78f358d88ae4 (diff)
parent6b649feafe10b293f4bd5a74aca95faf625ae525 (diff)
Merge branch 'inet_csums_part3'
Tom Herbert says: ==================== net: Checksum offload changes - Part III I am working on overhauling RX checksum offload. Goals of this effort are: - Specify what exactly it means when driver returns CHECKSUM_UNNECESSARY - Preserve CHECKSUM_COMPLETE through encapsulation layers - Don't do skb_checksum more than once per packet - Unify GRO and non-GRO csum verification as much as possible - Unify the checksum functions (checksum_init) - Simply code What is in this third patch set: - Remove sk_no_check from sunrpc (doesn't seem to have any effect) - Eliminate no_check from protosw. All protocols are using default of zero for this - Split sk_no_check into sk_no_check_tx and sk_no_check_rx - Make enabling of UDP6 more restrictive and explicit - Support zero UDP6 checksums in l2tp V2: Took out vxlan changes to set zero csums in IPv6, this will be in a later patch set. V3: Fixed bug in restricting UDP6 checksums. Please review carefully and test if possible, mucking with basic checksum functions is always a little precarious :-) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/scsi/iscsi_tcp.c2
-rw-r--r--include/linux/udp.h24
-rw-r--r--include/net/protocol.h1
-rw-r--r--include/net/sock.h6
-rw-r--r--include/net/udp.h9
-rw-r--r--include/uapi/linux/l2tp.h2
-rw-r--r--include/uapi/linux/udp.h2
-rw-r--r--net/appletalk/ddp.c2
-rw-r--r--net/core/sock.c4
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/decnet/af_decnet.c2
-rw-r--r--net/ipv4/af_inet.c7
-rw-r--r--net/ipv4/udp.c22
-rw-r--r--net/ipv4/udplite.c1
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/ipv6/ping.c1
-rw-r--r--net/ipv6/raw.c1
-rw-r--r--net/ipv6/tcp_ipv6.c1
-rw-r--r--net/ipv6/udp.c9
-rw-r--r--net/ipv6/udplite.c1
-rw-r--r--net/ipx/af_ipx.c2
-rw-r--r--net/ipx/ipx_route.c3
-rw-r--r--net/l2tp/l2tp_core.c13
-rw-r--r--net/l2tp/l2tp_core.h4
-rw-r--r--net/l2tp/l2tp_ip.c1
-rw-r--r--net/l2tp/l2tp_ip6.c1
-rw-r--r--net/l2tp/l2tp_netlink.c10
-rw-r--r--net/sctp/ipv6.c2
-rw-r--r--net/sctp/protocol.c2
-rw-r--r--net/sctp/socket.c3
-rw-r--r--net/sunrpc/xprtsock.c3
31 files changed, 86 insertions, 59 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 11854845393b..a669f2d11c31 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -244,7 +244,7 @@ iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
244 sk->sk_data_ready = tcp_sw_conn->old_data_ready; 244 sk->sk_data_ready = tcp_sw_conn->old_data_ready;
245 sk->sk_state_change = tcp_sw_conn->old_state_change; 245 sk->sk_state_change = tcp_sw_conn->old_state_change;
246 sk->sk_write_space = tcp_sw_conn->old_write_space; 246 sk->sk_write_space = tcp_sw_conn->old_write_space;
247 sk->sk_no_check = 0; 247 sk->sk_no_check_tx = 0;
248 write_unlock_bh(&sk->sk_callback_lock); 248 write_unlock_bh(&sk->sk_callback_lock);
249} 249}
250 250
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 42278bbf7a88..247cfdcc4b08 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -47,7 +47,9 @@ struct udp_sock {
47#define udp_portaddr_node inet.sk.__sk_common.skc_portaddr_node 47#define udp_portaddr_node inet.sk.__sk_common.skc_portaddr_node
48 int pending; /* Any pending frames ? */ 48 int pending; /* Any pending frames ? */
49 unsigned int corkflag; /* Cork is required */ 49 unsigned int corkflag; /* Cork is required */
50 __u16 encap_type; /* Is this an Encapsulation socket? */ 50 __u8 encap_type; /* Is this an Encapsulation socket? */
51 unsigned char no_check6_tx:1,/* Send zero UDP6 checksums on TX? */
52 no_check6_rx:1;/* Allow zero UDP6 checksums on RX? */
51 /* 53 /*
52 * Following member retains the information to create a UDP header 54 * Following member retains the information to create a UDP header
53 * when the socket is uncorked. 55 * when the socket is uncorked.
@@ -76,6 +78,26 @@ static inline struct udp_sock *udp_sk(const struct sock *sk)
76 return (struct udp_sock *)sk; 78 return (struct udp_sock *)sk;
77} 79}
78 80
81static inline void udp_set_no_check6_tx(struct sock *sk, bool val)
82{
83 udp_sk(sk)->no_check6_tx = val;
84}
85
86static inline void udp_set_no_check6_rx(struct sock *sk, bool val)
87{
88 udp_sk(sk)->no_check6_rx = val;
89}
90
91static inline bool udp_get_no_check6_tx(struct sock *sk)
92{
93 return udp_sk(sk)->no_check6_tx;
94}
95
96static inline bool udp_get_no_check6_rx(struct sock *sk)
97{
98 return udp_sk(sk)->no_check6_rx;
99}
100
79#define udp_portaddr_for_each_entry(__sk, node, list) \ 101#define udp_portaddr_for_each_entry(__sk, node, list) \
80 hlist_nulls_for_each_entry(__sk, node, list, __sk_common.skc_portaddr_node) 102 hlist_nulls_for_each_entry(__sk, node, list, __sk_common.skc_portaddr_node)
81 103
diff --git a/include/net/protocol.h b/include/net/protocol.h
index a7e986b08147..d6fcc1fcdb5b 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -86,7 +86,6 @@ struct inet_protosw {
86 struct proto *prot; 86 struct proto *prot;
87 const struct proto_ops *ops; 87 const struct proto_ops *ops;
88 88
89 char no_check; /* checksum on rcv/xmit/none? */
90 unsigned char flags; /* See INET_PROTOSW_* below. */ 89 unsigned char flags; /* See INET_PROTOSW_* below. */
91}; 90};
92#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ 91#define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */
diff --git a/include/net/sock.h b/include/net/sock.h
index 21569cf456ed..07b7fcd60d80 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -243,7 +243,8 @@ struct cg_proto;
243 * @sk_sndbuf: size of send buffer in bytes 243 * @sk_sndbuf: size of send buffer in bytes
244 * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, 244 * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
245 * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings 245 * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings
246 * @sk_no_check: %SO_NO_CHECK setting, whether or not checkup packets 246 * @sk_no_check_tx: %SO_NO_CHECK setting, set checksum in TX packets
247 * @sk_no_check_rx: allow zero checksum in RX packets
247 * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) 248 * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
248 * @sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK) 249 * @sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK)
249 * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) 250 * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
@@ -371,7 +372,8 @@ struct sock {
371 struct sk_buff_head sk_write_queue; 372 struct sk_buff_head sk_write_queue;
372 kmemcheck_bitfield_begin(flags); 373 kmemcheck_bitfield_begin(flags);
373 unsigned int sk_shutdown : 2, 374 unsigned int sk_shutdown : 2,
374 sk_no_check : 2, 375 sk_no_check_tx : 1,
376 sk_no_check_rx : 1,
375 sk_userlocks : 4, 377 sk_userlocks : 4,
376 sk_protocol : 8, 378 sk_protocol : 8,
377 sk_type : 16; 379 sk_type : 16;
diff --git a/include/net/udp.h b/include/net/udp.h
index a24f0f3e107f..5eb86874bcd6 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -95,15 +95,6 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table,
95 return &table->hash2[hash & table->mask]; 95 return &table->hash2[hash & table->mask];
96} 96}
97 97
98/* Note: this must match 'valbool' in sock_setsockopt */
99#define UDP_CSUM_NOXMIT 1
100
101/* Used by SunRPC/xprt layer. */
102#define UDP_CSUM_NORCV 2
103
104/* Default, as per the RFC, is to always do csums. */
105#define UDP_CSUM_DEFAULT 0
106
107extern struct proto udp_prot; 98extern struct proto udp_prot;
108 99
109extern atomic_long_t udp_memory_allocated; 100extern atomic_long_t udp_memory_allocated;
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index 8adb68160327..21caa2631c20 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h
@@ -124,6 +124,8 @@ enum {
124 L2TP_ATTR_STATS, /* nested */ 124 L2TP_ATTR_STATS, /* nested */
125 L2TP_ATTR_IP6_SADDR, /* struct in6_addr */ 125 L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
126 L2TP_ATTR_IP6_DADDR, /* struct in6_addr */ 126 L2TP_ATTR_IP6_DADDR, /* struct in6_addr */
127 L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* u8 */
128 L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* u8 */
127 __L2TP_ATTR_MAX, 129 __L2TP_ATTR_MAX,
128}; 130};
129 131
diff --git a/include/uapi/linux/udp.h b/include/uapi/linux/udp.h
index e2bcfd75a30d..16574ea18f0c 100644
--- a/include/uapi/linux/udp.h
+++ b/include/uapi/linux/udp.h
@@ -29,6 +29,8 @@ struct udphdr {
29/* UDP socket options */ 29/* UDP socket options */
30#define UDP_CORK 1 /* Never send partially complete segments */ 30#define UDP_CORK 1 /* Never send partially complete segments */
31#define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */ 31#define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */
32#define UDP_NO_CHECK6_TX 101 /* Disable sending checksum for UDP6X */
33#define UDP_NO_CHECK6_RX 102 /* Disable accpeting checksum for UDP6 */
32 34
33/* UDP encapsulation types */ 35/* UDP encapsulation types */
34#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ 36#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 786ee2f83d5f..01a1082e02b3 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1669,7 +1669,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1669 goto out; 1669 goto out;
1670 } 1670 }
1671 1671
1672 if (sk->sk_no_check == 1) 1672 if (sk->sk_no_check_tx)
1673 ddp->deh_sum = 0; 1673 ddp->deh_sum = 0;
1674 else 1674 else
1675 ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); 1675 ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp));
diff --git a/net/core/sock.c b/net/core/sock.c
index 664ee4295b6f..026e01f70274 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -784,7 +784,7 @@ set_rcvbuf:
784 break; 784 break;
785 785
786 case SO_NO_CHECK: 786 case SO_NO_CHECK:
787 sk->sk_no_check = valbool; 787 sk->sk_no_check_tx = valbool;
788 break; 788 break;
789 789
790 case SO_PRIORITY: 790 case SO_PRIORITY:
@@ -1064,7 +1064,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
1064 break; 1064 break;
1065 1065
1066 case SO_NO_CHECK: 1066 case SO_NO_CHECK:
1067 v.val = sk->sk_no_check; 1067 v.val = sk->sk_no_check_tx;
1068 break; 1068 break;
1069 1069
1070 case SO_PRIORITY: 1070 case SO_PRIORITY:
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 22b5d818b200..6ca645c4b48e 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1024,7 +1024,6 @@ static struct inet_protosw dccp_v4_protosw = {
1024 .protocol = IPPROTO_DCCP, 1024 .protocol = IPPROTO_DCCP,
1025 .prot = &dccp_v4_prot, 1025 .prot = &dccp_v4_prot,
1026 .ops = &inet_dccp_ops, 1026 .ops = &inet_dccp_ops,
1027 .no_check = 0,
1028 .flags = INET_PROTOSW_ICSK, 1027 .flags = INET_PROTOSW_ICSK,
1029}; 1028};
1030 1029
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 4c04848953bd..ae011b46c071 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -481,7 +481,7 @@ static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gf
481 481
482 sk->sk_backlog_rcv = dn_nsp_backlog_rcv; 482 sk->sk_backlog_rcv = dn_nsp_backlog_rcv;
483 sk->sk_destruct = dn_destruct; 483 sk->sk_destruct = dn_destruct;
484 sk->sk_no_check = 1; 484 sk->sk_no_check_tx = 1;
485 sk->sk_family = PF_DECnet; 485 sk->sk_family = PF_DECnet;
486 sk->sk_protocol = 0; 486 sk->sk_protocol = 0;
487 sk->sk_allocation = gfp; 487 sk->sk_allocation = gfp;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 279132bcadd9..0e9bb08a91e4 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -254,7 +254,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
254 struct inet_sock *inet; 254 struct inet_sock *inet;
255 struct proto *answer_prot; 255 struct proto *answer_prot;
256 unsigned char answer_flags; 256 unsigned char answer_flags;
257 char answer_no_check;
258 int try_loading_module = 0; 257 int try_loading_module = 0;
259 int err; 258 int err;
260 259
@@ -312,7 +311,6 @@ lookup_protocol:
312 311
313 sock->ops = answer->ops; 312 sock->ops = answer->ops;
314 answer_prot = answer->prot; 313 answer_prot = answer->prot;
315 answer_no_check = answer->no_check;
316 answer_flags = answer->flags; 314 answer_flags = answer->flags;
317 rcu_read_unlock(); 315 rcu_read_unlock();
318 316
@@ -324,7 +322,6 @@ lookup_protocol:
324 goto out; 322 goto out;
325 323
326 err = 0; 324 err = 0;
327 sk->sk_no_check = answer_no_check;
328 if (INET_PROTOSW_REUSE & answer_flags) 325 if (INET_PROTOSW_REUSE & answer_flags)
329 sk->sk_reuse = SK_CAN_REUSE; 326 sk->sk_reuse = SK_CAN_REUSE;
330 327
@@ -1002,7 +999,6 @@ static struct inet_protosw inetsw_array[] =
1002 .protocol = IPPROTO_TCP, 999 .protocol = IPPROTO_TCP,
1003 .prot = &tcp_prot, 1000 .prot = &tcp_prot,
1004 .ops = &inet_stream_ops, 1001 .ops = &inet_stream_ops,
1005 .no_check = 0,
1006 .flags = INET_PROTOSW_PERMANENT | 1002 .flags = INET_PROTOSW_PERMANENT |
1007 INET_PROTOSW_ICSK, 1003 INET_PROTOSW_ICSK,
1008 }, 1004 },
@@ -1012,7 +1008,6 @@ static struct inet_protosw inetsw_array[] =
1012 .protocol = IPPROTO_UDP, 1008 .protocol = IPPROTO_UDP,
1013 .prot = &udp_prot, 1009 .prot = &udp_prot,
1014 .ops = &inet_dgram_ops, 1010 .ops = &inet_dgram_ops,
1015 .no_check = UDP_CSUM_DEFAULT,
1016 .flags = INET_PROTOSW_PERMANENT, 1011 .flags = INET_PROTOSW_PERMANENT,
1017 }, 1012 },
1018 1013
@@ -1021,7 +1016,6 @@ static struct inet_protosw inetsw_array[] =
1021 .protocol = IPPROTO_ICMP, 1016 .protocol = IPPROTO_ICMP,
1022 .prot = &ping_prot, 1017 .prot = &ping_prot,
1023 .ops = &inet_dgram_ops, 1018 .ops = &inet_dgram_ops,
1024 .no_check = UDP_CSUM_DEFAULT,
1025 .flags = INET_PROTOSW_REUSE, 1019 .flags = INET_PROTOSW_REUSE,
1026 }, 1020 },
1027 1021
@@ -1030,7 +1024,6 @@ static struct inet_protosw inetsw_array[] =
1030 .protocol = IPPROTO_IP, /* wild card */ 1024 .protocol = IPPROTO_IP, /* wild card */
1031 .prot = &raw_prot, 1025 .prot = &raw_prot,
1032 .ops = &inet_sockraw_ops, 1026 .ops = &inet_sockraw_ops,
1033 .no_check = UDP_CSUM_DEFAULT,
1034 .flags = INET_PROTOSW_REUSE, 1027 .flags = INET_PROTOSW_REUSE,
1035 } 1028 }
1036}; 1029};
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 590532a7bd2d..e07d52b8617a 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -785,7 +785,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
785 if (is_udplite) /* UDP-Lite */ 785 if (is_udplite) /* UDP-Lite */
786 csum = udplite_csum(skb); 786 csum = udplite_csum(skb);
787 787
788 else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */ 788 else if (sk->sk_no_check_tx) { /* UDP csum disabled */
789 789
790 skb->ip_summed = CHECKSUM_NONE; 790 skb->ip_summed = CHECKSUM_NONE;
791 goto send; 791 goto send;
@@ -1968,7 +1968,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1968 int (*push_pending_frames)(struct sock *)) 1968 int (*push_pending_frames)(struct sock *))
1969{ 1969{
1970 struct udp_sock *up = udp_sk(sk); 1970 struct udp_sock *up = udp_sk(sk);
1971 int val; 1971 int val, valbool;
1972 int err = 0; 1972 int err = 0;
1973 int is_udplite = IS_UDPLITE(sk); 1973 int is_udplite = IS_UDPLITE(sk);
1974 1974
@@ -1978,6 +1978,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1978 if (get_user(val, (int __user *)optval)) 1978 if (get_user(val, (int __user *)optval))
1979 return -EFAULT; 1979 return -EFAULT;
1980 1980
1981 valbool = val ? 1 : 0;
1982
1981 switch (optname) { 1983 switch (optname) {
1982 case UDP_CORK: 1984 case UDP_CORK:
1983 if (val != 0) { 1985 if (val != 0) {
@@ -2007,6 +2009,14 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
2007 } 2009 }
2008 break; 2010 break;
2009 2011
2012 case UDP_NO_CHECK6_TX:
2013 up->no_check6_tx = valbool;
2014 break;
2015
2016 case UDP_NO_CHECK6_RX:
2017 up->no_check6_rx = valbool;
2018 break;
2019
2010 /* 2020 /*
2011 * UDP-Lite's partial checksum coverage (RFC 3828). 2021 * UDP-Lite's partial checksum coverage (RFC 3828).
2012 */ 2022 */
@@ -2089,6 +2099,14 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
2089 val = up->encap_type; 2099 val = up->encap_type;
2090 break; 2100 break;
2091 2101
2102 case UDP_NO_CHECK6_TX:
2103 val = up->no_check6_tx;
2104 break;
2105
2106 case UDP_NO_CHECK6_RX:
2107 val = up->no_check6_rx;
2108 break;
2109
2092 /* The following two cannot be changed on UDP sockets, the return is 2110 /* The following two cannot be changed on UDP sockets, the return is
2093 * always 0 (which corresponds to the full checksum coverage of UDP). */ 2111 * always 0 (which corresponds to the full checksum coverage of UDP). */
2094 case UDPLITE_SEND_CSCOV: 2112 case UDPLITE_SEND_CSCOV:
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 2c46acd4cc36..3b3efbda48e1 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -70,7 +70,6 @@ static struct inet_protosw udplite4_protosw = {
70 .protocol = IPPROTO_UDPLITE, 70 .protocol = IPPROTO_UDPLITE,
71 .prot = &udplite_prot, 71 .prot = &udplite_prot,
72 .ops = &inet_dgram_ops, 72 .ops = &inet_dgram_ops,
73 .no_check = 0, /* must checksum (RFC 3828) */
74 .flags = INET_PROTOSW_PERMANENT, 73 .flags = INET_PROTOSW_PERMANENT,
75}; 74};
76 75
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index dc47cc757b80..7cb4392690dd 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -106,7 +106,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
106 struct inet_protosw *answer; 106 struct inet_protosw *answer;
107 struct proto *answer_prot; 107 struct proto *answer_prot;
108 unsigned char answer_flags; 108 unsigned char answer_flags;
109 char answer_no_check;
110 int try_loading_module = 0; 109 int try_loading_module = 0;
111 int err; 110 int err;
112 111
@@ -162,7 +161,6 @@ lookup_protocol:
162 161
163 sock->ops = answer->ops; 162 sock->ops = answer->ops;
164 answer_prot = answer->prot; 163 answer_prot = answer->prot;
165 answer_no_check = answer->no_check;
166 answer_flags = answer->flags; 164 answer_flags = answer->flags;
167 rcu_read_unlock(); 165 rcu_read_unlock();
168 166
@@ -176,7 +174,6 @@ lookup_protocol:
176 sock_init_data(sock, sk); 174 sock_init_data(sock, sk);
177 175
178 err = 0; 176 err = 0;
179 sk->sk_no_check = answer_no_check;
180 if (INET_PROTOSW_REUSE & answer_flags) 177 if (INET_PROTOSW_REUSE & answer_flags)
181 sk->sk_reuse = SK_CAN_REUSE; 178 sk->sk_reuse = SK_CAN_REUSE;
182 179
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index a2a1d80dfe0c..5b7a1ed2aba9 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -51,7 +51,6 @@ static struct inet_protosw pingv6_protosw = {
51 .protocol = IPPROTO_ICMPV6, 51 .protocol = IPPROTO_ICMPV6,
52 .prot = &pingv6_prot, 52 .prot = &pingv6_prot,
53 .ops = &inet6_dgram_ops, 53 .ops = &inet6_dgram_ops,
54 .no_check = UDP_CSUM_DEFAULT,
55 .flags = INET_PROTOSW_REUSE, 54 .flags = INET_PROTOSW_REUSE,
56}; 55};
57 56
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index dddfb5fa2b7a..b2dc60b0c764 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1322,7 +1322,6 @@ static struct inet_protosw rawv6_protosw = {
1322 .protocol = IPPROTO_IP, /* wild card */ 1322 .protocol = IPPROTO_IP, /* wild card */
1323 .prot = &rawv6_prot, 1323 .prot = &rawv6_prot,
1324 .ops = &inet6_sockraw_ops, 1324 .ops = &inet6_sockraw_ops,
1325 .no_check = UDP_CSUM_DEFAULT,
1326 .flags = INET_PROTOSW_REUSE, 1325 .flags = INET_PROTOSW_REUSE,
1327}; 1326};
1328 1327
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index f07b2abba359..229239ad96b1 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1992,7 +1992,6 @@ static struct inet_protosw tcpv6_protosw = {
1992 .protocol = IPPROTO_TCP, 1992 .protocol = IPPROTO_TCP,
1993 .prot = &tcpv6_prot, 1993 .prot = &tcpv6_prot,
1994 .ops = &inet6_stream_ops, 1994 .ops = &inet6_stream_ops,
1995 .no_check = 0,
1996 .flags = INET_PROTOSW_PERMANENT | 1995 .flags = INET_PROTOSW_PERMANENT |
1997 INET_PROTOSW_ICSK, 1996 INET_PROTOSW_ICSK,
1998}; 1997};
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 7edf096867c4..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) 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) { 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 == UDP_CSUM_NOXMIT) { /* 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 */
@@ -1507,7 +1507,6 @@ static struct inet_protosw udpv6_protosw = {
1507 .protocol = IPPROTO_UDP, 1507 .protocol = IPPROTO_UDP,
1508 .prot = &udpv6_prot, 1508 .prot = &udpv6_prot,
1509 .ops = &inet6_dgram_ops, 1509 .ops = &inet6_dgram_ops,
1510 .no_check = UDP_CSUM_DEFAULT,
1511 .flags = INET_PROTOSW_PERMANENT, 1510 .flags = INET_PROTOSW_PERMANENT,
1512}; 1511};
1513 1512
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index dfcc4be46898..9cf097e206e9 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -64,7 +64,6 @@ static struct inet_protosw udplite6_protosw = {
64 .protocol = IPPROTO_UDPLITE, 64 .protocol = IPPROTO_UDPLITE,
65 .prot = &udplitev6_prot, 65 .prot = &udplitev6_prot,
66 .ops = &inet6_dgram_ops, 66 .ops = &inet6_dgram_ops,
67 .no_check = 0,
68 .flags = INET_PROTOSW_PERMANENT, 67 .flags = INET_PROTOSW_PERMANENT,
69}; 68};
70 69
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 41e4e93cb3aa..91729b807c7d 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1353,7 +1353,7 @@ static int ipx_create(struct net *net, struct socket *sock, int protocol,
1353 1353
1354 sk_refcnt_debug_inc(sk); 1354 sk_refcnt_debug_inc(sk);
1355 sock_init_data(sock, sk); 1355 sock_init_data(sock, sk);
1356 sk->sk_no_check = 1; /* Checksum off by default */ 1356 sk->sk_no_check_tx = 1; /* Checksum off by default */
1357 sock->ops = &ipx_dgram_ops; 1357 sock->ops = &ipx_dgram_ops;
1358 rc = 0; 1358 rc = 0;
1359out: 1359out:
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
index c1f03185c5e1..67e7ad3d46b1 100644
--- a/net/ipx/ipx_route.c
+++ b/net/ipx/ipx_route.c
@@ -236,7 +236,8 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
236 } 236 }
237 237
238 /* Apply checksum. Not allowed on 802.3 links. */ 238 /* Apply checksum. Not allowed on 802.3 links. */
239 if (sk->sk_no_check || intrfc->if_dlink_type == htons(IPX_FRAME_8023)) 239 if (sk->sk_no_check_tx ||
240 intrfc->if_dlink_type == htons(IPX_FRAME_8023))
240 ipx->ipx_checksum = htons(0xFFFF); 241 ipx->ipx_checksum = htons(0xFFFF);
241 else 242 else
242 ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); 243 ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr));
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index ed0716a075ba..379558014b60 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1102,7 +1102,9 @@ static void l2tp_xmit_ipv6_csum(struct sock *sk, struct sk_buff *skb,
1102 struct ipv6_pinfo *np = inet6_sk(sk); 1102 struct ipv6_pinfo *np = inet6_sk(sk);
1103 struct udphdr *uh = udp_hdr(skb); 1103 struct udphdr *uh = udp_hdr(skb);
1104 1104
1105 if (!skb_dst(skb) || !skb_dst(skb)->dev || 1105 if (udp_get_no_check6_tx(sk))
1106 skb->ip_summed = CHECKSUM_NONE;
1107 else if (!skb_dst(skb) || !skb_dst(skb)->dev ||
1106 !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) { 1108 !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) {
1107 __wsum csum = skb_checksum(skb, 0, udp_len, 0); 1109 __wsum csum = skb_checksum(skb, 0, udp_len, 0);
1108 skb->ip_summed = CHECKSUM_UNNECESSARY; 1110 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1188,7 +1190,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1188 l2tp_xmit_ipv6_csum(sk, skb, udp_len); 1190 l2tp_xmit_ipv6_csum(sk, skb, udp_len);
1189 else 1191 else
1190#endif 1192#endif
1191 if (sk->sk_no_check == UDP_CSUM_NOXMIT) 1193 if (sk->sk_no_check_tx)
1192 skb->ip_summed = CHECKSUM_NONE; 1194 skb->ip_summed = CHECKSUM_NONE;
1193 else if ((skb_dst(skb) && skb_dst(skb)->dev) && 1195 else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
1194 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) { 1196 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
@@ -1435,6 +1437,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
1435 sizeof(udp6_addr), 0); 1437 sizeof(udp6_addr), 0);
1436 if (err < 0) 1438 if (err < 0)
1437 goto out; 1439 goto out;
1440
1441 if (cfg->udp6_zero_tx_checksums)
1442 udp_set_no_check6_tx(sock->sk, true);
1443 if (cfg->udp6_zero_rx_checksums)
1444 udp_set_no_check6_rx(sock->sk, true);
1438 } else 1445 } else
1439#endif 1446#endif
1440 { 1447 {
@@ -1463,7 +1470,7 @@ static int l2tp_tunnel_sock_create(struct net *net,
1463 } 1470 }
1464 1471
1465 if (!cfg->use_udp_checksums) 1472 if (!cfg->use_udp_checksums)
1466 sock->sk->sk_no_check = UDP_CSUM_NOXMIT; 1473 sock->sk->sk_no_check_tx = 1;
1467 1474
1468 break; 1475 break;
1469 1476
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 3f93ccd6ba97..68aa9ffd4ae4 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -162,7 +162,9 @@ struct l2tp_tunnel_cfg {
162#endif 162#endif
163 u16 local_udp_port; 163 u16 local_udp_port;
164 u16 peer_udp_port; 164 u16 peer_udp_port;
165 unsigned int use_udp_checksums:1; 165 unsigned int use_udp_checksums:1,
166 udp6_zero_tx_checksums:1,
167 udp6_zero_rx_checksums:1;
166}; 168};
167 169
168struct l2tp_tunnel { 170struct l2tp_tunnel {
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 3397fe6897c0..369a9822488c 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -606,7 +606,6 @@ static struct inet_protosw l2tp_ip_protosw = {
606 .protocol = IPPROTO_L2TP, 606 .protocol = IPPROTO_L2TP,
607 .prot = &l2tp_ip_prot, 607 .prot = &l2tp_ip_prot,
608 .ops = &l2tp_ip_ops, 608 .ops = &l2tp_ip_ops,
609 .no_check = 0,
610}; 609};
611 610
612static struct net_protocol l2tp_ip_protocol __read_mostly = { 611static struct net_protocol l2tp_ip_protocol __read_mostly = {
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index e472d44a3b91..f3f98a156cee 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -755,7 +755,6 @@ static struct inet_protosw l2tp_ip6_protosw = {
755 .protocol = IPPROTO_L2TP, 755 .protocol = IPPROTO_L2TP,
756 .prot = &l2tp_ip6_prot, 756 .prot = &l2tp_ip6_prot,
757 .ops = &l2tp_ip6_ops, 757 .ops = &l2tp_ip6_ops,
758 .no_check = 0,
759}; 758};
760 759
761static struct inet6_protocol l2tp_ip6_protocol __read_mostly = { 760static struct inet6_protocol l2tp_ip6_protocol __read_mostly = {
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index bd7387adea9e..0ac907adb2f4 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -161,6 +161,13 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
161 cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]); 161 cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]);
162 if (info->attrs[L2TP_ATTR_UDP_CSUM]) 162 if (info->attrs[L2TP_ATTR_UDP_CSUM])
163 cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]); 163 cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]);
164
165#if IS_ENABLED(CONFIG_IPV6)
166 if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX])
167 cfg.udp6_zero_tx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]);
168 if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX])
169 cfg.udp6_zero_rx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]);
170#endif
164 } 171 }
165 172
166 if (info->attrs[L2TP_ATTR_DEBUG]) 173 if (info->attrs[L2TP_ATTR_DEBUG])
@@ -297,8 +304,7 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
297 case L2TP_ENCAPTYPE_UDP: 304 case L2TP_ENCAPTYPE_UDP:
298 if (nla_put_u16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)) || 305 if (nla_put_u16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)) ||
299 nla_put_u16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport)) || 306 nla_put_u16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport)) ||
300 nla_put_u8(skb, L2TP_ATTR_UDP_CSUM, 307 nla_put_u8(skb, L2TP_ATTR_UDP_CSUM, !sk->sk_no_check_tx))
301 (sk->sk_no_check != UDP_CSUM_NOXMIT)))
302 goto nla_put_failure; 308 goto nla_put_failure;
303 /* NOBREAK */ 309 /* NOBREAK */
304 case L2TP_ENCAPTYPE_IP: 310 case L2TP_ENCAPTYPE_IP:
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 4dc5d9e08311..1999592ba88c 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -943,7 +943,6 @@ static struct inet_protosw sctpv6_seqpacket_protosw = {
943 .protocol = IPPROTO_SCTP, 943 .protocol = IPPROTO_SCTP,
944 .prot = &sctpv6_prot, 944 .prot = &sctpv6_prot,
945 .ops = &inet6_seqpacket_ops, 945 .ops = &inet6_seqpacket_ops,
946 .no_check = 0,
947 .flags = SCTP_PROTOSW_FLAG 946 .flags = SCTP_PROTOSW_FLAG
948}; 947};
949static struct inet_protosw sctpv6_stream_protosw = { 948static struct inet_protosw sctpv6_stream_protosw = {
@@ -951,7 +950,6 @@ static struct inet_protosw sctpv6_stream_protosw = {
951 .protocol = IPPROTO_SCTP, 950 .protocol = IPPROTO_SCTP,
952 .prot = &sctpv6_prot, 951 .prot = &sctpv6_prot,
953 .ops = &inet6_seqpacket_ops, 952 .ops = &inet6_seqpacket_ops,
954 .no_check = 0,
955 .flags = SCTP_PROTOSW_FLAG, 953 .flags = SCTP_PROTOSW_FLAG,
956}; 954};
957 955
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index af5afca4b85a..6789d785e698 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1017,7 +1017,6 @@ static struct inet_protosw sctp_seqpacket_protosw = {
1017 .protocol = IPPROTO_SCTP, 1017 .protocol = IPPROTO_SCTP,
1018 .prot = &sctp_prot, 1018 .prot = &sctp_prot,
1019 .ops = &inet_seqpacket_ops, 1019 .ops = &inet_seqpacket_ops,
1020 .no_check = 0,
1021 .flags = SCTP_PROTOSW_FLAG 1020 .flags = SCTP_PROTOSW_FLAG
1022}; 1021};
1023static struct inet_protosw sctp_stream_protosw = { 1022static struct inet_protosw sctp_stream_protosw = {
@@ -1025,7 +1024,6 @@ static struct inet_protosw sctp_stream_protosw = {
1025 .protocol = IPPROTO_SCTP, 1024 .protocol = IPPROTO_SCTP,
1026 .prot = &sctp_prot, 1025 .prot = &sctp_prot,
1027 .ops = &inet_seqpacket_ops, 1026 .ops = &inet_seqpacket_ops,
1028 .no_check = 0,
1029 .flags = SCTP_PROTOSW_FLAG 1027 .flags = SCTP_PROTOSW_FLAG
1030}; 1028};
1031 1029
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 2af76eaba8f7..429899689408 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6946,7 +6946,8 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
6946 newsk->sk_type = sk->sk_type; 6946 newsk->sk_type = sk->sk_type;
6947 newsk->sk_bound_dev_if = sk->sk_bound_dev_if; 6947 newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
6948 newsk->sk_flags = sk->sk_flags; 6948 newsk->sk_flags = sk->sk_flags;
6949 newsk->sk_no_check = sk->sk_no_check; 6949 newsk->sk_no_check_tx = sk->sk_no_check_tx;
6950 newsk->sk_no_check_rx = sk->sk_no_check_rx;
6950 newsk->sk_reuse = sk->sk_reuse; 6951 newsk->sk_reuse = sk->sk_reuse;
6951 6952
6952 newsk->sk_shutdown = sk->sk_shutdown; 6953 newsk->sk_shutdown = sk->sk_shutdown;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 25a3dcf15cae..1dec6043e4de 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -866,8 +866,6 @@ static void xs_reset_transport(struct sock_xprt *transport)
866 xs_restore_old_callbacks(transport, sk); 866 xs_restore_old_callbacks(transport, sk);
867 write_unlock_bh(&sk->sk_callback_lock); 867 write_unlock_bh(&sk->sk_callback_lock);
868 868
869 sk->sk_no_check = 0;
870
871 trace_rpc_socket_close(&transport->xprt, sock); 869 trace_rpc_socket_close(&transport->xprt, sock);
872 sock_release(sock); 870 sock_release(sock);
873} 871}
@@ -2046,7 +2044,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
2046 sk->sk_user_data = xprt; 2044 sk->sk_user_data = xprt;
2047 sk->sk_data_ready = xs_udp_data_ready; 2045 sk->sk_data_ready = xs_udp_data_ready;
2048 sk->sk_write_space = xs_udp_write_space; 2046 sk->sk_write_space = xs_udp_write_space;
2049 sk->sk_no_check = UDP_CSUM_NORCV;
2050 sk->sk_allocation = GFP_ATOMIC; 2047 sk->sk_allocation = GFP_ATOMIC;
2051 2048
2052 xprt_set_connected(xprt); 2049 xprt_set_connected(xprt);