modify for offload checksum and add macro with tcp/icmp/icmpv6/igmp checksum

Signed-off-by: daichuan <daichuan@xiaomi.com>
This commit is contained in:
daichuan 2024-04-24 11:06:52 +08:00 committed by Xiang Xiao
parent 77205b353f
commit fe01d7c462
24 changed files with 329 additions and 27 deletions

View File

@ -871,6 +871,48 @@ uint16_t net_chksum(FAR uint16_t *data, uint16_t len);
uint16_t net_chksum_iob(uint16_t sum, FAR struct iob_s *iob, uint16_t net_chksum_iob(uint16_t sum, FAR struct iob_s *iob,
uint16_t offset); uint16_t offset);
#ifdef CONFIG_NET_IPv4
/****************************************************************************
* Name: ipv4_upperlayer_header_chksum
*
* Description:
* Perform the checksum calculation over the IPv4, protocol headers,
* IP source and destination addresses
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* proto - The protocol being supported
*
* Returned Value:
* The calculated checksum with pseudo-header and IP source and
* destination addresses
*
****************************************************************************/
uint16_t ipv4_upperlayer_header_chksum(FAR struct net_driver_s *dev,
uint8_t proto);
/****************************************************************************
* Name: ipv4_upperlayer_payload_chksum
*
* Description:
* Perform the checksum calculation over the iob data payload
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* sum - The default checksum
*
* Returned Value:
* The calculated checksum with iob data payload and default checksum
*
****************************************************************************/
uint16_t ipv4_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
uint16_t sum);
/**************************************************************************** /****************************************************************************
* Name: ipv4_upperlayer_chksum * Name: ipv4_upperlayer_chksum
* *
@ -888,10 +930,57 @@ uint16_t net_chksum_iob(uint16_t sum, FAR struct iob_s *iob,
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET_IPv4
uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto); uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto);
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
/****************************************************************************
* Name: ipv6_upperlayer_header_chksum
*
* Description:
* Perform the checksum calculation over the IPv6, protocol headers,
* IP source and destination addresses.
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* proto - The protocol being supported
* iplen - The size of the IPv6 header. This may be larger than
* IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
* present.
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
uint16_t ipv6_upperlayer_header_chksum(FAR struct net_driver_s *dev,
uint8_t proto, unsigned int iplen);
/****************************************************************************
* Name: ipv6_upperlayer_payload_chksum
*
* Description:
* Perform the checksum calculation over the iob data payload and
* default checksum.
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* proto - The protocol being supported
* iplen - The size of the IPv6 header. This may be larger than
* IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
* present.
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
uint16_t ipv6_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
unsigned int iplen, uint16_t sum);
/**************************************************************************** /****************************************************************************
* Name: ipv6_upperlayer_chksum * Name: ipv6_upperlayer_chksum
* *
@ -912,7 +1001,6 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto);
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET_IPv6
uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev, uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev,
uint8_t proto, unsigned int iplen); uint8_t proto, unsigned int iplen);
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */

View File

@ -381,6 +381,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
} }
#endif #endif
#ifdef CONFIG_NET_IPV4_CHECKSUMS
if (ipv4_chksum(IPv4BUF) != 0xffff) if (ipv4_chksum(IPv4BUF) != 0xffff)
{ {
/* Compute and check the IP header checksum. */ /* Compute and check the IP header checksum. */
@ -392,6 +393,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
nwarn("WARNING: Bad IP checksum\n"); nwarn("WARNING: Bad IP checksum\n");
goto drop; goto drop;
} }
#endif
#ifdef CONFIG_NET_IPFILTER #ifdef CONFIG_NET_IPFILTER
if (ipv4_filter_in(dev) != IPFILTER_TARGET_ACCEPT) if (ipv4_filter_in(dev) != IPFILTER_TARGET_ACCEPT)

View File

