net: ip: Add option to force checksum calculation

Modify internal L4 protocols APIs, to allow to enforce checksum
calculation, regardless of the checksum HW offloading capability.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2023-10-12 15:49:00 +02:00 committed by Fabio Baltieri
parent eadd933607
commit 08879ea7fb
13 changed files with 28 additions and 26 deletions

View file

@ -47,7 +47,7 @@ int net_icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code)
return net_pkt_set_data(pkt, &icmpv4_access);
}
int net_icmpv4_finalize(struct net_pkt *pkt)
int net_icmpv4_finalize(struct net_pkt *pkt, bool force_chksum)
{
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmpv4_access,
struct net_icmp_hdr);
@ -65,7 +65,7 @@ int net_icmpv4_finalize(struct net_pkt *pkt)
}
icmp_hdr->chksum = 0U;
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) {
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) {
icmp_hdr->chksum = net_calc_chksum_icmpv4(pkt);
net_pkt_set_chksum_done(pkt, true);
}

View file

@ -48,7 +48,7 @@ enum net_verdict net_icmpv4_input(struct net_pkt *pkt,
struct net_ipv4_hdr *ip_hdr);
int net_icmpv4_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code);
int net_icmpv4_finalize(struct net_pkt *pkt);
int net_icmpv4_finalize(struct net_pkt *pkt, bool force_chksum);
void net_icmpv4_init(void);
#else

View file

@ -57,7 +57,7 @@ const char *net_icmpv6_type2str(int icmpv6_type)
return "?";
}
int net_icmpv6_finalize(struct net_pkt *pkt)
int net_icmpv6_finalize(struct net_pkt *pkt, bool force_chksum)
{
NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(icmp_access,
struct net_icmp_hdr);
@ -69,7 +69,7 @@ int net_icmpv6_finalize(struct net_pkt *pkt)
}
icmp_hdr->chksum = 0U;
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) {
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) {
icmp_hdr->chksum = net_calc_chksum_icmpv6(pkt);
net_pkt_set_chksum_done(pkt, true);
}

View file

@ -188,7 +188,7 @@ enum net_verdict net_icmpv6_input(struct net_pkt *pkt,
struct net_ipv6_hdr *ip_hdr);
int net_icmpv6_create(struct net_pkt *pkt, uint8_t icmp_type, uint8_t icmp_code);
int net_icmpv6_finalize(struct net_pkt *pkt);
int net_icmpv6_finalize(struct net_pkt *pkt, bool force_chksum);
void net_icmpv6_init(void);
#else

View file

@ -118,12 +118,12 @@ int net_ipv4_finalize(struct net_pkt *pkt, uint8_t next_header_proto)
if (IS_ENABLED(CONFIG_NET_UDP) &&
next_header_proto == IPPROTO_UDP) {
return net_udp_finalize(pkt);
return net_udp_finalize(pkt, false);
} else if (IS_ENABLED(CONFIG_NET_TCP) &&
next_header_proto == IPPROTO_TCP) {
return net_tcp_finalize(pkt);
return net_tcp_finalize(pkt, false);
} else if (next_header_proto == IPPROTO_ICMP) {
return net_icmpv4_finalize(pkt);
return net_icmpv4_finalize(pkt, false);
}
return 0;

View file

@ -120,12 +120,12 @@ int net_ipv6_finalize(struct net_pkt *pkt, uint8_t next_header_proto)
if (IS_ENABLED(CONFIG_NET_UDP) &&
next_header_proto == IPPROTO_UDP) {
return net_udp_finalize(pkt);
return net_udp_finalize(pkt, false);
} else if (IS_ENABLED(CONFIG_NET_TCP) &&
next_header_proto == IPPROTO_TCP) {
return net_tcp_finalize(pkt);
return net_tcp_finalize(pkt, false);
} else if (next_header_proto == IPPROTO_ICMPV6) {
return net_icmpv6_finalize(pkt);
return net_icmpv6_finalize(pkt, false);
}
return 0;

View file

