mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 23:29:25 +00:00
ip_forward: fix IPv4 forwarding with multiple netifs/offloading
When we have multiple netifs where at least one has checksum offloading capabilities, IP forwarding needs to set various checksum fields to 0 to prevent HW algorithms on calculating an invalid checksum. -> set checksum fields of IP/UDP/TCP/ICMP to 0 in ip4_forward(). See bug #56288 Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
parent
695c323164
commit
61c67fc229
@ -336,6 +336,37 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100)));
|
||||
}
|
||||
|
||||
/* Take care of setting checksums to 0 for checksum offload netifs */
|
||||
if (CHECKSUM_GEN_IP || NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP)) {
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
}
|
||||
switch (IPH_PROTO(iphdr)) {
|
||||
#if LWIP_UDP
|
||||
#if LWIP_UDPLITE
|
||||
case IP_PROTO_UDPLITE:
|
||||
#endif
|
||||
case IP_PROTO_UDP:
|
||||
if (CHECKSUM_GEN_UDP || NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_UDP)) {
|
||||
((struct udp_hdr *)((const u8_t *)iphdr + IPH_HL_BYTES(iphdr)))->chksum = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if LWIP_TCP
|
||||
case IP_PROTO_TCP:
|
||||
if (CHECKSUM_GEN_TCP || NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_TCP)) {
|
||||
((struct tcp_hdr *)((const u8_t *)iphdr + IPH_HL_BYTES(iphdr)))->chksum = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if LWIP_ICMP
|
||||
case IP_PROTO_ICMP:
|
||||
if (CHECKSUM_GEN_ICMP || NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP)) {
|
||||
((struct icmp_hdr *)((const u8_t *)iphdr + IPH_HL_BYTES(iphdr)))->chksum = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
|
||||
ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
|
||||
|
@ -404,8 +404,10 @@ struct netif {
|
||||
#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))
|
||||
#define NETIF_CHECKSUM_ENABLED(netif, chksumflag) (((netif) == NULL) || (((netif)->chksum_flags & (chksumflag)) != 0))
|
||||
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) if NETIF_CHECKSUM_ENABLED(netif, chksumflag)
|
||||
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
#define NETIF_CHECKSUM_ENABLED(netif, chksumflag) 0
|
||||
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags)
|
||||
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
|
||||
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
|
Loading…
Reference in New Issue
Block a user