task #12178: hardware checksum capabilities can be configured per netif (use NETIF_SET_CHECKSUM_CTRL() in your netif's init function)

This commit is contained in:
sg 2015-09-01 22:04:15 +02:00
parent c4a1cad81b
commit aa0e41c389
13 changed files with 313 additions and 198 deletions

View File

@ -6,6 +6,10 @@ HISTORY
++ New features: ++ New features:
2015-09-01: Simon Goldschmidt
* task #12178: hardware checksum capabilities can be configured per netif
(use NETIF_SET_CHECKSUM_CTRL() in your netif's init function)
2015-08-30: Simon Goldschmidt 2015-08-30: Simon Goldschmidt
* PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in * PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in
contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required) contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required)

View File

@ -133,12 +133,14 @@ icmp_input(struct pbuf *p, struct netif *inp)
goto lenerr; goto lenerr;
} }
#if CHECKSUM_CHECK_ICMP #if CHECKSUM_CHECK_ICMP
if (inet_chksum_pbuf(p) != 0) { IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); if (inet_chksum_pbuf(p) != 0) {
pbuf_free(p); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
ICMP_STATS_INC(icmp.chkerr); pbuf_free(p);
snmp_inc_icmpinerrors(); ICMP_STATS_INC(icmp.chkerr);
return; snmp_inc_icmpinerrors();
return;
}
} }
#endif #endif
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN #if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
@ -193,12 +195,19 @@ icmp_input(struct pbuf *p, struct netif *inp)
ip4_addr_copy(iphdr->dest, *ip4_current_src_addr()); ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
ICMPH_TYPE_SET(iecho, ICMP_ER); ICMPH_TYPE_SET(iecho, ICMP_ER);
#if CHECKSUM_GEN_ICMP #if CHECKSUM_GEN_ICMP
/* adjust the checksum */ IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { /* adjust the checksum */
iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
} else { iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
iecho->chksum += PP_HTONS(ICMP_ECHO << 8); } else {
iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
}
} }
#if LWIP_CHECKSUM_CTRL_PER_NETIF
else {
iecho->chksum = 0;
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_ICMP */ #else /* CHECKSUM_GEN_ICMP */
iecho->chksum = 0; iecho->chksum = 0;
#endif /* CHECKSUM_GEN_ICMP */ #endif /* CHECKSUM_GEN_ICMP */
@ -207,7 +216,9 @@ icmp_input(struct pbuf *p, struct netif *inp)
IPH_TTL_SET(iphdr, ICMP_TTL); IPH_TTL_SET(iphdr, ICMP_TTL);
IPH_CHKSUM_SET(iphdr, 0); IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
ICMP_STATS_INC(icmp.xmit); ICMP_STATS_INC(icmp.xmit);
@ -293,6 +304,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
/* we can use the echo header here */ /* we can use the echo header here */
struct icmp_echo_hdr *icmphdr; struct icmp_echo_hdr *icmphdr;
ip4_addr_t iphdr_src; ip4_addr_t iphdr_src;
struct netif *netif;
/* ICMP header + IP header + 8 bytes of data */ /* ICMP header + IP header + 8 bytes of data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
@ -321,18 +333,23 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
/* calculate checksum */ netif = ip4_route(&iphdr_src);
icmphdr->chksum = 0; if (netif != NULL) {
/* calculate checksum */
icmphdr->chksum = 0;
#if CHECKSUM_GEN_ICMP #if CHECKSUM_GEN_ICMP
icmphdr->chksum = inet_chksum(icmphdr, q->len); IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
icmphdr->chksum = inet_chksum(icmphdr, q->len);
}
#endif #endif
ICMP_STATS_INC(icmp.xmit); ICMP_STATS_INC(icmp.xmit);
/* increase number of messages attempted to send */ /* increase number of messages attempted to send */
snmp_inc_icmpoutmsgs(); snmp_inc_icmpoutmsgs();
/* increase number of destination unreachable messages attempted to send */ /* increase number of destination unreachable messages attempted to send */
snmp_inc_icmpouttimeexcds(); snmp_inc_icmpouttimeexcds();
ip4_addr_copy(iphdr_src, iphdr->src); ip4_addr_copy(iphdr_src, iphdr->src);
ip4_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);
}
pbuf_free(q); pbuf_free(q);
} }