@ -3583,7 +3583,7 @@ int net_tcp_recv(struct net_context *context, net_context_recv_cb_t cb,
return 0;
}
int net_tcp_finalize(struct net_pkt *pkt)
int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum)
{
NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct net_tcp_hdr);
struct net_tcp_hdr *tcp_hdr;
@ -3595,7 +3595,7 @@ int net_tcp_finalize(struct net_pkt *pkt)
tcp_hdr->chksum = 0U;
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) {
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) {
tcp_hdr->chksum = net_calc_chksum_tcp(pkt);
net_pkt_set_chksum_done(pkt, true);
}

View file

@ -113,7 +113,7 @@ void net_tcp_init(void);
#endif
int net_tcp_update_recv_wnd(struct net_context *context, int32_t delta);
int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt);
int net_tcp_finalize(struct net_pkt *pkt);
int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum);
#if defined(CONFIG_NET_TEST_PROTOCOL)
/**

View file

@ -249,11 +249,12 @@ static inline int net_tcp_recv(struct net_context *context,
* @return 0 on success, negative errno otherwise.
*/
#if defined(CONFIG_NET_NATIVE_TCP)
int net_tcp_finalize(struct net_pkt *pkt);
int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum);
#else
static inline int net_tcp_finalize(struct net_pkt *pkt)
static inline int net_tcp_finalize(struct net_pkt *pkt, bool force_chksum)
{
ARG_UNUSED(pkt);
ARG_UNUSED(force_chksum);
return 0;
}
#endif

View file

@ -35,7 +35,7 @@ int net_udp_create(struct net_pkt *pkt, uint16_t src_port, uint16_t dst_port)
return net_pkt_set_data(pkt, &udp_access);
}
int net_udp_finalize(struct net_pkt *pkt)
int net_udp_finalize(struct net_pkt *pkt, bool force_chksum)
{
NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
struct net_udp_hdr *udp_hdr;
@ -51,7 +51,7 @@ int net_udp_finalize(struct net_pkt *pkt)
udp_hdr->len = htons(length);
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) {
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt)) || force_chksum) {
udp_hdr->chksum = net_calc_chksum_udp(pkt);
net_pkt_set_chksum_done(pkt, true);
}

View file

@ -63,11 +63,12 @@ static inline int net_udp_create(struct net_pkt *pkt,
* @return 0 on success, negative errno otherwise.
*/
#if defined(CONFIG_NET_NATIVE_UDP)
int net_udp_finalize(struct net_pkt *pkt);
int net_udp_finalize(struct net_pkt *pkt, bool force_chksum);
#else
static inline int net_udp_finalize(struct net_pkt *pkt)
static inline int net_udp_finalize(struct net_pkt *pkt, bool force_chksum)
{
ARG_UNUSED(pkt);
ARG_UNUSED(force_chksum);
return 0;
}

View file

@ -636,7 +636,7 @@ ZTEST(net_ipv4_fragment, test_udp)
net_pkt_cursor_init(pkt);
net_pkt_set_overwrite(pkt, true);
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt));
net_udp_finalize(pkt);
net_udp_finalize(pkt, false);
pkt_recv_expected_size = net_pkt_get_len(pkt);
@ -706,7 +706,7 @@ ZTEST(net_ipv4_fragment, test_tcp)
net_pkt_set_overwrite(pkt, true);
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt));
net_tcp_finalize(pkt);
net_tcp_finalize(pkt, false);
pkt_recv_expected_size = net_pkt_get_len(pkt);
@ -849,7 +849,7 @@ ZTEST(net_ipv4_fragment, test_do_not_fragment)
net_pkt_cursor_init(pkt);
net_pkt_set_overwrite(pkt, true);
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt));
net_udp_finalize(pkt);
net_udp_finalize(pkt, false);
pkt_recv_expected_size = net_pkt_get_len(pkt);

View file

@ -2015,7 +2015,7 @@ ZTEST(net_ipv6_fragment, test_send_ipv6_fragment)
net_pkt_set_overwrite(pkt, true);
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt));
net_udp_finalize(pkt);
net_udp_finalize(pkt, false);
test_failed = false;
test_complete = false;
@ -2175,7 +2175,7 @@ ZTEST(net_ipv6_fragment, test_send_ipv6_fragment_udp_loopback)
net_pkt_set_overwrite(pkt, true);
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) + net_pkt_ipv6_ext_len(pkt));
net_udp_finalize(pkt);
net_udp_finalize(pkt, false);
test_failed = false;
test_complete = false;