From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id A6F895A02F2 for ; Wed, 1 May 2024 08:54:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1714546436; bh=IWQ7ggjM6jPeJnBKoto/l71tuR8kCi8A5SsR9ftHq1Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EohqSHIp6NFNqRmPA3oP4nOEk47hc6schkpCWktESpch0C0N4ZfkzVW9JGzchVcyX HVsEMr4X9QwvRafgJHIti1Rwme/K0PNnTdUiRb8hl/VHph9QcMbdqLAMj710Kp8ov8 f/0CF0NL7QN96xiLA428FPlEVAmYAcsdh+c8jxpjkpL5swgwivSToHEiuKNuQNZ/Qc 8KhC9gs8lNZPoJ+uldkaF1GZZvTTVDWkt5LpW/yhekakv8vUSiG6X1BulY9/qq7bUS zQ8CwtpDCm+CLL2Cjun8liYLncBQgCZ92zfupGoq38Ea3yETOZ4sDM2Wy8drA7CJwu Ub+lz4aObQvzw== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4VTnpr16Tpz4x1R; Wed, 1 May 2024 16:53:56 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v2 05/10] checksum: Make csum_ip4_header() take a host endian length Date: Wed, 1 May 2024 16:53:48 +1000 Message-ID: <20240501065353.1682358-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240501065353.1682358-1-david@gibson.dropbear.id.au> References: <20240501065353.1682358-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: HAHSSFBOUF4CNAO3NSZNYDQFA3APSYHK X-Message-ID-Hash: HAHSSFBOUF4CNAO3NSZNYDQFA3APSYHK X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Laurent Vivier , David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: csum_ip4_header() takes the packet length as a network endian value. In general it's very error-prone to pass non-native-endian values as a raw integer. It's particularly bad here because this differs from other checksum functions (e.g. proto_ipv4_header_psum()) which take host native lengths. It turns out all the callers have easy access to the native endian value, so switch it to use host order like everything else. Signed-off-by: David Gibson --- checksum.c | 4 ++-- tap.c | 6 ++++-- tcp.c | 2 +- udp.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/checksum.c b/checksum.c index a5a506c7..b330e1ef 100644 --- a/checksum.c +++ b/checksum.c @@ -116,7 +116,7 @@ uint16_t csum_fold(uint32_t sum) /** * csum_ip4_header() - Calculate IPv4 header checksum - * @tot_len: IPv4 payload length (data + IP header, network order) + * @tot_len: IPv4 packet length (data + IP header, host order) * @protocol: Protocol number * @saddr: IPv4 source address * @daddr: IPv4 destination address @@ -128,7 +128,7 @@ uint16_t csum_ip4_header(uint16_t tot_len, uint8_t protocol, { uint32_t sum = L2_BUF_IP4_PSUM(protocol); - sum += tot_len; + sum += htons(tot_len); sum += (saddr.s_addr >> 16) & 0xffff; sum += saddr.s_addr & 0xffff; sum += (daddr.s_addr >> 16) & 0xffff; diff --git a/tap.c b/tap.c index d0ef6b5c..230566ba 100644 --- a/tap.c +++ b/tap.c @@ -149,17 +149,19 @@ static void *tap_push_l2h(const struct ctx *c, void *buf, uint16_t proto) static void *tap_push_ip4h(struct iphdr *ip4h, struct in_addr src, struct in_addr dst, size_t len, uint8_t proto) { + uint16_t tot_len = len + sizeof(*ip4h); + ip4h->version = 4; ip4h->ihl = sizeof(struct iphdr) / 4; ip4h->tos = 0; - ip4h->tot_len = htons(len + sizeof(*ip4h)); + ip4h->tot_len = htons(tot_len); ip4h->id = 0; ip4h->frag_off = 0; ip4h->ttl = 255; ip4h->protocol = proto; ip4h->saddr = src.s_addr; ip4h->daddr = dst.s_addr; - ip4h->check = csum_ip4_header(ip4h->tot_len, proto, src, dst); + ip4h->check = csum_ip4_header(tot_len, proto, src, dst); return ip4h + 1; } diff --git a/tcp.c b/tcp.c index 24f99cdf..3ba3aa4d 100644 --- a/tcp.c +++ b/tcp.c @@ -1359,7 +1359,7 @@ static size_t tcp_fill_headers4(const struct ctx *c, iph->daddr = c->ip4.addr_seen.s_addr; iph->check = check ? *check : - csum_ip4_header(iph->tot_len, IPPROTO_TCP, + csum_ip4_header(ip_len, IPPROTO_TCP, *a4, c->ip4.addr_seen); tcp_fill_header(th, conn, seq); diff --git a/udp.c b/udp.c index 4bf90591..09f98130 100644 --- a/udp.c +++ b/udp.c @@ -605,7 +605,7 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *b, b->iph.tot_len = htons(ip_len); b->iph.daddr = c->ip4.addr_seen.s_addr; b->iph.saddr = src.s_addr; - b->iph.check = csum_ip4_header(b->iph.tot_len, IPPROTO_UDP, + b->iph.check = csum_ip4_header(ip_len, IPPROTO_UDP, src, c->ip4.addr_seen); b->uh.source = b->s_in.sin_port; -- 2.44.0