diff options
author | Maciej Żenczykowski <maze@google.com> | 2023-03-16 11:34:12 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-03-16 11:34:12 +0000 |
commit | ac6e5d6c4200ea961f33c8af100e5c8cd3cd0a41 (patch) | |
tree | f3e94cae6c1ef4176c5a5f4071433496eeeb509a | |
parent | 31764f0e0c5e87d30635b94a1d69c57bc82b257b (diff) | |
parent | d661ac68c857abfa676ce034be8001d4e6696f56 (diff) | |
download | android-clat-ac6e5d6c4200ea961f33c8af100e5c8cd3cd0a41.tar.gz |
Merge "clatd: perform checksum calculation when required" am: 499eb6cb7a am: d661ac68c8
Original change: https://android-review.googlesource.com/c/platform/external/android-clat/+/2488815
Change-Id: I5007fcfaa9c12176f28a8078f4c7a5d1e0cf7adb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | clatd.c | 26 |
1 files changed, 22 insertions, 4 deletions
@@ -125,21 +125,39 @@ void process_packet_6_to_4(struct tun_data *tunnel) { } if (readlen < sizeof(struct virtio_net_hdr) + tp_net) { - logmsg(ANDROID_LOG_WARN, "%s: ignoring %zd byte pkt shorter than %u L2 header", - __func__, readlen, tp_net); + logmsg(ANDROID_LOG_WARN, "%s: ignoring %zd byte pkt shorter than %zu+%u L2 header", + __func__, readlen, sizeof(struct virtio_net_hdr), tp_net); return; } + const int pkt_len = readlen - sizeof(struct virtio_net_hdr); + // This will detect a skb->ip_summed == CHECKSUM_PARTIAL packet with non-final L4 checksum if (tp_status & TP_STATUS_CSUMNOTREADY) { static bool logged = false; if (!logged) { - logmsg(ANDROID_LOG_WARN, "read_packet checksum not ready"); + logmsg(ANDROID_LOG_WARN, "%s: L4 checksum calculation required", __func__); logged = true; } + + // These are non-negative by virtue of csum_start/offset being u16 + const int cs_start = buf.vnet.csum_start; + const int cs_offset = cs_start + buf.vnet.csum_offset; + if (cs_start > pkt_len) { + logmsg(ANDROID_LOG_ERROR, "%s: out of range - checksum start %d > %d", + __func__, cs_start, pkt_len); + } else if (cs_offset + 1 >= pkt_len) { + logmsg(ANDROID_LOG_ERROR, "%s: out of range - checksum offset %d + 1 >= %d", + __func__, cs_offset, pkt_len); + } else { + uint16_t csum = ip_checksum(buf.payload + cs_start, pkt_len - cs_start); + if (!csum) csum = 0xFFFF; // required fixup for UDP, TCP must live with it + buf.payload[cs_offset] = csum & 0xFF; + buf.payload[cs_offset + 1] = csum >> 8; + } } - translate_packet(tunnel->fd4, 0 /* to_ipv6 */, buf.payload + tp_net, readlen - sizeof(struct virtio_net_hdr) - tp_net); + translate_packet(tunnel->fd4, 0 /* to_ipv6 */, buf.payload + tp_net, pkt_len - tp_net); } // reads TUN_PI + L3 IPv4 packet from tun, translates to IPv6, writes to AF_INET6/RAW socket |