Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
b2a1d719 c2539d4f

+49 -102
-35
include/net/udplite.h
··· 12 12 #define UDPLITE_SEND_CSCOV 10 /* sender partial coverage (as sent) */ 13 13 #define UDPLITE_RECV_CSCOV 11 /* receiver partial coverage (threshold ) */ 14 14 15 - /* 16 - * Checksum computation is all in software, hence simpler getfrag. 17 - */ 18 - static __inline__ int udplite_getfrag(void *from, char *to, int offset, 19 - int len, int odd, struct sk_buff *skb) 20 - { 21 - struct msghdr *msg = from; 22 - return copy_from_iter_full(to, len, &msg->msg_iter) ? 0 : -EFAULT; 23 - } 24 - 25 - /* 26 - * Checksumming routines 27 - */ 28 - 29 - /* Fast-path computation of checksum. Socket may not be locked. */ 30 - static inline __wsum udplite_csum(struct sk_buff *skb) 31 - { 32 - const int off = skb_transport_offset(skb); 33 - const struct sock *sk = skb->sk; 34 - int len = skb->len - off; 35 - 36 - if (udp_test_bit(UDPLITE_SEND_CC, sk)) { 37 - u16 pcslen = READ_ONCE(udp_sk(sk)->pcslen); 38 - 39 - if (pcslen < len) { 40 - if (pcslen > 0) 41 - len = pcslen; 42 - udp_hdr(skb)->len = htons(pcslen); 43 - } 44 - } 45 - skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */ 46 - 47 - return skb_checksum(skb, off, len, 0); 48 - } 49 - 50 15 #endif /* _UDPLITE_H */
+23 -37
net/ipv4/udp.c
··· 1120 1120 struct inet_cork *cork) 1121 1121 { 1122 1122 struct sock *sk = skb->sk; 1123 - struct inet_sock *inet = inet_sk(sk); 1123 + int offset, len, datalen; 1124 1124 struct udphdr *uh; 1125 1125 int err; 1126 - int is_udplite = IS_UDPLITE(sk); 1127 - int offset = skb_transport_offset(skb); 1128 - int len = skb->len - offset; 1129 - int datalen = len - sizeof(*uh); 1130 - __wsum csum = 0; 1126 + 1127 + offset = skb_transport_offset(skb); 1128 + len = skb->len - offset; 1129 + datalen = len - sizeof(*uh); 1131 1130 1132 1131 /* 1133 1132 * Create a UDP header 1134 1133 */ 1135 1134 uh = udp_hdr(skb); 1136 - uh->source = inet->inet_sport; 1135 + uh->source = inet_sk(sk)->inet_sport; 1137 1136 uh->dest = fl4->fl4_dport; 1138 1137 uh->len = htons(len); 1139 1138 uh->check = 0; ··· 1153 1154 kfree_skb(skb); 1154 1155 return -EINVAL; 1155 1156 } 1156 - if (is_udplite || dst_xfrm(skb_dst(skb))) { 1157 + if (dst_xfrm(skb_dst(skb))) { 1157 1158 kfree_skb(skb); 1158 1159 return -EIO; 1159 1160 } ··· 1169 1170 } 1170 1171 } 1171 1172 1172 - if (is_udplite) /* UDP-Lite */ 1173 - csum = udplite_csum(skb); 1174 - 1175 - else if (sk->sk_no_check_tx) { /* UDP csum off */ 1176 - 1173 + if (sk->sk_no_check_tx) { /* UDP csum off */ 1177 1174 skb->ip_summed = CHECKSUM_NONE; 1178 1175 goto send; 1179 - 1180 1176 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ 1181 1177 csum_partial: 1182 - 1183 1178 udp4_hwcsum(skb, fl4->saddr, fl4->daddr); 1184 1179 goto send; 1185 - 1186 - } else 1187 - csum = udp_csum(skb); 1180 + } 1188 1181 1189 1182 /* add protocol-dependent pseudo-header */ 1190 1183 uh->check = csum_tcpudp_magic(fl4->saddr, fl4->daddr, len, 1191 - sk->sk_protocol, csum); 1184 + IPPROTO_UDP, udp_csum(skb)); 1192 1185 if (uh->check == 0) 1193 1186 uh->check = CSUM_MANGLED_0; 1194 1187 ··· 1261 1270 1262 1271 int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) 1263 1272 { 1273 + int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; 1264 1274 DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data, 1265 1275 IP_OPTIONS_DATA_FIXED_SIZE); 1276 + DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); 1277 + int ulen = len, free = 0, connected = 0; 1266 1278 struct inet_sock *inet = inet_sk(sk); 1267 1279 struct udp_sock *up = udp_sk(sk); 1268 - DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); 1269 - struct flowi4 fl4_stack; 1270 - struct flowi4 *fl4; 1271 - int ulen = len; 1272 - struct ipcm_cookie ipc; 1273 - struct rtable *rt = NULL; 1274 - int free = 0; 1275 - int connected = 0; 1276 1280 __be32 daddr, faddr, saddr; 1277 - u8 scope; 1278 - __be16 dport; 1279 - int err, is_udplite = IS_UDPLITE(sk); 1280 - int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; 1281 - int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); 1281 + struct rtable *rt = NULL; 1282 + struct flowi4 fl4_stack; 1283 + struct ipcm_cookie ipc; 1282 1284 struct sk_buff *skb; 1285 + struct flowi4 *fl4; 1286 + __be16 dport; 1283 1287 int uc_index; 1288 + u8 scope; 1289 + int err; 1284 1290 1285 1291 if (len > 0xFFFF) 1286 1292 return -EMSGSIZE; ··· 1288 1300 1289 1301 if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ 1290 1302 return -EOPNOTSUPP; 1291 - 1292 - getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; 1293 1303 1294 1304 fl4 = &inet->cork.fl.u.ip4; 1295 1305 if (READ_ONCE(up->pending)) { ··· 1430 1444 1431 1445 flowi4_init_output(fl4, ipc.oif, ipc.sockc.mark, 1432 1446 ipc.tos & INET_DSCP_MASK, scope, 1433 - sk->sk_protocol, flow_flags, faddr, saddr, 1447 + IPPROTO_UDP, flow_flags, faddr, saddr, 1434 1448 dport, inet->inet_sport, 1435 1449 sk_uid(sk)); 1436 1450 ··· 1464 1478 if (!corkreq) { 1465 1479 struct inet_cork cork; 1466 1480 1467 - skb = ip_make_skb(sk, fl4, getfrag, msg, ulen, 1481 + skb = ip_make_skb(sk, fl4, ip_generic_getfrag, msg, ulen, 1468 1482 sizeof(struct udphdr), &ipc, &rt, 1469 1483 &cork, msg->msg_flags); 1470 1484 err = PTR_ERR(skb); ··· 1495 1509 1496 1510 do_append_data: 1497 1511 up->len += ulen; 1498 - err = ip_append_data(sk, fl4, getfrag, msg, ulen, 1512 + err = ip_append_data(sk, fl4, ip_generic_getfrag, msg, ulen, 1499 1513 sizeof(struct udphdr), &ipc, &rt, 1500 1514 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 1501 1515 if (err)
+26 -30
net/ipv6/udp.c
··· 1370 1370 struct inet_cork *cork) 1371 1371 { 1372 1372 struct sock *sk = skb->sk; 1373 + int offset, len, datalen; 1373 1374 struct udphdr *uh; 1374 1375 int err = 0; 1375 - int is_udplite = IS_UDPLITE(sk); 1376 - __wsum csum = 0; 1377 - int offset = skb_transport_offset(skb); 1378 - int len = skb->len - offset; 1379 - int datalen = len - sizeof(*uh); 1376 + 1377 + offset = skb_transport_offset(skb); 1378 + len = skb->len - offset; 1379 + datalen = len - sizeof(*uh); 1380 1380 1381 1381 /* 1382 1382 * Create a UDP header ··· 1403 1403 kfree_skb(skb); 1404 1404 return -EINVAL; 1405 1405 } 1406 - if (is_udplite || dst_xfrm(skb_dst(skb))) { 1406 + if (dst_xfrm(skb_dst(skb))) { 1407 1407 kfree_skb(skb); 1408 1408 return -EIO; 1409 1409 } ··· 1419 1419 } 1420 1420 } 1421 1421 1422 - if (is_udplite) 1423 - csum = udplite_csum(skb); 1424 - else if (udp_get_no_check6_tx(sk)) { /* UDP csum disabled */ 1422 + if (udp_get_no_check6_tx(sk)) { /* UDP csum disabled */ 1425 1423 skb->ip_summed = CHECKSUM_NONE; 1426 1424 goto send; 1427 1425 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ 1428 1426 csum_partial: 1429 1427 udp6_hwcsum_outgoing(sk, skb, &fl6->saddr, &fl6->daddr, len); 1430 1428 goto send; 1431 - } else 1432 - csum = udp_csum(skb); 1429 + } 1433 1430 1434 1431 /* add protocol-dependent pseudo-header */ 1435 1432 uh->check = csum_ipv6_magic(&fl6->saddr, &fl6->daddr, 1436 - len, fl6->flowi6_proto, csum); 1433 + len, IPPROTO_UDP, udp_csum(skb)); 1437 1434 if (uh->check == 0) 1438 1435 uh->check = CSUM_MANGLED_0; 1439 1436 ··· 1470 1473 1471 1474 int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) 1472 1475 { 1473 - struct ipv6_txoptions opt_space; 1474 - struct udp_sock *up = udp_sk(sk); 1476 + int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; 1477 + DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); 1478 + struct ipv6_txoptions *opt_to_free = NULL; 1479 + struct in6_addr *daddr, *final_p, final; 1480 + struct ip6_flowlabel *flowlabel = NULL; 1475 1481 struct inet_sock *inet = inet_sk(sk); 1476 1482 struct ipv6_pinfo *np = inet6_sk(sk); 1477 - DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); 1478 - struct in6_addr *daddr, *final_p, final; 1479 1483 struct ipv6_txoptions *opt = NULL; 1480 - struct ipv6_txoptions *opt_to_free = NULL; 1481 - struct ip6_flowlabel *flowlabel = NULL; 1482 - struct inet_cork_full cork; 1483 - struct flowi6 *fl6 = &cork.fl.u.ip6; 1484 - struct dst_entry *dst; 1485 - struct ipcm6_cookie ipc6; 1484 + struct udp_sock *up = udp_sk(sk); 1485 + struct ipv6_txoptions opt_space; 1486 1486 int addr_len = msg->msg_namelen; 1487 + struct inet_cork_full cork; 1488 + struct ipcm6_cookie ipc6; 1487 1489 bool connected = false; 1490 + struct dst_entry *dst; 1491 + struct flowi6 *fl6; 1488 1492 int ulen = len; 1489 - int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE; 1490 1493 int err; 1491 - int is_udplite = IS_UDPLITE(sk); 1492 - int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); 1493 1494 1495 + fl6 = &cork.fl.u.ip6; 1494 1496 ipcm6_init_sk(&ipc6, sk); 1495 1497 ipc6.gso_size = READ_ONCE(up->gso_size); 1496 1498 ··· 1548 1552 if (len > INT_MAX - sizeof(struct udphdr)) 1549 1553 return -EMSGSIZE; 1550 1554 1551 - getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; 1552 1555 if (READ_ONCE(up->pending)) { 1553 1556 if (READ_ONCE(up->pending) == AF_INET) 1554 1557 return udp_sendmsg(sk, msg, len); ··· 1649 1654 opt = ipv6_fixup_options(&opt_space, opt); 1650 1655 ipc6.opt = opt; 1651 1656 1652 - fl6->flowi6_proto = sk->sk_protocol; 1657 + fl6->flowi6_proto = IPPROTO_UDP; 1653 1658 fl6->flowi6_mark = ipc6.sockc.mark; 1654 1659 fl6->daddr = *daddr; 1655 1660 if (ipv6_addr_any(&fl6->saddr) && !ipv6_addr_any(&np->saddr)) ··· 1716 1721 if (!corkreq) { 1717 1722 struct sk_buff *skb; 1718 1723 1719 - skb = ip6_make_skb(sk, getfrag, msg, ulen, 1724 + skb = ip6_make_skb(sk, ip_generic_getfrag, msg, ulen, 1720 1725 sizeof(struct udphdr), &ipc6, 1721 1726 dst_rt6_info(dst), 1722 1727 msg->msg_flags, &cork); ··· 1742 1747 1743 1748 do_append_data: 1744 1749 up->len += ulen; 1745 - err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr), 1746 - &ipc6, fl6, dst_rt6_info(dst), 1750 + err = ip6_append_data(sk, ip_generic_getfrag, msg, ulen, 1751 + sizeof(struct udphdr), &ipc6, fl6, 1752 + dst_rt6_info(dst), 1747 1753 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 1748 1754 if (err) 1749 1755 udp_v6_flush_pending_frames(sk);