@ -43,6 +43,12 @@ config NET_ICMP_SOCKET
for application level support for sending ECHO (ping) requests and for application level support for sending ECHO (ping) requests and
receiving associated ECHO replies. receiving associated ECHO replies.
config NET_ICMP_CHECKSUMS
bool "ICMP checksums"
default y
---help---
Enable/disable ICMP checksum support.
if NET_ICMP_SOCKET if NET_ICMP_SOCKET
config NET_ICMP_PREALLOC_CONNS config NET_ICMP_PREALLOC_CONNS

View File

@ -324,7 +324,7 @@ void icmp_input(FAR struct net_driver_s *dev)
/* The quick way -- Since only the type has changed, just adjust the /* The quick way -- Since only the type has changed, just adjust the
* checksum for the change of type * checksum for the change of type
*/ */
#ifdef CONFIG_NET_ICMP_CHECKSUMS
if (icmp->icmpchksum >= HTONS(0xffff - (ICMP_ECHO_REQUEST << 8))) if (icmp->icmpchksum >= HTONS(0xffff - (ICMP_ECHO_REQUEST << 8)))
{ {
icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8) + 1; icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8) + 1;
@ -333,6 +333,10 @@ void icmp_input(FAR struct net_driver_s *dev)
{ {
icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8); icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8);
} }
#else
icmp->icmpchksum = 0;
#endif
#endif #endif
ninfo("Outgoing ICMP packet length: %d (%d)\n", ninfo("Outgoing ICMP packet length: %d (%d)\n",

View File

@ -197,11 +197,13 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
/* Calculate the ICMP checksum. */ /* Calculate the ICMP checksum. */
icmp->icmpchksum = 0; icmp->icmpchksum = 0;
#ifdef CONFIG_NET_ICMP_CHECKSUMS
icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob); icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob);
if (icmp->icmpchksum == 0) if (icmp->icmpchksum == 0)
{ {
icmp->icmpchksum = 0xffff; icmp->icmpchksum = 0xffff;
} }
#endif
ninfo("Outgoing ICMP packet length: %d\n", dev->d_len); ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);
} }

View File

@ -132,11 +132,14 @@ static void sendto_request(FAR struct net_driver_s *dev,
/* Calculate the ICMP checksum. */ /* Calculate the ICMP checksum. */
icmp->icmpchksum = 0; icmp->icmpchksum = 0;
#ifdef CONFIG_NET_ICMP_CHECKSUMS
icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob); icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob);
if (icmp->icmpchksum == 0) if (icmp->icmpchksum == 0)
{ {
icmp->icmpchksum = 0xffff; icmp->icmpchksum = 0xffff;
} }
#endif
ninfo("Outgoing ICMP packet length: %d\n", dev->d_len); ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);

View File

@ -45,6 +45,12 @@ config NET_ICMPv6_SOCKET
for application level support for sending ICMPv7 ECHO requests and for application level support for sending ICMPv7 ECHO requests and
receiving associated ICMPv6 ECHO replies. receiving associated ICMPv6 ECHO replies.
config NET_ICMPv6_CHECKSUMS
bool "ICMPv6 checksums"
default y
---help---
Enable/disable ICMPv6 checksum support.
config NET_ICMPv6_NEIGHBOR config NET_ICMPv6_NEIGHBOR
bool "Solicit destination addresses" bool "Solicit destination addresses"
default n default n

View File

@ -111,8 +111,9 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
/* Calculate the checksum over both the ICMP header and payload */ /* Calculate the checksum over both the ICMP header and payload */
adv->chksum = 0; adv->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#endif
/* Set the size to the size of the IPv6 header and the payload size */ /* Set the size to the size of the IPv6 header and the payload size */
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;

View File

@ -556,7 +556,10 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
net_ipv6addr_copy(ipv6->srcipaddr, srcaddr); net_ipv6addr_copy(ipv6->srcipaddr, srcaddr);
icmpv6->chksum = 0; icmpv6->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
icmpv6->chksum = ~icmpv6_chksum(dev, iplen); icmpv6->chksum = ~icmpv6_chksum(dev, iplen);
#endif
} }
break; break;

View File

