Skip to content

Commit

Permalink
modify for offload checksum and add macro with tcp/icmp/icmpv6/igmp c…
Browse files Browse the repository at this point in the history
…hecksum

Signed-off-by: daichuan <[email protected]>
  • Loading branch information
13627105546 authored and xiaoxiang781216 committed Aug 24, 2024
1 parent 77205b3 commit fe01d7c
Show file tree
Hide file tree
Showing 24 changed files with 329 additions and 27 deletions.
92 changes: 90 additions & 2 deletions include/nuttx/net/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 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
*
Expand All @@ -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);
#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
*
Expand All @@ -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,
uint8_t proto, unsigned int iplen);
#endif /* CONFIG_NET_IPv6 */
Expand Down
2 changes: 2 additions & 0 deletions net/devif/ipv4_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
}
#endif

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

#ifdef CONFIG_NET_IPFILTER
if (ipv4_filter_in(dev) != IPFILTER_TARGET_ACCEPT)
Expand Down
6 changes: 6 additions & 0 deletions net/icmp/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ config NET_ICMP_SOCKET
for application level support for sending ECHO (ping) requests and
receiving associated ECHO replies.

config NET_ICMP_CHECKSUMS
bool "ICMP checksums"
default y
---help---
Enable/disable ICMP checksum support.

if NET_ICMP_SOCKET

config NET_ICMP_PREALLOC_CONNS
Expand Down
6 changes: 5 additions & 1 deletion net/icmp/icmp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* checksum for the change of type
*/

#ifdef CONFIG_NET_ICMP_CHECKSUMS
if (icmp->icmpchksum >= HTONS(0xffff - (ICMP_ECHO_REQUEST << 8)))
{
icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8) + 1;
Expand All @@ -333,6 +333,10 @@ void icmp_input(FAR struct net_driver_s *dev)
{
icmp->icmpchksum += HTONS(ICMP_ECHO_REQUEST << 8);
}
#else
icmp->icmpchksum = 0;
#endif

#endif

ninfo("Outgoing ICMP packet length: %d (%d)\n",
Expand Down
2 changes: 2 additions & 0 deletions net/icmp/icmp_reply.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,13 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
/* Calculate the ICMP checksum. */

icmp->icmpchksum = 0;
#ifdef CONFIG_NET_ICMP_CHECKSUMS
icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob);
if (icmp->icmpchksum == 0)
{
icmp->icmpchksum = 0xffff;
}
#endif

ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);
}
Expand Down
3 changes: 3 additions & 0 deletions net/icmp/icmp_sendmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,14 @@ static void sendto_request(FAR struct net_driver_s *dev,
/* Calculate the ICMP checksum. */

icmp->icmpchksum = 0;

#ifdef CONFIG_NET_ICMP_CHECKSUMS
icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob);
if (icmp->icmpchksum == 0)
{
icmp->icmpchksum = 0xffff;
}
#endif

ninfo("Outgoing ICMP packet length: %d\n", dev->d_len);

Expand Down
6 changes: 6 additions & 0 deletions net/icmpv6/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ config NET_ICMPv6_SOCKET
for application level support for sending ICMPv7 ECHO requests and
receiving associated ICMPv6 ECHO replies.

config NET_ICMPv6_CHECKSUMS
bool "ICMPv6 checksums"
default y
---help---
Enable/disable ICMPv6 checksum support.

config NET_ICMPv6_NEIGHBOR
bool "Solicit destination addresses"
default n
Expand Down
3 changes: 2 additions & 1 deletion net/icmpv6/icmpv6_advertise.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
/* Calculate the checksum over both the ICMP header and payload */

adv->chksum = 0;
#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 */

dev->d_len = IPv6_HDRLEN + l3size;
Expand Down
3 changes: 3 additions & 0 deletions net/icmpv6/icmpv6_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,10 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
net_ipv6addr_copy(ipv6->srcipaddr, srcaddr);

icmpv6->chksum = 0;

#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
icmpv6->chksum = ~icmpv6_chksum(dev, iplen);
#endif
}
break;