View File

@ -63,8 +63,13 @@
/** Set this to 0 in the rare case of wanting to call an extra function to /** 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). */ * generate the IP checksum (in contrast to calculating it on-the-fly). */
#ifndef LWIP_INLINE_IP_CHKSUM #ifndef LWIP_INLINE_IP_CHKSUM
#if LWIP_CHECKSUM_CTRL_PER_NETIF
#define LWIP_INLINE_IP_CHKSUM 0
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#define LWIP_INLINE_IP_CHKSUM 1 #define LWIP_INLINE_IP_CHKSUM 1
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#endif #endif
#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
#define CHECKSUM_GEN_IP_INLINE 1 #define CHECKSUM_GEN_IP_INLINE 1
#else #else
@ -178,7 +183,7 @@ ip4_route(const ip4_addr_t *dest)
if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||
ip4_addr_isany_val(*netif_ip4_addr(netif_default))) { ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
/* No matching netif found an default netif is not usable. /* No matching netif found and default netif is not usable.
If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
@ -443,16 +448,18 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* verify checksum */ /* verify checksum */
#if CHECKSUM_CHECK_IP #if CHECKSUM_CHECK_IP
if (inet_chksum(iphdr, iphdr_hlen) != 0) { IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) {
if (inet_chksum(iphdr, iphdr_hlen) != 0) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
ip4_debug_print(p); ip4_debug_print(p);
pbuf_free(p); pbuf_free(p);
IP_STATS_INC(ip.chkerr); IP_STATS_INC(ip.chkerr);
IP_STATS_INC(ip.drop); IP_STATS_INC(ip.drop);
snmp_inc_ipinhdrerrors(); snmp_inc_ipinhdrerrors();
return ERR_OK; return ERR_OK;
}
} }
#endif #endif
@ -597,7 +604,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* packet consists of multiple fragments? */ /* packet consists of multiple fragments? */
if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
#if IP_REASSEMBLY /* packet fragment reassembly code present? */ #if IP_REASSEMBLY /* packet fragment reassembly code present? */
LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n",
ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
/* reassemble the packet*/ /* reassemble the packet*/
p = ip4_reass(p); p = ip4_reass(p);
@ -889,12 +896,21 @@ err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_add
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + chk_sum; chk_sum = (chk_sum >> 16) + chk_sum;
chk_sum = ~chk_sum; chk_sum = ~chk_sum;
iphdr->_chksum = (u16_t)chk_sum; /* network order */ IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
iphdr->_chksum = (u16_t)chk_sum; /* network order */
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF
else {
IPH_CHKSUM_SET(iphdr, 0);
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
#else /* CHECKSUM_GEN_IP_INLINE */ #else /* CHECKSUM_GEN_IP_INLINE */
IPH_CHKSUM_SET(iphdr, 0); IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
#endif IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
}
#endif /* CHECKSUM_GEN_IP */
#endif /* CHECKSUM_GEN_IP_INLINE */ #endif /* CHECKSUM_GEN_IP_INLINE */
} else { } else {
/* IP header already included in p */ /* IP header already included in p */

View File

@ -320,7 +320,7 @@ ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
prev->next = ipr->next; prev->next = ipr->next;
} }
/* now we can free the ip_reass struct */ /* now we can free the ip_reassdata struct */
memp_free(MEMP_REASSDATA, ipr); memp_free(MEMP_REASSDATA, ipr);
} }
@ -494,7 +494,7 @@ ip4_reass(struct pbuf *p)
fraghdr = (struct ip_hdr*)p->payload; fraghdr = (struct ip_hdr*)p->payload;
if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { if ((IPH_HL(fraghdr) * 4) != IP_HLEN) {
LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: IP options currently not supported!\n"));
IPFRAG_STATS_INC(ip_frag.err); IPFRAG_STATS_INC(ip_frag.err);
goto nullreturn; goto nullreturn;
} }
@ -511,7 +511,7 @@ ip4_reass(struct pbuf *p)
#endif /* IP_REASS_FREE_OLDEST */ #endif /* IP_REASS_FREE_OLDEST */
{ {
/* No datagram could be freed and still too many pbufs enqueued */ /* No datagram could be freed and still too many pbufs enqueued */
LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
IPFRAG_STATS_INC(ip_frag.memerr); IPFRAG_STATS_INC(ip_frag.memerr);
/* @todo: send ICMP time exceeded here? */ /* @todo: send ICMP time exceeded here? */
@ -527,7 +527,7 @@ ip4_reass(struct pbuf *p)
in the reassembly buffer. If so, we proceed with copying the in the reassembly buffer. If so, we proceed with copying the
fragment into the buffer. */ fragment into the buffer. */
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
ntohs(IPH_ID(fraghdr)))); ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit); IPFRAG_STATS_INC(ip_frag.cachehit);
break; break;
@ -563,7 +563,7 @@ ip4_reass(struct pbuf *p)
ipr->flags |= IP_REASS_FLAG_LASTFRAG; ipr->flags |= IP_REASS_FLAG_LASTFRAG;
ipr->datagram_len = offset + len; ipr->datagram_len = offset + len;
LWIP_DEBUGF(IP_REASS_DEBUG, LWIP_DEBUGF(IP_REASS_DEBUG,
("ip_reass: last fragment seen, total len %"S16_F"\n", ("ip4_reass: last fragment seen, total len %"S16_F"\n",
ipr->datagram_len)); ipr->datagram_len));
} }
/* find the right place to insert this pbuf */ /* find the right place to insert this pbuf */
@ -583,9 +583,11 @@ ip4_reass(struct pbuf *p)
IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); IPH_LEN_SET(fraghdr, htons(ipr->datagram_len));
IPH_OFFSET_SET(fraghdr, 0); IPH_OFFSET_SET(fraghdr, 0);
IPH_CHKSUM_SET(fraghdr, 0); IPH_CHKSUM_SET(fraghdr, 0);
/* @todo: do we need to set calculate the correct checksum? */ /* @todo: do we need to set/calculate the correct checksum? */
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
p = ipr->p; p = ipr->p;
@ -625,7 +627,7 @@ ip4_reass(struct pbuf *p)
return NULL; return NULL;
nullreturn: nullreturn:
LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: nullreturn\n"));
IPFRAG_STATS_INC(ip_frag.drop); IPFRAG_STATS_INC(ip_frag.drop);
pbuf_free(p); pbuf_free(p);
return NULL; return NULL;
@ -831,7 +833,9 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); IPH_LEN_SET(iphdr, htons(cop + IP_HLEN));
IPH_CHKSUM_SET(iphdr, 0); IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
#if IP_FRAG_USES_STATIC_BUF #if IP_FRAG_USES_STATIC_BUF
@ -841,7 +845,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
/* This part is ugly: we alloc a RAM based pbuf for /* This part is ugly: we alloc a RAM based pbuf for
* the link level header for each chunk and then * the link level header for each chunk and then
* free it.A PBUF_ROM style pbuf for which pbuf_header * free it. A PBUF_ROM style pbuf for which pbuf_header
* worked would make things simpler. * worked would make things simpler.
*/ */
header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM);