@ -309,8 +309,10 @@ skip_prefix:
/* Calculate the checksum over both the ICMP header and payload */ /* Calculate the checksum over both the ICMP header and payload */
adv->chksum = 0; adv->chksum = 0;
adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
adv->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#endif
/* Set the size to the size of the IPv6 header and the payload size */ /* Set the size to the size of the IPv6 header and the payload size */
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;

View File

@ -186,11 +186,14 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
/* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */ /* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */
icmpv6->chksum = 0; icmpv6->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
if (icmpv6->chksum == 0) if (icmpv6->chksum == 0)
{ {
icmpv6->chksum = 0xffff; icmpv6->chksum = 0xffff;
} }
#endif
ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len); ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);
} }

View File

@ -105,8 +105,10 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
/* Calculate the checksum over both the ICMP header and payload */ /* Calculate the checksum over both the ICMP header and payload */
sol->chksum = 0; sol->chksum = 0;
sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#endif
/* Set the size to the size of the IPv6 header and the payload size */ /* Set the size to the size of the IPv6 header and the payload size */
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;

View File

@ -129,11 +129,14 @@ static void sendto_request(FAR struct net_driver_s *dev,
/* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */ /* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */
icmpv6->chksum = 0; icmpv6->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN); icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
if (icmpv6->chksum == 0) if (icmpv6->chksum == 0)
{ {
icmpv6->chksum = 0xffff; icmpv6->chksum = 0xffff;
} }
#endif
ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len); ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);

View File

@ -127,8 +127,10 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
/* Calculate the checksum over both the ICMP header and payload */ /* Calculate the checksum over both the ICMP header and payload */
sol->chksum = 0; sol->chksum = 0;
sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
sol->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
#endif
/* Set the size to the size of the IPv6 header and the payload size */ /* Set the size to the size of the IPv6 header and the payload size */
dev->d_len = IPv6_HDRLEN + l3size; dev->d_len = IPv6_HDRLEN + l3size;

View File

@ -12,6 +12,12 @@ config NET_IGMP
---help--- ---help---
Enable IGMPv2 client support. Enable IGMPv2 client support.
config NET_IGMP_CHECKSUMS
bool "IGMP checksums"
default y
---help---
Enable/disable IGMP checksum support.
if NET_IGMP if NET_IGMP
endif # NET_IGMP endif # NET_IGMP

View File

@ -136,6 +136,7 @@ void igmp_input(struct net_driver_s *dev)
goto drop; goto drop;
} }
#ifdef CONFIG_NET_IGMP_CHECKSUMS
/* Calculate and check the IGMP checksum */ /* Calculate and check the IGMP checksum */
if (net_chksum((FAR uint16_t *)igmp, IGMP_HDRLEN) != 0) if (net_chksum((FAR uint16_t *)igmp, IGMP_HDRLEN) != 0)
@ -144,6 +145,7 @@ void igmp_input(struct net_driver_s *dev)
nwarn("WARNING: Checksum error\n"); nwarn("WARNING: Checksum error\n");
goto drop; goto drop;
} }
#endif
/* Find the group (or create a new one) using the incoming IP address. */ /* Find the group (or create a new one) using the incoming IP address. */

View File

@ -67,11 +67,13 @@
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_NET_IGMP_CHECKSUMS
static uint16_t igmp_chksum(FAR uint8_t *buffer, int buflen) static uint16_t igmp_chksum(FAR uint8_t *buffer, int buflen)
{ {
uint16_t sum = net_chksum((FAR uint16_t *)buffer, buflen); uint16_t sum = net_chksum((FAR uint16_t *)buffer, buflen);
return sum ? sum : 0xffff; return sum ? sum : 0xffff;
} }
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -157,7 +159,10 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
/* Calculate the IGMP checksum. */ /* Calculate the IGMP checksum. */
igmp->chksum = 0; igmp->chksum = 0;
#ifdef CONFIG_NET_IGMP_CHECKSUMS
igmp->chksum = ~igmp_chksum(&igmp->type, IGMP_HDRLEN); igmp->chksum = ~igmp_chksum(&igmp->type, IGMP_HDRLEN);
#endif
IGMP_STATINCR(g_netstats.igmp.poll_send); IGMP_STATINCR(g_netstats.igmp.poll_send);
IGMP_STATINCR(g_netstats.ipv4.sent); IGMP_STATINCR(g_netstats.ipv4.sent);

