From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=ZMER0dzH; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id DB0A65A0625 for ; Thu, 19 Mar 2026 07:12:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1773900722; bh=lRQwNUpJGHIz5lfTvT5M11HzIdHERQX5o/lFdI6wW6s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZMER0dzHeB7vOOtktiq3yblXQk5NCUYDi/NPe+CO2p8GPL50xxIehnUs8HzJOer1n hGiJRSB/ygIapVY86E+yAIdHJSBzMxz/NW2mXLiETuVeUuXuFerAFxqb1vmh4vu3Ug 49QrSnhNVVBDZxL5wpk5qVWDCcRJxdwyEBdlVopUbPj7Uv7PebYnJuUA5Y/q/lhyeO QwhG2DHuISFT15LW3jdpPTMIhAMFeWUbQE/+iD1h+Gf8He3cL2pS5zPNk+GsMX8Kw1 P2MuWm7SPb4J2PsRnoO8RxstD4xFlloqH+lg86JDnJCAWdSWauDgXrVvcE7/rHOxsb HwnQmYbgz2U1A== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fbwMQ0mn9z4wSt; Thu, 19 Mar 2026 17:12:02 +1100 (AEDT) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v2 10/15] ip: Prepare ip.[ch] for sharing with pesto tool Date: Thu, 19 Mar 2026 17:11:52 +1100 Message-ID: <20260319061157.1983818-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260319061157.1983818-1-david@gibson.dropbear.id.au> References: <20260319061157.1983818-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: KHUTY3LORDEU4SKLZZP37KR25JF7RJFG X-Message-ID-Hash: KHUTY3LORDEU4SKLZZP37KR25JF7RJFG 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: 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: Most things in ip.[ch] related purely to IP addresses and headers with no dependency on other passt/pasta internals. A number of these will be useful to re-use in pesto. The exception is ipv6_l4hdr() which uses iov_tail. The only caller of this is in tap.c, so move the function there. Along with moving the constant byteswapping functions to common.h, that lets ip.[ch] to be linked into pesto as well as passt/pasta. Signed-off-by: David Gibson --- Makefile | 15 +++++++-------- common.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ ip.c | 56 +++----------------------------------------------------- ip.h | 3 +-- tap.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 48 ------------------------------------------------ 6 files changed, 113 insertions(+), 111 deletions(-) diff --git a/Makefile b/Makefile index d085c9c1..b9f20bb5 100644 --- a/Makefile +++ b/Makefile @@ -44,19 +44,18 @@ PASST_SRCS = arch.c arp.c checksum.c conf.c dhcp.c dhcpv6.c epoll_ctl.c \ udp.c udp_flow.c udp_vu.c util.c vhost_user.c virtio.c vu_common.c QRAP_SRCS = qrap.c PASST_REPAIR_SRCS = passt-repair.c -PESTO_SRCS = pesto.c serialise.c +PESTO_SRCS = pesto.c ip.c serialise.c SRCS = $(PASST_SRCS) $(QRAP_SRCS) $(PASST_REPAIR_SRCS) $(PESTO_SRCS) MANPAGES = passt.1 pasta.1 pesto.1 qrap.1 passt-repair.1 -PESTO_HEADERS = common.h pesto.h serialise.h +PESTO_HEADERS = common.h ip.h pesto.h serialise.h PASST_HEADERS = arch.h arp.h checksum.h conf.h dhcp.h dhcpv6.h epoll_ctl.h \ - flow.h fwd.h flow_table.h icmp.h icmp_flow.h inany.h iov.h ip.h \ - isolation.h lineread.h log.h migrate.h ndp.h netlink.h packet.h \ - passt.h pasta.h pcap.h pif.h repair.h siphash.h tap.h tcp.h tcp_buf.h \ - tcp_conn.h tcp_internal.h tcp_splice.h tcp_vu.h udp.h udp_flow.h \ - udp_internal.h udp_vu.h util.h vhost_user.h virtio.h vu_common.h \ - $(PESTO_HEADERS) + flow.h fwd.h flow_table.h icmp.h icmp_flow.h inany.h iov.h isolation.h \ + lineread.h log.h migrate.h ndp.h netlink.h packet.h passt.h pasta.h \ + pcap.h pif.h repair.h siphash.h tap.h tcp.h tcp_buf.h tcp_conn.h \ + tcp_internal.h tcp_splice.h tcp_vu.h udp.h udp_flow.h udp_internal.h \ + udp_vu.h util.h vhost_user.h virtio.h vu_common.h $(PESTO_HEADERS) HEADERS = $(PASST_HEADERS) seccomp.h C := \#include \nint main(){int a=getrandom(0, 0, 0);} diff --git a/common.h b/common.h index 927d20a4..7d6ba5c1 100644 --- a/common.h +++ b/common.h @@ -19,4 +19,54 @@ /* FPRINTF() intentionally silences cert-err33-c clang-tidy warnings */ #define FPRINTF(f, ...) (void)fprintf(f, __VA_ARGS__) +#define BIT(n) (1UL << (n)) + +#ifndef __bswap_constant_16 +#define __bswap_constant_16(x) \ + ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) +#endif + +#ifndef __bswap_constant_32 +#define __bswap_constant_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#endif + +#ifndef __bswap_constant_32 +#define __bswap_constant_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#endif + +#ifndef __bswap_constant_64 +#define __bswap_constant_64(x) \ + ((((x) & 0xff00000000000000ULL) >> 56) | \ + (((x) & 0x00ff000000000000ULL) >> 40) | \ + (((x) & 0x0000ff0000000000ULL) >> 24) | \ + (((x) & 0x000000ff00000000ULL) >> 8) | \ + (((x) & 0x00000000ff000000ULL) << 8) | \ + (((x) & 0x0000000000ff0000ULL) << 24) | \ + (((x) & 0x000000000000ff00ULL) << 40) | \ + (((x) & 0x00000000000000ffULL) << 56)) +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN +#define htons_constant(x) (x) +#define htonl_constant(x) (x) +#define htonll_constant(x) (x) +#define ntohs_constant(x) (x) +#define ntohl_constant(x) (x) +#define ntohll_constant(x) (x) +#else +#define htons_constant(x) (__bswap_constant_16(x)) +#define htonl_constant(x) (__bswap_constant_32(x)) +#define htonll_constant(x) (__bswap_constant_64(x)) +#define ntohs_constant(x) (__bswap_constant_16(x)) +#define ntohl_constant(x) (__bswap_constant_32(x)) +#define ntohll_constant(x) (__bswap_constant_64(x)) +#endif + +#define ntohll(x) (be64toh((x))) +#define htonll(x) (htobe64((x))) + #endif /* _COMMON_H */ diff --git a/ip.c b/ip.c index 0ea62998..4e4e0bf5 100644 --- a/ip.c +++ b/ip.c @@ -6,6 +6,9 @@ * PASTA - Pack A Subtle Tap Abstraction * for network namespace/tap device mode * + * PESTO - Programmable Extensible Socket Translation Orchestrator + * front-end for passt(1) and pasta(1) forwarding configuration + * * ip.c - IP related functions * * Copyright (c) 2020-2021 Red Hat GmbH @@ -15,61 +18,8 @@ #include #include -#include "util.h" #include "ip.h" -#define IPV6_NH_OPT(nh) \ - ((nh) == 0 || (nh) == 43 || (nh) == 44 || (nh) == 50 || \ - (nh) == 51 || (nh) == 60 || (nh) == 135 || (nh) == 139 || \ - (nh) == 140 || (nh) == 253 || (nh) == 254) - -/** - * ipv6_l4hdr() - Find pointer to L4 header in IPv6 packet and extract protocol - * @data: IPv6 packet - * @proto: Filled with L4 protocol number - * @dlen: Data length (payload excluding header extensions), set on return - * - * Return: true if the L4 header is found and @data, @proto, @dlen are set, - * false on error. Outputs are indeterminate on failure. - */ -bool ipv6_l4hdr(struct iov_tail *data, uint8_t *proto, size_t *dlen) -{ - struct ipv6_opt_hdr o_storage; - const struct ipv6_opt_hdr *o; - struct ipv6hdr ip6h_storage; - const struct ipv6hdr *ip6h; - int hdrlen; - uint8_t nh; - - ip6h = IOV_REMOVE_HEADER(data, ip6h_storage); - if (!ip6h) - return false; - - nh = ip6h->nexthdr; - if (!IPV6_NH_OPT(nh)) - goto found; - - while ((o = IOV_PEEK_HEADER(data, o_storage))) { - nh = o->nexthdr; - hdrlen = (o->hdrlen + 1) * 8; - - if (IPV6_NH_OPT(nh)) - iov_drop_header(data, hdrlen); - else - goto found; - } - - return false; - -found: - if (nh == IPPROTO_NONE) - return false; - - *dlen = iov_tail_size(data); - *proto = nh; - return true; -} - /** * ipproto_name() - Get IP protocol name from number * @proto: IP protocol number diff --git a/ip.h b/ip.h index d0de6c8d..f6c29e00 100644 --- a/ip.h +++ b/ip.h @@ -9,7 +9,7 @@ #include #include -#include "util.h" +#include "common.h" #define IN4_IS_ADDR_UNSPECIFIED(a) \ (((struct in_addr *)(a))->s_addr == htonl_constant(INADDR_ANY)) @@ -117,7 +117,6 @@ static inline uint32_t ip6_get_flow_lbl(const struct ipv6hdr *ip6h) ip6h->flow_lbl[2]; } -bool ipv6_l4hdr(struct iov_tail *data, uint8_t *proto, size_t *dlen); const char *ipproto_name(uint8_t proto); /* IPv6 link-local all-nodes multicast address, ff02::1 */ diff --git a/tap.c b/tap.c index 1049e023..185ab471 100644 --- a/tap.c +++ b/tap.c @@ -881,6 +881,58 @@ append: return in->count; } +#define IPV6_NH_OPT(nh) \ + ((nh) == 0 || (nh) == 43 || (nh) == 44 || (nh) == 50 || \ + (nh) == 51 || (nh) == 60 || (nh) == 135 || (nh) == 139 || \ + (nh) == 140 || (nh) == 253 || (nh) == 254) + +/** + * ipv6_l4hdr() - Find pointer to L4 header in IPv6 packet and extract protocol + * @data: IPv6 packet + * @proto: Filled with L4 protocol number + * @dlen: Data length (payload excluding header extensions), set on return + * + * Return: true if the L4 header is found and @data, @proto, @dlen are set, + * false on error. Outputs are indeterminate on failure. + */ +static bool ipv6_l4hdr(struct iov_tail *data, uint8_t *proto, size_t *dlen) +{ + struct ipv6_opt_hdr o_storage; + const struct ipv6_opt_hdr *o; + struct ipv6hdr ip6h_storage; + const struct ipv6hdr *ip6h; + int hdrlen; + uint8_t nh; + + ip6h = IOV_REMOVE_HEADER(data, ip6h_storage); + if (!ip6h) + return false; + + nh = ip6h->nexthdr; + if (!IPV6_NH_OPT(nh)) + goto found; + + while ((o = IOV_PEEK_HEADER(data, o_storage))) { + nh = o->nexthdr; + hdrlen = (o->hdrlen + 1) * 8; + + if (IPV6_NH_OPT(nh)) + iov_drop_header(data, hdrlen); + else + goto found; + } + + return false; + +found: + if (nh == IPPROTO_NONE) + return false; + + *dlen = iov_tail_size(data); + *proto = nh; + return true; +} + /** * tap6_handler() - IPv6 packet handler for tap file descriptor * @c: Execution context diff --git a/util.h b/util.h index d7c397f6..5357814c 100644 --- a/util.h +++ b/util.h @@ -106,54 +106,6 @@ void abort_with_msg(const char *fmt, ...) #define MAC_UNDEF MAC_BROADCAST #define MAC_IS_UNDEF(addr) (!memcmp((addr), MAC_UNDEF, ETH_ALEN)) -#ifndef __bswap_constant_16 -#define __bswap_constant_16(x) \ - ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) -#endif - -#ifndef __bswap_constant_32 -#define __bswap_constant_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) -#endif - -#ifndef __bswap_constant_32 -#define __bswap_constant_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) -#endif - -#ifndef __bswap_constant_64 -#define __bswap_constant_64(x) \ - ((((x) & 0xff00000000000000ULL) >> 56) | \ - (((x) & 0x00ff000000000000ULL) >> 40) | \ - (((x) & 0x0000ff0000000000ULL) >> 24) | \ - (((x) & 0x000000ff00000000ULL) >> 8) | \ - (((x) & 0x00000000ff000000ULL) << 8) | \ - (((x) & 0x0000000000ff0000ULL) << 24) | \ - (((x) & 0x000000000000ff00ULL) << 40) | \ - (((x) & 0x00000000000000ffULL) << 56)) -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN -#define htons_constant(x) (x) -#define htonl_constant(x) (x) -#define htonll_constant(x) (x) -#define ntohs_constant(x) (x) -#define ntohl_constant(x) (x) -#define ntohll_constant(x) (x) -#else -#define htons_constant(x) (__bswap_constant_16(x)) -#define htonl_constant(x) (__bswap_constant_32(x)) -#define htonll_constant(x) (__bswap_constant_64(x)) -#define ntohs_constant(x) (__bswap_constant_16(x)) -#define ntohl_constant(x) (__bswap_constant_32(x)) -#define ntohll_constant(x) (__bswap_constant_64(x)) -#endif - -#define ntohll(x) (be64toh((x))) -#define htonll(x) (htobe64((x))) - extern uint8_t eth_pad[ETH_ZLEN]; /** -- 2.53.0