View File

@ -97,13 +97,15 @@ icmp6_input(struct pbuf *p, struct netif *inp)
icmp6hdr = (struct icmp6_hdr *)p->payload; icmp6hdr = (struct icmp6_hdr *)p->payload;
#if CHECKSUM_CHECK_ICMP6 #if CHECKSUM_CHECK_ICMP6
if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) {
ip6_current_dest_addr()) != 0) { if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
/* Checksum failed */ ip6_current_dest_addr()) != 0) {
pbuf_free(p); /* Checksum failed */
ICMP6_STATS_INC(icmp6.chkerr); pbuf_free(p);
ICMP6_STATS_INC(icmp6.drop); ICMP6_STATS_INC(icmp6.chkerr);
return; ICMP6_STATS_INC(icmp6.drop);
return;
}
} }
#endif /* CHECKSUM_CHECK_ICMP6 */ #endif /* CHECKSUM_CHECK_ICMP6 */
@ -180,8 +182,10 @@ icmp6_input(struct pbuf *p, struct netif *inp)
((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r, IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) {
IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r,
IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr());
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send reply. */ /* Send reply. */
@ -330,8 +334,10 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
/* calculate checksum */ /* calculate checksum */
icmp6hdr->chksum = 0; icmp6hdr->chksum = 0;
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
reply_src, reply_dest); icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
reply_src, reply_dest);
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
ICMP6_STATS_INC(icmp6.xmit); ICMP6_STATS_INC(icmp6.xmit);