View File

@ -2,3 +2,9 @@
# For a description of the syntax of this configuration file, # For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository. # see the file kconfig-language.txt in the NuttX tools repository.
# #
config NET_IPV4_CHECKSUMS
bool "IPV4 checksums"
default y
---help---
Enable/disable IPV4 checksum support.

View File

@ -99,7 +99,10 @@ uint16_t ipv4_build_header(FAR struct ipv4_hdr_s *ipv4, uint16_t total_len,
/* Calculate IP checksum. */ /* Calculate IP checksum. */
ipv4->ipchksum = 0; ipv4->ipchksum = 0;
#ifdef CONFIG_NET_IPV4_CHECKSUMS
ipv4->ipchksum = ~ipv4_chksum(ipv4); ipv4->ipchksum = ~ipv4_chksum(ipv4);
#endif
ninfo("IPv4 Packet: ipid:%d, length: %d\n", g_ipid, total_len); ninfo("IPv4 Packet: ipid:%d, length: %d\n", g_ipid, total_len);

View File

@ -285,7 +285,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
/* Calculate the ICMPv6 checksum. */ /* Calculate the ICMPv6 checksum. */
query->chksum = 0; query->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
query->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); query->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN);
#endif
MLD_STATINCR(g_netstats.mld.query_sent); MLD_STATINCR(g_netstats.mld.query_sent);
@ -326,7 +329,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
/* Calculate the ICMPv6 checksum. */ /* Calculate the ICMPv6 checksum. */
report->chksum = 0; report->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
report->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); report->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN);
#endif
SET_MLD_LASTREPORT(group->flags); /* Remember we were the last to report */ SET_MLD_LASTREPORT(group->flags); /* Remember we were the last to report */
MLD_STATINCR(g_netstats.mld.v1report_sent); MLD_STATINCR(g_netstats.mld.v1report_sent);
@ -352,7 +358,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
/* Calculate the ICMPv6 checksum. */ /* Calculate the ICMPv6 checksum. */
report->chksum = 0; report->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
report->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); report->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN);
#endif
SET_MLD_LASTREPORT(group->flags); /* Remember we were the last to report */ SET_MLD_LASTREPORT(group->flags); /* Remember we were the last to report */
MLD_STATINCR(g_netstats.mld.v2report_sent); MLD_STATINCR(g_netstats.mld.v2report_sent);
@ -372,7 +381,10 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
/* Calculate the ICMPv6 checksum. */ /* Calculate the ICMPv6 checksum. */
done->chksum = 0; done->chksum = 0;
#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
done->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN); done->chksum = ~icmpv6_chksum(dev, MLD_HDRLEN);
#endif
MLD_STATINCR(g_netstats.mld.done_sent); MLD_STATINCR(g_netstats.mld.done_sent);
} }

View File

@ -50,6 +50,12 @@ config NET_TCPURGDATA
compiled in. Urgent data (out-of-band data) is a rarely used TCP feature compiled in. Urgent data (out-of-band data) is a rarely used TCP feature
that is very seldom would be required. that is very seldom would be required.
config NET_TCP_CHECKSUMS
bool "TCP checksums"
default y
---help---
Enable/disable TCP checksum support.
config NET_TCP_PREALLOC_CONNS config NET_TCP_PREALLOC_CONNS
int "Preallocated TCP/IP connections" int "Preallocated TCP/IP connections"
default 8 default 8

View File

@ -722,6 +722,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
tcpiplen = iplen + TCP_HDRLEN; tcpiplen = iplen + TCP_HDRLEN;
#ifdef CONFIG_NET_TCP_CHECKSUMS
/* Start of TCP input header processing code. */ /* Start of TCP input header processing code. */
if (tcp_chksum(dev) != 0xffff) if (tcp_chksum(dev) != 0xffff)
@ -735,6 +736,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
nwarn("WARNING: Bad TCP checksum\n"); nwarn("WARNING: Bad TCP checksum\n");
goto drop; goto drop;
} }
#endif
/* Demultiplex this segment. First check any active connections. */ /* Demultiplex this segment. First check any active connections. */

