summaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@google.com>2026-03-11 05:19:55 +0000
committerJakub Kicinski <kuba@kernel.org>2026-03-13 18:57:45 -0700
commitb2a1d719be4f8e9d970038ecd4db983f6e42d377 (patch)
tree2215358a1e83da4a55241a1d416953a1f573d06d /net/ipv4
parentc2539d4f2df7a9889b71bad97b97ddfd9e47add1 (diff)
udp: Remove partial csum code in TX.
UDP TX paths also have some code for UDP-Lite partial checksum: * udplite_csum() in udp_send_skb() and udp_v6_send_skb() * udplite_getfrag() in udp_sendmsg() and udpv6_sendmsg() Let's remove such code. Now, we can use IPPROTO_UDP directly instead of sk->sk_protocol or fl6->flowi6_proto for csum_tcpudp_magic() and csum_ipv6_magic(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260311052020.1213705-9-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/udp.c58
1 files changed, 22 insertions, 36 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d42fb9330c22..9a2c8ff96e83 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1120,20 +1120,19 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
struct inet_cork *cork)
{
struct sock *sk = skb->sk;
- struct inet_sock *inet = inet_sk(sk);
+ int offset, len, datalen;
struct udphdr *uh;
int err;
- int is_udplite = IS_UDPLITE(sk);
- int offset = skb_transport_offset(skb);
- int len = skb->len - offset;
- int datalen = len - sizeof(*uh);
- __wsum csum = 0;
+
+ offset = skb_transport_offset(skb);
+ len = skb->len - offset;
+ datalen = len - sizeof(*uh);
/*
* Create a UDP header
*/
uh = udp_hdr(skb);
- uh->source = inet->inet_sport;
+ uh->source = inet_sk(sk)->inet_sport;
uh->dest = fl4->fl4_dport;
uh->len = htons(len);
uh->check = 0;
@@ -1154,7 +1153,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
kfree_skb(skb);
return -EINVAL;
}
- if (is_udplite || dst_xfrm(skb_dst(skb))) {
+ if (dst_xfrm(skb_dst(skb))) {
kfree_skb(skb);
return -EIO;
}
@@ -1170,26 +1169,18 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
}
}
- if (is_udplite) /* UDP-Lite */
- csum = udplite_csum(skb);
-
- else if (sk->sk_no_check_tx) { /* UDP csum off */
-
+ if (sk->sk_no_check_tx) { /* UDP csum off */
skb->ip_summed = CHECKSUM_NONE;
goto send;
-
} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
csum_partial:
-
udp4_hwcsum(skb, fl4->saddr, fl4->daddr);
goto send;
-
- } else
- csum = udp_csum(skb);
+ }
/* add protocol-dependent pseudo-header */
uh->check = csum_tcpudp_magic(fl4->saddr, fl4->daddr, len,
- sk->sk_protocol, csum);
+ IPPROTO_UDP, udp_csum(skb));
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
@@ -1270,26 +1261,23 @@ EXPORT_IPV6_MOD_GPL(udp_cmsg_send);
int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
+ int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE;
DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data,
IP_OPTIONS_DATA_FIXED_SIZE);
+ DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
+ int ulen = len, free = 0, connected = 0;
struct inet_sock *inet = inet_sk(sk);
struct udp_sock *up = udp_sk(sk);
- DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
+ __be32 daddr, faddr, saddr;
+ struct rtable *rt = NULL;
struct flowi4 fl4_stack;
- struct flowi4 *fl4;
- int ulen = len;
struct ipcm_cookie ipc;
- struct rtable *rt = NULL;
- int free = 0;
- int connected = 0;
- __be32 daddr, faddr, saddr;
- u8 scope;
- __be16 dport;
- int err, is_udplite = IS_UDPLITE(sk);
- int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE;
- int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
struct sk_buff *skb;
+ struct flowi4 *fl4;
+ __be16 dport;
int uc_index;
+ u8 scope;
+ int err;
if (len > 0xFFFF)
return -EMSGSIZE;
@@ -1301,8 +1289,6 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
return -EOPNOTSUPP;
- getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
-
fl4 = &inet->cork.fl.u.ip4;
if (READ_ONCE(up->pending)) {
/*
@@ -1444,7 +1430,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
flowi4_init_output(fl4, ipc.oif, ipc.sockc.mark,
ipc.tos & INET_DSCP_MASK, scope,
- sk->sk_protocol, flow_flags, faddr, saddr,
+ IPPROTO_UDP, flow_flags, faddr, saddr,
dport, inet->inet_sport,
sk_uid(sk));
@@ -1478,7 +1464,7 @@ back_from_confirm:
if (!corkreq) {
struct inet_cork cork;
- skb = ip_make_skb(sk, fl4, getfrag, msg, ulen,
+ skb = ip_make_skb(sk, fl4, ip_generic_getfrag, msg, ulen,
sizeof(struct udphdr), &ipc, &rt,
&cork, msg->msg_flags);
err = PTR_ERR(skb);
@@ -1509,7 +1495,7 @@ back_from_confirm:
do_append_data:
up->len += ulen;
- err = ip_append_data(sk, fl4, getfrag, msg, ulen,
+ err = ip_append_data(sk, fl4, ip_generic_getfrag, msg, ulen,
sizeof(struct udphdr), &ipc, &rt,
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
if (err)