Expand Down
4 changes: 3 additions & 1 deletion net/icmpv6/icmpv6_radvertise.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,10 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
/* Calculate the checksum over both the ICMP header and payload */

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 */

dev->d_len = IPv6_HDRLEN + l3size;
Expand Down
3 changes: 3 additions & 0 deletions net/icmpv6/icmpv6_reply.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */

icmpv6->chksum = 0;

#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
if (icmpv6->chksum == 0)
{
icmpv6->chksum = 0xffff;
}
#endif

ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);
}
Expand Down
4 changes: 3 additions & 1 deletion net/icmpv6/icmpv6_rsolicit.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
/* Calculate the checksum over both the ICMP header and payload */

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 */

dev->d_len = IPv6_HDRLEN + l3size;
Expand Down
3 changes: 3 additions & 0 deletions net/icmpv6/icmpv6_sendmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,14 @@ static void sendto_request(FAR struct net_driver_s *dev,
/* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */

icmpv6->chksum = 0;

#ifdef CONFIG_NET_ICMPv6_CHECKSUMS
icmpv6->chksum = ~icmpv6_chksum(dev, IPv6_HDRLEN);
if (icmpv6->chksum == 0)
{
icmpv6->chksum = 0xffff;
}
#endif

ninfo("Outgoing ICMPv6 packet length: %d\n", dev->d_len);

Expand Down
4 changes: 3 additions & 1 deletion net/icmpv6/icmpv6_solicit.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
/* Calculate the checksum over both the ICMP header and payload */

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 */

dev->d_len = IPv6_HDRLEN + l3size;
Expand Down
6 changes: 6 additions & 0 deletions net/igmp/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ config NET_IGMP
---help---
Enable IGMPv2 client support.

config NET_IGMP_CHECKSUMS
bool "IGMP checksums"
default y
---help---
Enable/disable IGMP checksum support.

if NET_IGMP

endif # NET_IGMP
2 changes: 2 additions & 0 deletions net/igmp/igmp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ void igmp_input(struct net_driver_s *dev)
goto drop;
}

#ifdef CONFIG_NET_IGMP_CHECKSUMS
/* Calculate and check the IGMP checksum */

if (net_chksum((FAR uint16_t *)igmp, IGMP_HDRLEN) != 0)
Expand All @@ -144,6 +145,7 @@ void igmp_input(struct net_driver_s *dev)
nwarn("WARNING: Checksum error\n");
goto drop;
}
#endif

/* Find the group (or create a new one) using the incoming IP address. */

Expand Down
5 changes: 5 additions & 0 deletions net/igmp/igmp_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@
* Private Functions
****************************************************************************/

#ifdef CONFIG_NET_IGMP_CHECKSUMS
static uint16_t igmp_chksum(FAR uint8_t *buffer, int buflen)
{
uint16_t sum = net_chksum((FAR uint16_t *)buffer, buflen);
return sum ? sum : 0xffff;
}
#endif

/****************************************************************************
* Public Functions
Expand Down Expand Up @@ -157,7 +159,10 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
/* Calculate the IGMP checksum. */

igmp->chksum = 0;

#ifdef CONFIG_NET_IGMP_CHECKSUMS
igmp->chksum = ~igmp_chksum(&igmp->type, IGMP_HDRLEN);
#endif

IGMP_STATINCR(g_netstats.igmp.poll_send);
IGMP_STATINCR(g_netstats.ipv4.sent);
Expand Down
6 changes: 6 additions & 0 deletions net/inet/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@
# For a description of the syntax of this configuration file,
# 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.
3 changes: 3 additions & 0 deletions net/inet/ipv4_build_header.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ uint16_t ipv4_build_header(FAR struct ipv4_hdr_s *ipv4, uint16_t total_len,
/* Calculate IP checksum. */

ipv4->ipchksum = 0;

#ifdef CONFIG_NET_IPV4_CHECKSUMS
ipv4->ipchksum = ~ipv4_chksum(ipv4);
#endif

ninfo("IPv4 Packet: ipid:%d, length: %d\n", g_ipid, total_len);

Expand Down
Loading

0 comments on commit fe01d7c

Please sign in to comment.