View File

@ -196,7 +196,11 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
/* Calculate TCP checksum. */ /* Calculate TCP checksum. */
tcp->tcpchksum = 0; tcp->tcpchksum = 0;
#ifdef CONFIG_NET_TCP_CHECKSUMS
tcp->tcpchksum = ~tcp_ipv6_chksum(dev); tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
#endif
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.sent++; g_netstats.ipv6.sent++;
#endif #endif
@ -216,7 +220,11 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
/* Calculate TCP checksum. */ /* Calculate TCP checksum. */
tcp->tcpchksum = 0; tcp->tcpchksum = 0;
#ifdef CONFIG_NET_TCP_CHECKSUMS
tcp->tcpchksum = ~tcp_ipv4_chksum(dev); tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
#endif
#ifdef CONFIG_NET_STATISTICS #ifdef CONFIG_NET_STATISTICS
g_netstats.ipv4.sent++; g_netstats.ipv4.sent++;
#endif #endif
@ -491,7 +499,10 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
conn ? conn->sconn.s_ttl : IP_TTL_DEFAULT, conn ? conn->sconn.s_ttl : IP_TTL_DEFAULT,
conn ? conn->sconn.s_tos : 0); conn ? conn->sconn.s_tos : 0);
tcp->tcpchksum = 0; tcp->tcpchksum = 0;
#ifdef CONFIG_NET_TCP_CHECKSUMS
tcp->tcpchksum = ~tcp_ipv6_chksum(dev); tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
#endif
} }
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
@ -508,7 +519,10 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
conn ? conn->sconn.s_tos : 0, NULL); conn ? conn->sconn.s_tos : 0, NULL);
tcp->tcpchksum = 0; tcp->tcpchksum = 0;
#ifdef CONFIG_NET_TCP_CHECKSUMS
tcp->tcpchksum = ~tcp_ipv4_chksum(dev); tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
#endif
} }
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
} }

View File