View File

@ -569,8 +569,10 @@ mld6_send(struct mld_group *group, u8_t type)
ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address)); ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, IF__NETIF_CHECKSUM_ENABLED(group->netif, NETIF_CHECKSUM_GEN_ICMP6) {
src_addr, &(group->group_address)); mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
src_addr, &(group->group_address));
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Add hop-by-hop headers options: router alert with MLD value. */ /* Add hop-by-hop headers options: router alert with MLD value. */

View File

@ -878,8 +878,10 @@ nd6_send_ns(struct netif * netif, const ip6_addr_t * target_addr, u8_t flags)
} }
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
target_addr); ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
target_addr);
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send the packet out. */ /* Send the packet out. */
@ -954,8 +956,10 @@ nd6_send_na(struct netif * netif, const ip6_addr_t * target_addr, u8_t flags)
} }
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
dest_addr); na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
dest_addr);
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send the packet out. */ /* Send the packet out. */
@ -1023,8 +1027,10 @@ nd6_send_rs(struct netif * netif)
} }
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
&multicast_address); rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
&multicast_address);
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send the packet out. */ /* Send the packet out. */

View File

@ -205,6 +205,7 @@ netif_add(struct netif *netif,
} }
netif->output_ip6 = netif_null_output_ip6; netif->output_ip6 = netif_null_output_ip6;
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
netif->flags = 0; netif->flags = 0;
#if LWIP_DHCP #if LWIP_DHCP
/* netif not under DHCP control by default */ /* netif not under DHCP control by default */

View File

@ -111,9 +111,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
#endif /* SO_REUSE */ #endif /* SO_REUSE */
u8_t hdrlen; u8_t hdrlen;
err_t err; err_t err;
#if CHECKSUM_CHECK_TCP
u16_t chksum;
#endif /* CHECKSUM_CHECK_TCP */
LWIP_UNUSED_ARG(inp); LWIP_UNUSED_ARG(inp);
@ -147,15 +144,17 @@ tcp_input(struct pbuf *p, struct netif *inp)
} }
#if CHECKSUM_CHECK_TCP #if CHECKSUM_CHECK_TCP
/* Verify TCP checksum. */ IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) {
chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, /* Verify TCP checksum. */
ip_current_src_addr(), ip_current_dest_addr()); u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
if (chksum != 0) { ip_current_src_addr(), ip_current_dest_addr());
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", if (chksum != 0) {
chksum)); LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
tcp_debug_print(tcphdr); chksum));
TCP_STATS_INC(tcp.chkerr); tcp_debug_print(tcphdr);
goto dropped; TCP_STATS_INC(tcp.chkerr);
goto dropped;
}
} }
#endif /* CHECKSUM_CHECK_TCP */ #endif /* CHECKSUM_CHECK_TCP */

View File

