mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-29 03:14:04 +00:00
Inline generating IP checksum to save a function call
This commit is contained in:
parent
51061fb61e
commit
01d2a87f5d
@ -13,6 +13,9 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2010-04-28: Patch by Bill Auerbach
|
||||
* ip.c: Inline generating IP checksum to save a function call
|
||||
|
||||
2010-04-14: Simon Goldschmidt
|
||||
* tcpip.h/.c, timers.c: Added an overridable define to get informed when the
|
||||
tcpip_thread processes messages or timeouts to implement a watchdog.
|
||||
|
@ -58,6 +58,17 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/** Set this to 0 in the rare case of wanting to call an extra function to
|
||||
* generate the IP checksum (in contrast to calculating it on-the-fly). */
|
||||
#ifndef LWIP_INLINE_IP_CHKSUM
|
||||
#define LWIP_INLINE_IP_CHKSUM 1
|
||||
#endif
|
||||
#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
|
||||
#define CHECKSUM_GEN_IP_INLINE 1
|
||||
#else
|
||||
#define CHECKSUM_GEN_IP_INLINE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The interface that provided the packet for the current callback
|
||||
* invocation.
|
||||
@ -537,6 +548,9 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
||||
#endif /* IP_OPTIONS_SEND */
|
||||
struct ip_hdr *iphdr;
|
||||
static u16_t ip_id = 0;
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
u32_t chk_sum;
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
|
||||
/* pbufs passed to IP must have a ref-count of 1 as their payload pointer
|
||||
gets altered as the packet is passed down the stack */
|
||||
@ -582,14 +596,30 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
||||
|
||||
IPH_TTL_SET(iphdr, ttl);
|
||||
IPH_PROTO_SET(iphdr, proto);
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
chk_sum = (proto << 8) | ttl;
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
|
||||
/* dest cannot be NULL here */
|
||||
ip_addr_copy(iphdr->dest, *dest);
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
chk_sum += iphdr->dest.addr & 0xFFFF;
|
||||
chk_sum += iphdr->dest.addr >> 16;
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
|
||||
IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos);
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
chk_sum += iphdr->_v_hl_tos;
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
IPH_LEN_SET(iphdr, htons(p->tot_len));
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
chk_sum += iphdr->_len;
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
IPH_OFFSET_SET(iphdr, 0);
|
||||
IPH_ID_SET(iphdr, htons(ip_id));
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
chk_sum += iphdr->_id;
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
++ip_id;
|
||||
|
||||
if (ip_addr_isany(src)) {
|
||||
@ -599,10 +629,19 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
||||
ip_addr_copy(iphdr->src, *src);
|
||||
}
|
||||
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
chk_sum += iphdr->src.addr & 0xFFFF;
|
||||
chk_sum += iphdr->src.addr >> 16;
|
||||
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
|
||||
chk_sum = (chk_sum >> 16) + chk_sum;
|
||||
chk_sum = ~chk_sum;
|
||||
iphdr->_chksum = chk_sum; /* network order */
|
||||
#else /* CHECKSUM_GEN_IP_INLINE */
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
|
||||
#endif
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
} else {
|
||||
/* IP header already included in p */
|
||||
iphdr = (struct ip_hdr *)p->payload;
|
||||
|
Loading…
Reference in New Issue
Block a user