@ -37,26 +37,29 @@
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
#if !defined(CONFIG_NET_ARCH_CHKSUM) && \
defined(CONFIG_NET_IPv4) && defined(CONFIG_MM_IOB)
/**************************************************************************** /****************************************************************************
* Name: ipv4_upperlayer_chksum * Name: ipv4_upperlayer_header_chksum
* *
* Description: * Description:
* Perform the checksum calculation over the IPv4, protocol headers, and * Perform the checksum calculation over the IPv4, protocol headers,
* data payload as necessary. * IP source and destination addresses
* *
* Input Parameters: * Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf * dev - The network driver instance. The packet data is in the d_buf
* of the device. * of the device.
* proto - The protocol being supported * proto - The protocol being supported
* *
* Returned Value: * Returned Value:
* The calculated checksum * The calculated checksum with pseudo-header and IP source and
* destination addresses
* *
****************************************************************************/ ****************************************************************************/
#if !defined(CONFIG_NET_ARCH_CHKSUM) && \ uint16_t ipv4_upperlayer_header_chksum(FAR struct net_driver_s *dev,
defined(CONFIG_NET_IPv4) && defined(CONFIG_MM_IOB) uint8_t proto)
uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
{ {
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF; FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
uint16_t upperlen; uint16_t upperlen;
@ -83,22 +86,82 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
/* Sum IP source and destination addresses. */ /* Sum IP source and destination addresses. */
sum = chksum(sum, (FAR uint8_t *)&ipv4->srcipaddr, 2 * sizeof(in_addr_t)); return chksum(sum, (FAR uint8_t *)&ipv4->srcipaddr, 2 * sizeof(in_addr_t));
}
/****************************************************************************
* Name: ipv4_upperlayer_payload_chksum
*
* Description:
* Perform the checksum calculation over the iob data payload
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* sum - The default checksum
*
* Returned Value:
* The calculated checksum with iob data payload and default checksum
*
****************************************************************************/
uint16_t ipv4_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
uint16_t sum)
{
FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
uint16_t iphdrlen;
/* Get the IP header length (accounting for possible options). */
iphdrlen = (ipv4->vhl & IPv4_HLMASK) << 2;
/* Sum IP payload data. */ /* Sum IP payload data. */
sum = chksum_iob(sum, dev->d_iob, iphdrlen); return chksum_iob(sum, dev->d_iob, iphdrlen);
}
/****************************************************************************
* Name: ipv4_upperlayer_chksum
*
* Description:
* Perform the checksum calculation over the IPv4, protocol headers, and
* data payload as necessary.
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* proto - The protocol being supported
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
{
uint16_t sum;
/* Sum pseudo-header IP source and destination addresses. */
sum = ipv4_upperlayer_header_chksum(dev, proto);
/* Sum IP payload data. */
sum = ipv4_upperlayer_payload_chksum(dev, sum);
return (sum == 0) ? 0xffff : HTONS(sum); return (sum == 0) ? 0xffff : HTONS(sum);
} }
#endif /* CONFIG_NET_ARCH_CHKSUM */ #endif /* CONFIG_NET_ARCH_CHKSUM */
#if !defined(CONFIG_NET_ARCH_CHKSUM) && \
defined(CONFIG_NET_IPv6) && defined(CONFIG_MM_IOB)
/**************************************************************************** /****************************************************************************
* Name: ipv6_upperlayer_chksum * Name: ipv6_upperlayer_header_chksum
* *
* Description: * Description:
* Perform the checksum calculation over the IPv6, protocol headers, and * Perform the checksum calculation over the IPv6, protocol headers,
* data payload as necessary. * IP source and destination addresses.
* *
* Input Parameters: * Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf * dev - The network driver instance. The packet data is in the d_buf
@ -113,10 +176,8 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto)
* *
****************************************************************************/ ****************************************************************************/
#if !defined(CONFIG_NET_ARCH_CHKSUM) && \ uint16_t ipv6_upperlayer_header_chksum(FAR struct net_driver_s *dev,
defined(CONFIG_NET_IPv6) && defined(CONFIG_MM_IOB) uint8_t proto, unsigned int iplen)
uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev,
uint8_t proto, unsigned int iplen)
{ {
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF; FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
uint16_t upperlen; uint16_t upperlen;
@ -144,12 +205,70 @@ uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev,
/* Sum IP source and destination addresses. */ /* Sum IP source and destination addresses. */
sum = chksum(sum, (FAR uint8_t *)&ipv6->srcipaddr, return chksum(sum, (FAR uint8_t *)&ipv6->srcipaddr,
2 * sizeof(net_ipv6addr_t)); 2 * sizeof(net_ipv6addr_t));
}
/****************************************************************************
* Name: ipv6_upperlayer_payload_chksum
*
* Description:
* Perform the checksum calculation over the IPv6, protocol headers,
* IP source and destination addresses.
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* proto - The protocol being supported
* iplen - The size of the IPv6 header. This may be larger than
* IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
* present.
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
uint16_t ipv6_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
unsigned int iplen, uint16_t sum)
{
/* Sum IP payload data. */
return chksum_iob(sum, dev->d_iob, iplen);
}
/****************************************************************************
* Name: ipv6_upperlayer_chksum
*
* Description:
* Perform the checksum calculation over the IPv6, protocol headers, and
* data payload as necessary.
*
* Input Parameters:
* dev - The network driver instance. The packet data is in the d_buf
* of the device.
* proto - The protocol being supported
* iplen - The size of the IPv6 header. This may be larger than
* IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
* present.
*
* Returned Value:
* The calculated checksum
*
****************************************************************************/
uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev,
uint8_t proto, unsigned int iplen)
{
uint16_t sum;
/* Sum IP source and destination addresses. */
sum = ipv6_upperlayer_header_chksum(dev, proto, iplen);
/* Sum IP payload data. */ /* Sum IP payload data. */
sum = chksum_iob(sum, dev->d_iob, iplen); sum = ipv6_upperlayer_payload_chksum(dev, iplen, sum);
return (sum == 0) ? 0xffff : HTONS(sum); return (sum == 0) ? 0xffff : HTONS(sum);
} }