@ -898,6 +898,7 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
err_t err; err_t err;
struct pbuf *p; struct pbuf *p;
u8_t optlen = 0; u8_t optlen = 0;
struct netif *netif;
#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP #if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP
struct tcp_hdr *tcphdr; struct tcp_hdr *tcphdr;
#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ #endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */
@ -928,19 +929,23 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
if (pcb->flags & TF_TIMESTAMP) { if (pcb->flags & TF_TIMESTAMP) {
tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
} }
#endif
#if CHECKSUM_GEN_TCP
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
&pcb->local_ip, &pcb->remote_ip);
#endif #endif
#if LWIP_NETIF_HWADDRHINT
err = ip_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, netif = ip_route(PCB_ISIPV6(pcb), &pcb->remote_ip, &pcb->local_ip);
IP_PROTO_TCP, &pcb->addr_hint); if (netif == NULL) {
#else /* LWIP_NETIF_HWADDRHINT*/ err = ERR_RTE;
err = ip_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, } else {
IP_PROTO_TCP); #if CHECKSUM_GEN_TCP
#endif /* LWIP_NETIF_HWADDRHINT*/ IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
&pcb->local_ip, &pcb->remote_ip);
}
#endif
NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
err = ip_output_if(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip,
pcb->ttl, pcb->tos, IP_PROTO_TCP, netif);
NETIF_SET_HWADDRHINT(netif, NULL);
}
pbuf_free(p); pbuf_free(p);
if (err != ERR_OK) { if (err != ERR_OK) {
@ -1128,6 +1133,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
err_t err; err_t err;
u16_t len; u16_t len;
u32_t *opts; u32_t *opts;
struct netif *netif;
/** @bug Exclude retransmitted segments from this count. */ /** @bug Exclude retransmitted segments from this count. */
snmp_inc_tcpoutsegs(); snmp_inc_tcpoutsegs();
@ -1184,13 +1190,16 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
pcb->rtime = 0; pcb->rtime = 0;
} }
/* If we don't have a local IP address, we get one by netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip);
calling ip_route(). */ if (netif == NULL) {
return ERR_RTE;
}
/* If we don't have a local IP address, we get one from netif */
if (ip_addr_isany(&pcb->local_ip)) { if (ip_addr_isany(&pcb->local_ip)) {
struct netif *netif; ip_addr_t *local_ip = ip_netif_get_local_ip(PCB_ISIPV6(pcb), netif,
ip_addr_t *local_ip; &pcb->remote_ip, &pcb->local_ip);
ip_route_get_local_ip(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip, &pcb->local_ip); if (local_ip == NULL) {
if ((netif == NULL) || (local_ip == NULL)) {
return ERR_RTE; return ERR_RTE;
} }
#if !LWIP_IPV4 || !LWIP_IPV6 #if !LWIP_IPV4 || !LWIP_IPV6
@ -1216,8 +1225,9 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
seg->p->payload = seg->tcphdr; seg->p->payload = seg->tcphdr;
seg->tcphdr->chksum = 0; seg->tcphdr->chksum = 0;
#if CHECKSUM_GEN_TCP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
#if TCP_CHECKSUM_ON_COPY #if TCP_CHECKSUM_ON_COPY
{
u32_t acc; u32_t acc;
#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK #if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
@ -1246,22 +1256,18 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
seg->tcphdr->chksum = chksum_slow; seg->tcphdr->chksum = chksum_slow;
} }
#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ #endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
}
#else /* TCP_CHECKSUM_ON_COPY */ #else /* TCP_CHECKSUM_ON_COPY */
#if CHECKSUM_GEN_TCP seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
#endif /* CHECKSUM_GEN_TCP */
#endif /* TCP_CHECKSUM_ON_COPY */ #endif /* TCP_CHECKSUM_ON_COPY */
#endif /* CHECKSUM_GEN_TCP */
}
TCP_STATS_INC(tcp.xmit); TCP_STATS_INC(tcp.xmit);
#if LWIP_NETIF_HWADDRHINT NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
err = ip_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, err = ip_output_if(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint); pcb->tos, IP_PROTO_TCP, netif);
#else /* LWIP_NETIF_HWADDRHINT*/ NETIF_SET_HWADDRHINT(netif, NULL);
err = ip_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
pcb->tos, IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/
return err; return err;
} }
@ -1292,6 +1298,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
{ {
struct pbuf *p; struct pbuf *p;
struct tcp_hdr *tcphdr; struct tcp_hdr *tcphdr;
struct netif *netif;
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
if (p == NULL) { if (p == NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
@ -1317,12 +1324,17 @@ tcp_rst(u32_t seqno, u32_t ackno,
TCP_STATS_INC(tcp.xmit); TCP_STATS_INC(tcp.xmit);
snmp_inc_tcpoutrsts(); snmp_inc_tcpoutrsts();
netif = ip_route(IP_IS_V6(remote_ip), local_ip, remote_ip);
if (netif != NULL) {
#if CHECKSUM_GEN_TCP #if CHECKSUM_GEN_TCP
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
local_ip, remote_ip); tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
local_ip, remote_ip);
}
#endif #endif
/* Send output with hardcoded TTL/HL since we have no access to the pcb */ /* Send output with hardcoded TTL/HL since we have no access to the pcb */
ip_output(IP_IS_V6(remote_ip), p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); ip_output_if(IP_IS_V6(remote_ip), p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP, netif);
}
pbuf_free(p); pbuf_free(p);
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno));
} }
@ -1469,9 +1481,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
{ {
err_t err; err_t err;
struct pbuf *p; struct pbuf *p;
#if CHECKSUM_GEN_TCP struct netif *netif;
struct tcp_hdr *tcphdr;
#endif /* CHECKSUM_GEN_TCP */
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip); ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip);
@ -1486,23 +1496,25 @@ tcp_keepalive(struct tcp_pcb *pcb)
("tcp_keepalive: could not allocate memory for pbuf\n")); ("tcp_keepalive: could not allocate memory for pbuf\n"));
return ERR_MEM; return ERR_MEM;
} }
netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip);
if (netif == NULL) {
err = ERR_RTE;
} else {
#if CHECKSUM_GEN_TCP #if CHECKSUM_GEN_TCP
tcphdr = (struct tcp_hdr *)p->payload; IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload;
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
&pcb->local_ip, &pcb->remote_ip); &pcb->local_ip, &pcb->remote_ip);
}
#endif /* CHECKSUM_GEN_TCP */ #endif /* CHECKSUM_GEN_TCP */
TCP_STATS_INC(tcp.xmit); TCP_STATS_INC(tcp.xmit);
/* Send output to IP */
#if LWIP_NETIF_HWADDRHINT
err = ip_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip,
pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint);
#else /* LWIP_NETIF_HWADDRHINT*/
err = ip_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
0, IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/
/* Send output to IP */
NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
err = ip_output_if(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
0, IP_PROTO_TCP, netif);
NETIF_SET_HWADDRHINT(netif, NULL);
}
pbuf_free(p); pbuf_free(p);
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n", LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
@ -1528,6 +1540,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
struct tcp_seg *seg; struct tcp_seg *seg;
u16_t len; u16_t len;
u8_t is_fin; u8_t is_fin;
struct netif *netif;
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip); ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip);
@ -1571,19 +1584,23 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len);
} }
netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip);
if (netif == NULL) {
err = ERR_RTE;
} else {
#if CHECKSUM_GEN_TCP #if CHECKSUM_GEN_TCP
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
&pcb->local_ip, &pcb->remote_ip); tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
&pcb->local_ip, &pcb->remote_ip);
}
#endif #endif
TCP_STATS_INC(tcp.xmit); TCP_STATS_INC(tcp.xmit);
/* Send output to IP */ /* Send output to IP */
#if LWIP_NETIF_HWADDRHINT NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
err = ip_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, err = ip_output_if(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
0, IP_PROTO_TCP, &pcb->addr_hint); 0, IP_PROTO_TCP, netif);
#else /* LWIP_NETIF_HWADDRHINT*/ }
err = ip_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/
pbuf_free(p); pbuf_free(p);

