mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-08-25 23:52:51 +00:00
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:
parent
c4a1cad81b
commit
aa0e41c389
@ -6,6 +6,10 @@ HISTORY
|
||||
|
||||
++ 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
|
||||
* PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in
|
||||
contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required)
|
||||
|
@ -133,6 +133,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
goto lenerr;
|
||||
}
|
||||
#if CHECKSUM_CHECK_ICMP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
|
||||
if (inet_chksum_pbuf(p) != 0) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
|
||||
pbuf_free(p);
|
||||
@ -140,6 +141,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
snmp_inc_icmpinerrors();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
|
||||
if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) {
|
||||
@ -193,12 +195,19 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
|
||||
ICMPH_TYPE_SET(iecho, ICMP_ER);
|
||||
#if CHECKSUM_GEN_ICMP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
|
||||
/* adjust the checksum */
|
||||
if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
|
||||
iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
|
||||
} 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 */
|
||||
iecho->chksum = 0;
|
||||
#endif /* CHECKSUM_GEN_ICMP */
|
||||
@ -207,7 +216,9 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
IPH_TTL_SET(iphdr, ICMP_TTL);
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
|
||||
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 */
|
||||
struct icmp_echo_hdr *icmphdr;
|
||||
ip4_addr_t iphdr_src;
|
||||
struct netif *netif;
|
||||
|
||||
/* ICMP header + IP header + 8 bytes of data */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
|
||||
@ -321,10 +333,14 @@ 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,
|
||||
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
|
||||
|
||||
netif = ip4_route(&iphdr_src);
|
||||
if (netif != NULL) {
|
||||
/* calculate checksum */
|
||||
icmphdr->chksum = 0;
|
||||
#if CHECKSUM_GEN_ICMP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
|
||||
icmphdr->chksum = inet_chksum(icmphdr, q->len);
|
||||
}
|
||||
#endif
|
||||
ICMP_STATS_INC(icmp.xmit);
|
||||
/* increase number of messages attempted to send */
|
||||
@ -332,7 +348,8 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
|
||||
/* increase number of destination unreachable messages attempted to send */
|
||||
snmp_inc_icmpouttimeexcds();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,13 @@
|
||||
/** 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
|
||||
#if LWIP_CHECKSUM_CTRL_PER_NETIF
|
||||
#define LWIP_INLINE_IP_CHKSUM 0
|
||||
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
#define LWIP_INLINE_IP_CHKSUM 1
|
||||
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
#endif
|
||||
|
||||
#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
|
||||
#define CHECKSUM_GEN_IP_INLINE 1
|
||||
#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) ||
|
||||
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() */
|
||||
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)));
|
||||
@ -443,6 +448,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
/* verify checksum */
|
||||
#if CHECKSUM_CHECK_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) {
|
||||
if (inet_chksum(iphdr, iphdr_hlen) != 0) {
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
@ -454,6 +460,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
snmp_inc_ipinhdrerrors();
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* copy IP addresses to aligned ip_addr_t */
|
||||
@ -597,7 +604,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* packet consists of multiple fragments? */
|
||||
if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
|
||||
#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));
|
||||
/* reassemble the packet*/
|
||||
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;
|
||||
chk_sum = ~chk_sum;
|
||||
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 */
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
|
||||
#endif
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
} else {
|
||||
/* IP header already included in p */
|
||||
|
@ -320,7 +320,7 @@ ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -494,7 +494,7 @@ ip4_reass(struct pbuf *p)
|
||||
fraghdr = (struct ip_hdr*)p->payload;
|
||||
|
||||
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);
|
||||
goto nullreturn;
|
||||
}
|
||||
@ -511,7 +511,7 @@ ip4_reass(struct pbuf *p)
|
||||
#endif /* IP_REASS_FREE_OLDEST */
|
||||
{
|
||||
/* 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));
|
||||
IPFRAG_STATS_INC(ip_frag.memerr);
|
||||
/* @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
|
||||
fragment into the buffer. */
|
||||
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))));
|
||||
IPFRAG_STATS_INC(ip_frag.cachehit);
|
||||
break;
|
||||
@ -563,7 +563,7 @@ ip4_reass(struct pbuf *p)
|
||||
ipr->flags |= IP_REASS_FLAG_LASTFRAG;
|
||||
ipr->datagram_len = offset + len;
|
||||
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));
|
||||
}
|
||||
/* 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_OFFSET_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__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
|
||||
p = ipr->p;
|
||||
@ -625,7 +627,7 @@ ip4_reass(struct pbuf *p)
|
||||
return NULL;
|
||||
|
||||
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);
|
||||
pbuf_free(p);
|
||||
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_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
|
||||
#if IP_FRAG_USES_STATIC_BUF
|
||||
|
@ -97,6 +97,7 @@ icmp6_input(struct pbuf *p, struct netif *inp)
|
||||
icmp6hdr = (struct icmp6_hdr *)p->payload;
|
||||
|
||||
#if CHECKSUM_CHECK_ICMP6
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) {
|
||||
if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
|
||||
ip6_current_dest_addr()) != 0) {
|
||||
/* Checksum failed */
|
||||
@ -105,6 +106,7 @@ icmp6_input(struct pbuf *p, struct netif *inp)
|
||||
ICMP6_STATS_INC(icmp6.drop);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* CHECKSUM_CHECK_ICMP6 */
|
||||
|
||||
switch (icmp6hdr->type) {
|
||||
@ -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))->chksum = 0;
|
||||
#if CHECKSUM_GEN_ICMP6
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) {
|
||||
((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 */
|
||||
|
||||
/* Send reply. */
|
||||
@ -330,8 +334,10 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
|
||||
/* calculate checksum */
|
||||
icmp6hdr->chksum = 0;
|
||||
#if CHECKSUM_GEN_ICMP6
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
|
||||
icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
|
||||
reply_src, reply_dest);
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
ICMP6_STATS_INC(icmp6.xmit);
|
||||
|
@ -569,8 +569,10 @@ mld6_send(struct mld_group *group, u8_t type)
|
||||
ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
|
||||
|
||||
#if CHECKSUM_GEN_ICMP6
|
||||
IF__NETIF_CHECKSUM_ENABLED(group->netif, NETIF_CHECKSUM_GEN_ICMP6) {
|
||||
mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
|
||||
src_addr, &(group->group_address));
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
/* Add hop-by-hop headers options: router alert with MLD value. */
|
||||
|
@ -878,8 +878,10 @@ nd6_send_ns(struct netif * netif, const ip6_addr_t * target_addr, u8_t flags)
|
||||
}
|
||||
|
||||
#if CHECKSUM_GEN_ICMP6
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
|
||||
ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
|
||||
target_addr);
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
/* 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__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
|
||||
na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
|
||||
dest_addr);
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
/* Send the packet out. */
|
||||
@ -1023,8 +1027,10 @@ nd6_send_rs(struct netif * netif)
|
||||
}
|
||||
|
||||
#if CHECKSUM_GEN_ICMP6
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
|
||||
rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr,
|
||||
&multicast_address);
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
/* Send the packet out. */
|
||||
|
@ -205,6 +205,7 @@ netif_add(struct netif *netif,
|
||||
}
|
||||
netif->output_ip6 = netif_null_output_ip6;
|
||||
#endif /* LWIP_IPV6 */
|
||||
NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
|
||||
netif->flags = 0;
|
||||
#if LWIP_DHCP
|
||||
/* netif not under DHCP control by default */
|
||||
|
@ -111,9 +111,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
#endif /* SO_REUSE */
|
||||
u8_t hdrlen;
|
||||
err_t err;
|
||||
#if CHECKSUM_CHECK_TCP
|
||||
u16_t chksum;
|
||||
#endif /* CHECKSUM_CHECK_TCP */
|
||||
|
||||
LWIP_UNUSED_ARG(inp);
|
||||
|
||||
@ -147,8 +144,9 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
|
||||
#if CHECKSUM_CHECK_TCP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) {
|
||||
/* Verify TCP checksum. */
|
||||
chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
||||
u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
||||
ip_current_src_addr(), ip_current_dest_addr());
|
||||
if (chksum != 0) {
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
|
||||
@ -157,6 +155,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
TCP_STATS_INC(tcp.chkerr);
|
||||
goto dropped;
|
||||
}
|
||||
}
|
||||
#endif /* CHECKSUM_CHECK_TCP */
|
||||
|
||||
/* Move the payload pointer in the pbuf so that it points to the
|
||||
|
@ -898,6 +898,7 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
|
||||
err_t err;
|
||||
struct pbuf *p;
|
||||
u8_t optlen = 0;
|
||||
struct netif *netif;
|
||||
#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP
|
||||
struct tcp_hdr *tcphdr;
|
||||
#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */
|
||||
@ -930,17 +931,21 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
netif = ip_route(PCB_ISIPV6(pcb), &pcb->remote_ip, &pcb->local_ip);
|
||||
if (netif == NULL) {
|
||||
err = ERR_RTE;
|
||||
} else {
|
||||
#if CHECKSUM_GEN_TCP
|
||||
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
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
err = ip_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos,
|
||||
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, pcb->tos,
|
||||
IP_PROTO_TCP);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
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);
|
||||
|
||||
if (err != ERR_OK) {
|
||||
@ -1128,6 +1133,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
err_t err;
|
||||
u16_t len;
|
||||
u32_t *opts;
|
||||
struct netif *netif;
|
||||
|
||||
/** @bug Exclude retransmitted segments from this count. */
|
||||
snmp_inc_tcpoutsegs();
|
||||
@ -1184,13 +1190,16 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
pcb->rtime = 0;
|
||||
}
|
||||
|
||||
/* If we don't have a local IP address, we get one by
|
||||
calling ip_route(). */
|
||||
netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip);
|
||||
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)) {
|
||||
struct netif *netif;
|
||||
ip_addr_t *local_ip;
|
||||
ip_route_get_local_ip(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip, &pcb->local_ip);
|
||||
if ((netif == NULL) || (local_ip == NULL)) {
|
||||
ip_addr_t *local_ip = ip_netif_get_local_ip(PCB_ISIPV6(pcb), netif,
|
||||
&pcb->remote_ip, &pcb->local_ip);
|
||||
if (local_ip == NULL) {
|
||||
return ERR_RTE;
|
||||
}
|
||||
#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->tcphdr->chksum = 0;
|
||||
#if CHECKSUM_GEN_TCP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
||||
#if TCP_CHECKSUM_ON_COPY
|
||||
{
|
||||
u32_t acc;
|
||||
#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
|
||||
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;
|
||||
}
|
||||
#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */
|
||||
}
|
||||
#else /* TCP_CHECKSUM_ON_COPY */
|
||||
#if CHECKSUM_GEN_TCP
|
||||
seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP,
|
||||
seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
|
||||
#endif /* CHECKSUM_GEN_TCP */
|
||||
#endif /* TCP_CHECKSUM_ON_COPY */
|
||||
#endif /* CHECKSUM_GEN_TCP */
|
||||
}
|
||||
TCP_STATS_INC(tcp.xmit);
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
err = ip_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip,
|
||||
pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint);
|
||||
#else /* LWIP_NETIF_HWADDRHINT*/
|
||||
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*/
|
||||
NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
|
||||
err = ip_output_if(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl,
|
||||
pcb->tos, IP_PROTO_TCP, netif);
|
||||
NETIF_SET_HWADDRHINT(netif, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1292,6 +1298,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
||||
{
|
||||
struct pbuf *p;
|
||||
struct tcp_hdr *tcphdr;
|
||||
struct netif *netif;
|
||||
p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM);
|
||||
if (p == NULL) {
|
||||
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);
|
||||
snmp_inc_tcpoutrsts();
|
||||
|
||||
netif = ip_route(IP_IS_V6(remote_ip), local_ip, remote_ip);
|
||||
if (netif != NULL) {
|
||||
#if CHECKSUM_GEN_TCP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
||||
tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len,
|
||||
local_ip, remote_ip);
|
||||
}
|
||||
#endif
|
||||
/* 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);
|
||||
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;
|
||||
struct pbuf *p;
|
||||
#if CHECKSUM_GEN_TCP
|
||||
struct tcp_hdr *tcphdr;
|
||||
#endif /* CHECKSUM_GEN_TCP */
|
||||
struct netif *netif;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to "));
|
||||
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"));
|
||||
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
|
||||
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,
|
||||
&pcb->local_ip, &pcb->remote_ip);
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_TCP */
|
||||
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*/
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
u16_t len;
|
||||
u8_t is_fin;
|
||||
struct netif *netif;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to "));
|
||||
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);
|
||||
}
|
||||
|
||||
netif = ip_route(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
err = ERR_RTE;
|
||||
} else {
|
||||
#if CHECKSUM_GEN_TCP
|
||||
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
|
||||
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*/
|
||||
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);
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
|
||||
|
@ -325,6 +325,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
if (for_us) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
|
||||
#if CHECKSUM_CHECK_UDP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, CHECKSUM_CHECK_UDP) {
|
||||
#if LWIP_UDPLITE
|
||||
if (ip_current_header_proto() == IP_PROTO_UDPLITE) {
|
||||
/* Do the UDP Lite checksum */
|
||||
@ -356,6 +357,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CHECKSUM_CHECK_UDP */
|
||||
if(pbuf_header(p, -UDP_HLEN)) {
|
||||
/* Can we cope with this failing? Just assert for now */
|
||||
@ -804,6 +806,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
|
||||
udphdr->len = htons(chklen_hdr);
|
||||
/* calculate checksum */
|
||||
#if CHECKSUM_GEN_UDP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) {
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
if (have_chksum) {
|
||||
chklen = UDP_HLEN;
|
||||
@ -823,6 +826,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
|
||||
if (udphdr->chksum == 0x0000) {
|
||||
udphdr->chksum = 0xffff;
|
||||
}
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_UDP */
|
||||
|
||||
ip_proto = IP_PROTO_UDPLITE;
|
||||
@ -833,6 +837,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
|
||||
udphdr->len = htons(q->tot_len);
|
||||
/* calculate checksum */
|
||||
#if CHECKSUM_GEN_UDP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) {
|
||||
/* Checksum is mandatory over IPv6. */
|
||||
if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
|
||||
u16_t udpchksum;
|
||||
@ -856,6 +861,7 @@ udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *d
|
||||
}
|
||||
udphdr->chksum = udpchksum;
|
||||
}
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_UDP */
|
||||
ip_proto = IP_PROTO_UDP;
|
||||
}
|
||||
|
@ -98,6 +98,21 @@ extern "C" {
|
||||
* Set by the netif driver in its init function. */
|
||||
#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;
|
||||
|
||||
/** 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 */
|
||||
char* 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) */
|
||||
u16_t mtu;
|
||||
/** number of bytes used in hwaddr */
|
||||
@ -292,8 +310,17 @@ struct netif {
|
||||
#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
|
||||
#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 */ \
|
||||
(netif)->link_type = (type); \
|
||||
/* your link speed here (units: bits per second) */ \
|
||||
@ -306,7 +333,7 @@ struct netif {
|
||||
(netif)->ifoutoctets = 0; \
|
||||
(netif)->ifoutucastpkts = 0; \
|
||||
(netif)->ifoutnucastpkts = 0; \
|
||||
(netif)->ifoutdiscards = 0
|
||||
(netif)->ifoutdiscards = 0; } while(0)
|
||||
#else /* LWIP_SNMP */
|
||||
#define NETIF_INIT_SNMP(netif, type, speed)
|
||||
#endif /* LWIP_SNMP */
|
||||
|
@ -2443,6 +2443,16 @@
|
||||
---------- 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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user