net: ipv4: Calculate checksum before fragmentation

In case the stack has to fragment the IPv4 packet, calculate the
checksum before fragmentation (if haven't done so).

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2023-10-12 18:18:11 +02:00 committed by Fabio Baltieri
parent 08879ea7fb
commit 887a3a321d

View File

@ -480,9 +480,9 @@ static int send_ipv4_fragment(struct net_pkt *pkt, uint16_t rand_id, uint16_t fi
ipv4_hdr->len = htons((fit_len + net_pkt_ip_hdr_len(pkt)));
ipv4_hdr->chksum = 0;
if (net_if_need_calc_tx_checksum(net_pkt_iface(frag_pkt))) {
ipv4_hdr->chksum = net_calc_chksum_ipv4(frag_pkt);
}
ipv4_hdr->chksum = net_calc_chksum_ipv4(frag_pkt);
net_pkt_set_chksum_done(frag_pkt, true);
net_pkt_set_data(frag_pkt, &ipv4_access);
@ -554,6 +554,35 @@ int net_ipv4_send_fragmented_pkt(struct net_if *iface, struct net_pkt *pkt,
pkt_len -= net_pkt_ip_hdr_len(pkt);
/* Calculate the L4 checksum (if not done already) before the fragmentation. */
if (!net_pkt_is_chksum_done(pkt)) {
struct net_pkt_cursor backup;
net_pkt_cursor_backup(pkt, &backup);
net_pkt_acknowledge_data(pkt, &frag_access);
switch (frag_hdr->proto) {
case IPPROTO_ICMP:
ret = net_icmpv4_finalize(pkt, true);
break;
case IPPROTO_TCP:
ret = net_tcp_finalize(pkt, true);
break;
case IPPROTO_UDP:
ret = net_udp_finalize(pkt, true);
break;
default:
ret = 0;
break;
}
if (ret < 0) {
return ret;
}
net_pkt_cursor_restore(pkt, &backup);
}
while (frag_offset < pkt_len) {
bool final = false;