View File

@ -325,34 +325,36 @@ udp_input(struct pbuf *p, struct netif *inp)
if (for_us) { if (for_us) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
#if CHECKSUM_CHECK_UDP #if CHECKSUM_CHECK_UDP
IF__NETIF_CHECKSUM_ENABLED(inp, CHECKSUM_CHECK_UDP) {
#if LWIP_UDPLITE #if LWIP_UDPLITE
if (ip_current_header_proto() == IP_PROTO_UDPLITE) { if (ip_current_header_proto() == IP_PROTO_UDPLITE) {
/* Do the UDP Lite checksum */ /* Do the UDP Lite checksum */
u16_t chklen = ntohs(udphdr->len); u16_t chklen = ntohs(udphdr->len);
if (chklen < sizeof(struct udp_hdr)) { if (chklen < sizeof(struct udp_hdr)) {
if (chklen == 0) { if (chklen == 0) {
/* For UDP-Lite, checksum length of 0 means checksum /* For UDP-Lite, checksum length of 0 means checksum
over the complete packet (See RFC 3828 chap. 3.1) */ over the complete packet (See RFC 3828 chap. 3.1) */
chklen = p->tot_len; chklen = p->tot_len;
} else { } else {
/* At least the UDP-Lite header must be covered by the /* At least the UDP-Lite header must be covered by the
checksum! (Again, see RFC 3828 chap. 3.1) */ checksum! (Again, see RFC 3828 chap. 3.1) */
goto chkerr;
}
}
if (ip_chksum_pseudo_partial(p, IP_PROTO_UDPLITE,
p->tot_len, chklen,
ip_current_src_addr(), ip_current_dest_addr()) != 0) {
goto chkerr; goto chkerr;
} }
} } else
if (ip_chksum_pseudo_partial(p, IP_PROTO_UDPLITE,
p->tot_len, chklen,
ip_current_src_addr(), ip_current_dest_addr()) != 0) {
goto chkerr;
}
} else
#endif /* LWIP_UDPLITE */ #endif /* LWIP_UDPLITE */
{ {
if (udphdr->chksum != 0) { if (udphdr->chksum != 0) {
if (ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, if (ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len,
ip_current_src_addr(), ip_current_src_addr(),
ip_current_dest_addr()) != 0) { ip_current_dest_addr()) != 0) {
goto chkerr; goto chkerr;
}
} }
} }
} }
@ -804,24 +806,26 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
udphdr->len = htons(chklen_hdr); udphdr->len = htons(chklen_hdr);
/* calculate checksum */ /* calculate checksum */
#if CHECKSUM_GEN_UDP #if CHECKSUM_GEN_UDP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) {
#if LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY
if (have_chksum) { if (have_chksum) {
chklen = UDP_HLEN; chklen = UDP_HLEN;
} }
#endif /* LWIP_CHECKSUM_ON_COPY */ #endif /* LWIP_CHECKSUM_ON_COPY */
udphdr->chksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDPLITE, udphdr->chksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDPLITE,
q->tot_len, chklen, src_ip, dst_ip); q->tot_len, chklen, src_ip, dst_ip);
#if LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY
if (have_chksum) { if (have_chksum) {
u32_t acc; u32_t acc;
acc = udphdr->chksum + (u16_t)~(chksum); acc = udphdr->chksum + (u16_t)~(chksum);
udphdr->chksum = FOLD_U32T(acc); udphdr->chksum = FOLD_U32T(acc);
} }
#endif /* LWIP_CHECKSUM_ON_COPY */ #endif /* LWIP_CHECKSUM_ON_COPY */
/* chksum zero must become 0xffff, as zero means 'no checksum' */ /* chksum zero must become 0xffff, as zero means 'no checksum' */
if (udphdr->chksum == 0x0000) { if (udphdr->chksum == 0x0000) {
udphdr->chksum = 0xffff; udphdr->chksum = 0xffff;
}
} }
#endif /* CHECKSUM_GEN_UDP */ #endif /* CHECKSUM_GEN_UDP */
@ -833,28 +837,30 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
udphdr->len = htons(q->tot_len); udphdr->len = htons(q->tot_len);
/* calculate checksum */ /* calculate checksum */
#if CHECKSUM_GEN_UDP #if CHECKSUM_GEN_UDP
/* Checksum is mandatory over IPv6. */ IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) {
if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { /* Checksum is mandatory over IPv6. */
u16_t udpchksum; if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
u16_t udpchksum;
#if LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY
if (have_chksum) { if (have_chksum) {
u32_t acc; u32_t acc;
udpchksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDP, udpchksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDP,
q->tot_len, UDP_HLEN, src_ip, dst_ip); q->tot_len, UDP_HLEN, src_ip, dst_ip);
acc = udpchksum + (u16_t)~(chksum); acc = udpchksum + (u16_t)~(chksum);
udpchksum = FOLD_U32T(acc); udpchksum = FOLD_U32T(acc);
} else } else
#endif /* LWIP_CHECKSUM_ON_COPY */ #endif /* LWIP_CHECKSUM_ON_COPY */
{ {
udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len, udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len,
src_ip, dst_ip); src_ip, dst_ip);
} }
/* chksum zero must become 0xffff, as zero means 'no checksum' */ /* chksum zero must become 0xffff, as zero means 'no checksum' */
if (udpchksum == 0x0000) { if (udpchksum == 0x0000) {
udpchksum = 0xffff; udpchksum = 0xffff;
}
udphdr->chksum = udpchksum;
} }
udphdr->chksum = udpchksum;
} }
#endif /* CHECKSUM_GEN_UDP */ #endif /* CHECKSUM_GEN_UDP */
ip_proto = IP_PROTO_UDP; ip_proto = IP_PROTO_UDP;

View File

@ -98,6 +98,21 @@ extern "C" {
* Set by the netif driver in its init function. */ * Set by the netif driver in its init function. */
#define NETIF_FLAG_MLD6 0x40U #define NETIF_FLAG_MLD6 0x40U
#if LWIP_CHECKSUM_CTRL_PER_NETIF
#define NETIF_CHECKSUM_GEN_IP 0x0001
#define NETIF_CHECKSUM_GEN_UDP 0x0002
#define NETIF_CHECKSUM_GEN_TCP 0x0004
#define NETIF_CHECKSUM_GEN_ICMP 0x0008
#define NETIF_CHECKSUM_GEN_ICMP6 0x0010
#define NETIF_CHECKSUM_CHECK_IP 0x0100
#define NETIF_CHECKSUM_CHECK_UDP 0x0200
#define NETIF_CHECKSUM_CHECK_TCP 0x0400
#define NETIF_CHECKSUM_CHECK_ICMP 0x0800
#define NETIF_CHECKSUM_CHECK_ICMP6 0x1000
#define NETIF_CHECKSUM_ENABLE_ALL 0xFFFF
#define NETIF_CHECKSUM_DISABLE_ALL 0x0000
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
struct netif; struct netif;
/** Function prototype for netif init functions. Set up flags and output/linkoutput /** Function prototype for netif init functions. Set up flags and output/linkoutput
@ -240,6 +255,9 @@ struct netif {
/* the hostname for this netif, NULL is a valid value */ /* the hostname for this netif, NULL is a valid value */
char* hostname; char* hostname;
#endif /* LWIP_NETIF_HOSTNAME */ #endif /* LWIP_NETIF_HOSTNAME */
#if LWIP_CHECKSUM_CTRL_PER_NETIF
u16_t chksum_flags;
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
/** maximum transfer unit (in bytes) */ /** maximum transfer unit (in bytes) */
u16_t mtu; u16_t mtu;
/** number of bytes used in hwaddr */ /** number of bytes used in hwaddr */
@ -292,12 +310,21 @@ struct netif {
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */
}; };
#if LWIP_CHECKSUM_CTRL_PER_NETIF
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \
(netif)->chksum_flags = chksumflags; } while(0)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) if (((netif) == NULL) || (((netif)->chksum_flags & (chksumflag)) != 0))
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#if LWIP_SNMP #if LWIP_SNMP
#define NETIF_INIT_SNMP(netif, type, speed) \ #define NETIF_INIT_SNMP(netif, type, speed) do { \
/* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
(netif)->link_type = (type); \ (netif)->link_type = (type); \
/* your link speed here (units: bits per second) */ \ /* your link speed here (units: bits per second) */ \
(netif)->link_speed = (speed); \ (netif)->link_speed = (speed);\
(netif)->ts = 0; \ (netif)->ts = 0; \
(netif)->ifinoctets = 0; \ (netif)->ifinoctets = 0; \
(netif)->ifinucastpkts = 0; \ (netif)->ifinucastpkts = 0; \
@ -306,7 +333,7 @@ struct netif {
(netif)->ifoutoctets = 0; \ (netif)->ifoutoctets = 0; \
(netif)->ifoutucastpkts = 0; \ (netif)->ifoutucastpkts = 0; \
(netif)->ifoutnucastpkts = 0; \ (netif)->ifoutnucastpkts = 0; \
(netif)->ifoutdiscards = 0 (netif)->ifoutdiscards = 0; } while(0)
#else /* LWIP_SNMP */ #else /* LWIP_SNMP */
#define NETIF_INIT_SNMP(netif, type, speed) #define NETIF_INIT_SNMP(netif, type, speed)
#endif /* LWIP_SNMP */ #endif /* LWIP_SNMP */

View File

@ -2443,6 +2443,16 @@
---------- Checksum options ---------- ---------- Checksum options ----------
-------------------------------------- --------------------------------------
*/ */
/**
* LWIP_CHECKSUM_CTRL_PER_NETIF==1: Checksum generation/check can be enabled/disabled
* per netif.
* ATTENTION: if enabled, the CHECKSUM_GEN_* and CHECKSUM_CHECK_* defines must be enabled!
*/
#ifndef LWIP_CHECKSUM_CTRL_PER_NETIF
#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
#endif
/** /**
* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.
*/ */