diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2021-10-21 04:26:08 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2021-10-21 04:26:08 +0200 |
commit | dd942eaa480a0744fd64844f34233900a0da6893 (patch) | |
tree | 42f048af444890506e208d0058c5cd3e03718667 | |
parent | 6257a2752e39c55bfb03d6db94af0c6033feb8df (diff) | |
download | passt-dd942eaa480a0744fd64844f34233900a0da6893.tar passt-dd942eaa480a0744fd64844f34233900a0da6893.tar.gz passt-dd942eaa480a0744fd64844f34233900a0da6893.tar.bz2 passt-dd942eaa480a0744fd64844f34233900a0da6893.tar.lz passt-dd942eaa480a0744fd64844f34233900a0da6893.tar.xz passt-dd942eaa480a0744fd64844f34233900a0da6893.tar.zst passt-dd942eaa480a0744fd64844f34233900a0da6893.zip |
passt: Fix build with gcc 7, use std=c99, enable some more Clang checkers
Unions and structs, you all have names now.
Take the chance to enable bugprone-reserved-identifier,
cert-dcl37-c, and cert-dcl51-cpp checkers in clang-tidy.
Provide a ffsl() weak declaration using gcc built-in.
Start reordering includes, but that's not enough for the
llvm-include-order checker yet.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | arp.c | 18 | ||||
-rw-r--r-- | checksum.c | 9 | ||||
-rw-r--r-- | conf.c | 18 | ||||
-rw-r--r-- | dhcp.c | 17 | ||||
-rw-r--r-- | dhcpv6.c | 27 | ||||
-rw-r--r-- | icmp.c | 42 | ||||
-rw-r--r-- | icmp.h | 2 | ||||
-rw-r--r-- | igmp.c | 2 | ||||
-rw-r--r-- | mld.c | 2 | ||||
-rw-r--r-- | ndp.c | 10 | ||||
-rw-r--r-- | netlink.c | 81 | ||||
-rw-r--r-- | passt.c | 33 | ||||
-rw-r--r-- | passt.h | 4 | ||||
-rw-r--r-- | pasta.c | 3 | ||||
-rw-r--r-- | pcap.c | 3 | ||||
-rw-r--r-- | qrap.c | 6 | ||||
-rw-r--r-- | tap.c | 13 | ||||
-rw-r--r-- | tcp.c | 172 | ||||
-rw-r--r-- | tcp.h | 2 | ||||
-rw-r--r-- | udp.c | 89 | ||||
-rw-r--r-- | udp.h | 2 | ||||
-rw-r--r-- | util.c | 10 | ||||
-rw-r--r-- | util.h | 3 |
24 files changed, 295 insertions, 279 deletions
@@ -9,7 +9,7 @@ # Copyright (c) 2021 Red Hat GmbH # Author: Stefano Brivio <sbrivio@redhat.com> -CFLAGS += -Wall -Wextra -pedantic +CFLAGS += -Wall -Wextra -pedantic -std=c99 -D_XOPEN_SOURCE=700 -D_GNU_SOURCE CFLAGS += -DRLIMIT_STACK_VAL=$(shell ulimit -s) CFLAGS += -DPAGE_SIZE=$(shell getconf PAGE_SIZE) CFLAGS += -DNETNS_RUN_DIR=\"/run/netns\" @@ -120,9 +120,6 @@ pkgs: # - hicpp-signed-bitwise # Those are needed for syscalls, epoll_wait flags, etc. # -# - bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp -# This flags _GNU_SOURCE, currently needed -# # - llvm-include-order # TODO: not really important, but nice to fix eventually # @@ -155,7 +152,6 @@ clang-tidy: $(wildcard *.c) -readability-magic-numbers,\ -llvmlibc-restrict-system-libc-headers,\ -hicpp-signed-bitwise,\ - -bugprone-reserved-identifier,-cert-dcl37-c,-cert-dcl51-cpp,\ -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,\ -llvm-include-order,\ -cppcoreguidelines-avoid-magic-numbers,\ @@ -12,24 +12,24 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ -#include <stdio.h> +#include <arpa/inet.h> +#include <limits.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <netinet/if_ether.h> #include <stddef.h> #include <stdint.h> +#include <stdio.h> #include <unistd.h> #include <string.h> -#include <linux/if_ether.h> -#include <linux/ip.h> + #include <linux/ipv6.h> -#include <linux/udp.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <arpa/inet.h> #include "util.h" -#include "passt.h" +#include "arp.h" #include "dhcp.h" +#include "passt.h" #include "tap.h" -#include "arp.h" /** * arp() - Check if this is an ARP message, reply as needed @@ -46,12 +46,11 @@ * See the comment to csum_avx2() for further details. */ -#include <stdint.h> -#include <stddef.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/udp.h> #include <arpa/inet.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <stddef.h> +#include <stdint.h> /** * sum_16b() - Calculate sum of 16-bit words @@ -14,32 +14,30 @@ * #syscalls stat */ -#define _GNU_SOURCE -#include <sched.h> +#include <arpa/inet.h> +#include <errno.h> +#include <fcntl.h> #include <getopt.h> #include <string.h> -#include <errno.h> +#include <sched.h> #include <sys/types.h> #include <sys/stat.h> -#include <fcntl.h> -#include <ifaddrs.h> #include <limits.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <syslog.h> #include <time.h> -#include <arpa/inet.h> #include <netinet/in.h> -#include <linux/if_ether.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> +#include <netinet/if_ether.h> + +#include <linux/ipv6.h> #include "util.h" #include "passt.h" +#include "netlink.h" #include "udp.h" #include "tcp.h" -#include "netlink.h" #include "pasta.h" /** @@ -12,23 +12,24 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ -#include <stdio.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <netinet/if_ether.h> +#include <netinet/ip.h> +#include <netinet/udp.h> #include <stddef.h> +#include <stdio.h> #include <stdint.h> #include <unistd.h> #include <string.h> -#include <linux/if_ether.h> -#include <linux/ip.h> + #include <linux/ipv6.h> -#include <linux/udp.h> -#include <net/if.h> -#include <arpa/inet.h> -#include "checksum.h" #include "util.h" +#include "checksum.h" #include "passt.h" -#include "dhcp.h" #include "tap.h" +#include "dhcp.h" /** * struct opt - DHCP option @@ -12,19 +12,20 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ +#include <arpa/inet.h> +#include <net/if_arp.h> +#include <net/if.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <netinet/if_ether.h> #include <stdio.h> #include <stddef.h> #include <stdint.h> #include <unistd.h> #include <string.h> #include <time.h> -#include <arpa/inet.h> -#include <linux/if_ether.h> -#include <linux/ip.h> + #include <linux/ipv6.h> -#include <linux/udp.h> -#include <net/if.h> -#include <net/if_arp.h> #include "util.h" #include "passt.h" @@ -205,9 +206,9 @@ struct msg_hdr { } __attribute__((__packed__)); #if __BYTE_ORDER == __BIG_ENDIAN -#define UH_RESP { 547, 546, 0, 0, } +#define UH_RESP {{{ 547, 546, 0, 0, }}} #else -#define UH_RESP { __bswap_constant_16(547), __bswap_constant_16(546), 0, 0 } +#define UH_RESP {{{ __bswap_constant_16(547), __bswap_constant_16(546), 0, 0 }}} #endif /** @@ -316,26 +317,26 @@ static struct opt_hdr *dhcpv6_opt(struct opt_hdr *o, uint16_t type, size_t *len) /** * dhcpv6_ia_notonlink() - Check if any IA contains non-appropriate addresses * @o: First option header to check for IAs - * @len: Remaining message length, host order + * @rem_len: Remaining message length, host order * @addr: Address we want to lease to the client * * Return: pointer to non-appropriate IA_NA or IA_TA, if any, NULL otherwise */ -static struct opt_hdr *dhcpv6_ia_notonlink(struct opt_hdr *o, size_t len, +static struct opt_hdr *dhcpv6_ia_notonlink(struct opt_hdr *o, size_t rem_len, struct in6_addr *addr) { struct opt_hdr *ia, *ia_addr; char buf[INET6_ADDRSTRLEN]; struct in6_addr *req_addr; - size_t __len; + size_t len; int ia_type; ia_type = OPT_IA_NA; ia_ta: - __len = len; + len = rem_len; ia = o; - while ((ia = dhcpv6_opt(ia, ia_type, &__len))) { + while ((ia = dhcpv6_opt(ia, ia_type, &len))) { size_t ia_len = ntohs(ia->l); if (ia_type == OPT_IA_NA) { @@ -12,12 +12,14 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ -#include <stdio.h> #include <errno.h> -#include <limits.h> #include <net/ethernet.h> #include <net/if.h> #include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip_icmp.h> +#include <stdio.h> +#include <limits.h> #include <stdint.h> #include <stddef.h> #include <string.h> @@ -25,12 +27,11 @@ #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> -#include <linux/ip.h> -#include <linux/ipv6.h> -#include <linux/icmp.h> -#include <linux/icmpv6.h> #include <time.h> +#include <linux/icmpv6.h> +#include <linux/ipv6.h> + #include "util.h" #include "passt.h" #include "tap.h" @@ -39,19 +40,19 @@ #define ICMP_ECHO_TIMEOUT 60 /* s, timeout for ICMP socket activity */ /** - * struct icmp_id - Tracking information for single ICMP echo identifier + * struct icmp_id_sock - Tracking information for single ICMP echo identifier * @sock: Bound socket for identifier * @ts: Last associated activity from tap, seconds * @seq: Last sequence number sent to tap, host order */ -struct icmp_id { +struct icmp_id_sock { int sock; time_t ts; uint16_t seq; }; /* Indexed by ICMP echo identifier */ -static struct icmp_id icmp_id_map [IP_VERSIONS][USHRT_MAX]; +static struct icmp_id_sock icmp_id_map [IP_VERSIONS][USHRT_MAX]; /* Bitmaps, activity monitoring needed for identifier */ static uint8_t icmp_act [IP_VERSIONS][USHRT_MAX / 8]; @@ -70,6 +71,7 @@ void icmp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0 } }; + union icmp_epoll_ref *iref = &ref.r.p.icmp; struct sockaddr_storage sr; socklen_t sl = sizeof(sr); char buf[USHRT_MAX]; @@ -79,11 +81,11 @@ void icmp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, (void)events; (void)now; - n = recvfrom(ref.s, buf, sizeof(buf), 0, (struct sockaddr *)&sr, &sl); + n = recvfrom(ref.r.s, buf, sizeof(buf), 0, (struct sockaddr *)&sr, &sl); if (n < 0) return; - if (ref.icmp.v6) { + if (iref->icmp.v6) { struct sockaddr_in6 *sr6 = (struct sockaddr_in6 *)&sr; struct icmp6hdr *ih = (struct icmp6hdr *)buf; @@ -92,8 +94,8 @@ void icmp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, /* If bind() fails e.g. because of a broken SELinux policy, this * might happen. Fix up the identifier to match the sent one. */ - if (id != ref.icmp.id) - ih->icmp6_identifier = htons(ref.icmp.id); + if (id != iref->icmp.id) + ih->icmp6_identifier = htons(iref->icmp.id); /* In PASTA mode, we'll get any reply we send, discard them. */ if (c->mode == MODE_PASTA) { @@ -111,8 +113,8 @@ void icmp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, struct icmphdr *ih = (struct icmphdr *)buf; id = ntohs(ih->un.echo.id); - if (id != ref.icmp.id) - ih->un.echo.id = htons(ref.icmp.id); + if (id != iref->icmp.id) + ih->un.echo.id = htons(iref->icmp.id); if (c->mode == MODE_PASTA) { seq = ntohs(ih->un.echo.sequence); @@ -146,7 +148,7 @@ int icmp_tap_handler(struct ctx *c, int af, void *addr, (void)count; if (af == AF_INET) { - union icmp_epoll_ref iref = { .v6 = 0 }; + union icmp_epoll_ref iref = { .icmp.v6 = 0 }; struct sockaddr_in sa = { .sin_family = AF_INET, .sin_addr = { .s_addr = INADDR_ANY }, @@ -161,7 +163,7 @@ int icmp_tap_handler(struct ctx *c, int af, void *addr, sa.sin_port = ih->un.echo.id; - iref.id = id = ntohs(ih->un.echo.id); + iref.icmp.id = id = ntohs(ih->un.echo.id); if ((s = icmp_id_map[V4][id].sock) <= 0) { s = sock_l4(c, AF_INET, IPPROTO_ICMP, id, 0, iref.u32); @@ -177,7 +179,7 @@ int icmp_tap_handler(struct ctx *c, int af, void *addr, sendto(s, ih, msg[0].l4_len, MSG_NOSIGNAL, (struct sockaddr *)&sa, sizeof(sa)); } else if (af == AF_INET6) { - union icmp_epoll_ref iref = { .v6 = 1 }; + union icmp_epoll_ref iref = { .icmp.v6 = 1 }; struct sockaddr_in6 sa = { .sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, @@ -193,7 +195,7 @@ int icmp_tap_handler(struct ctx *c, int af, void *addr, sa.sin6_port = ih->icmp6_identifier; - iref.id = id = ntohs(ih->icmp6_identifier); + iref.icmp.id = id = ntohs(ih->icmp6_identifier); if ((s = icmp_id_map[V6][id].sock) <= 0) { s = sock_l4(c, AF_INET6, IPPROTO_ICMPV6, id, 0, iref.u32); @@ -229,7 +231,7 @@ fail_sock: static void icmp_timer_one(struct ctx *c, int v6, uint16_t id, struct timespec *ts) { - struct icmp_id *id_map = &icmp_id_map[v6 ? V6 : V4][id]; + struct icmp_id_sock *id_map = &icmp_id_map[v6 ? V6 : V4][id]; if (ts->tv_sec - id_map->ts <= ICMP_ECHO_TIMEOUT) return; @@ -26,7 +26,7 @@ union icmp_epoll_ref { struct { uint32_t v6:1, id:16; - }; + } icmp; uint32_t u32; }; @@ -13,4 +13,4 @@ */ /* TO BE IMPLEMENTED */ -__attribute__((__unused__)) static void __(void) { } +__attribute__((__unused__)) static void unused(void) { } @@ -13,4 +13,4 @@ */ /* TO BE IMPLEMENTED */ -__attribute__((__unused__)) static void __(void) { } +__attribute__((__unused__)) static void unused(void) { } @@ -19,13 +19,13 @@ #include <unistd.h> #include <string.h> #include <arpa/inet.h> -#include <linux/if_ether.h> -#include <linux/ip.h> -#include <linux/ipv6.h> -#include <linux/icmpv6.h> -#include <linux/udp.h> +#include <netinet/ip.h> #include <net/if.h> #include <net/if_arp.h> +#include <netinet/if_ether.h> + +#include <linux/ipv6.h> +#include <linux/icmpv6.h> #include "checksum.h" #include "util.h" @@ -12,7 +12,6 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ -#define _GNU_SOURCE #include <sched.h> #include <string.h> #include <stddef.h> @@ -24,7 +23,9 @@ #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> -#include <linux/if_ether.h> +#include <netinet/if_ether.h> + +#include <linux/ipv6.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> @@ -38,12 +39,12 @@ static int nl_sock_ns = -1; static int nl_seq; /** - * __nl_sock_init() - Set up netlink sockets in init and target namespace + * nl_sock_init_do() - Set up netlink sockets in init and target namespace * @arg: Execution context * * Return: 0 */ -static int __nl_sock_init(void *arg) +static int nl_sock_init_do(void *arg) { struct sockaddr_nl addr = { .nl_family = AF_NETLINK, }; struct ctx *c = (struct ctx *)arg; @@ -65,7 +66,7 @@ ns: } /** - * nl_sock_init() - Call __nl_sock_init() and check for failures + * nl_sock_init() - Call nl_sock_init_do() and check for failures * @c: Execution context * * Return: -EIO if sockets couldn't be set up, 0 otherwise @@ -73,11 +74,11 @@ ns: int nl_sock_init(struct ctx *c) { if (c->mode == MODE_PASTA) { - NS_CALL(__nl_sock_init, c); + NS_CALL(nl_sock_init_do, c); if (nl_sock_ns == -1) return -EIO; } else { - __nl_sock_init(NULL); + nl_sock_init_do(NULL); } if (nl_sock == -1) @@ -267,7 +268,7 @@ void nl_route(int ns, unsigned int ifi, sa_family_t af, void *gw) uint32_t a; uint8_t end; } r4; - }; + } set; } req = { .nlh.nlmsg_type = set ? RTM_NEWROUTE : RTM_GETROUTE, .nlh.nlmsg_flags = NLM_F_REQUEST, @@ -290,29 +291,33 @@ void nl_route(int ns, unsigned int ifi, sa_family_t af, void *gw) if (set) { if (af == AF_INET6) { + size_t rta_len = RTA_LENGTH(sizeof(req.set.r6.d)); + req.nlh.nlmsg_len = sizeof(req); - req.r6.rta_dst.rta_type = RTA_DST; - req.r6.rta_dst.rta_len = RTA_LENGTH(sizeof(req.r6.d)); + req.set.r6.rta_dst.rta_type = RTA_DST; + req.set.r6.rta_dst.rta_len = rta_len; - memcpy(&req.r6.a, gw, sizeof(req.r6.a)); - req.r6.rta_gw.rta_type = RTA_GATEWAY; - req.r6.rta_gw.rta_len = RTA_LENGTH(sizeof(req.r6.a)); + memcpy(&req.set.r6.a, gw, sizeof(req.set.r6.a)); + req.set.r6.rta_gw.rta_type = RTA_GATEWAY; + req.set.r6.rta_gw.rta_len = rta_len; } else { - req.nlh.nlmsg_len = offsetof(struct req_t, r4.end); + size_t rta_len = RTA_LENGTH(sizeof(req.set.r4.d)); + + req.nlh.nlmsg_len = offsetof(struct req_t, set.r4.end); - req.r4.rta_dst.rta_type = RTA_DST; - req.r4.rta_dst.rta_len = RTA_LENGTH(sizeof(req.r4.d)); + req.set.r4.rta_dst.rta_type = RTA_DST; + req.set.r4.rta_dst.rta_len = rta_len; - req.r4.a = *(uint32_t *)gw; - req.r4.rta_gw.rta_type = RTA_GATEWAY; - req.r4.rta_gw.rta_len = RTA_LENGTH(sizeof(req.r4.a)); + req.set.r4.a = *(uint32_t *)gw; + req.set.r4.rta_gw.rta_type = RTA_GATEWAY; + req.set.r4.rta_gw.rta_len = rta_len; } req.rtm.rtm_protocol = RTPROT_BOOT; req.nlh.nlmsg_flags |= NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; } else { - req.nlh.nlmsg_len = offsetof(struct req_t, r6); + req.nlh.nlmsg_len = offsetof(struct req_t, set.r6); req.nlh.nlmsg_flags |= NLM_F_DUMP; } @@ -376,7 +381,7 @@ void nl_addr(int ns, unsigned int ifi, sa_family_t af, struct rtattr rta_a; struct in6_addr a; } a6; - }; + } set; } req = { .nlh.nlmsg_type = set ? RTM_NEWADDR : RTM_GETADDR, .nlh.nlmsg_flags = NLM_F_REQUEST, @@ -395,22 +400,26 @@ void nl_addr(int ns, unsigned int ifi, sa_family_t af, if (set) { if (af == AF_INET6) { + size_t rta_len = sizeof(req.set.a6.l); + req.nlh.nlmsg_len = sizeof(req); - memcpy(&req.a6.l, addr, sizeof(req.a6.l)); - req.a6.rta_l.rta_len = RTA_LENGTH(sizeof(req.a6.l)); - req.a4.rta_l.rta_type = IFA_LOCAL; - memcpy(&req.a6.a, addr, sizeof(req.a6.a)); - req.a6.rta_a.rta_len = RTA_LENGTH(sizeof(req.a6.a)); - req.a6.rta_a.rta_type = IFA_ADDRESS; + memcpy(&req.set.a6.l, addr, sizeof(req.set.a6.l)); + req.set.a6.rta_l.rta_len = rta_len; + req.set.a4.rta_l.rta_type = IFA_LOCAL; + memcpy(&req.set.a6.a, addr, sizeof(req.set.a6.a)); + req.set.a6.rta_a.rta_len = rta_len; + req.set.a6.rta_a.rta_type = IFA_ADDRESS; } else { - req.nlh.nlmsg_len = offsetof(struct req_t, a4.end); + size_t rta_len = sizeof(req.set.a4.l); + + req.nlh.nlmsg_len = offsetof(struct req_t, set.a4.end); - req.a4.l = req.a4.a = *(uint32_t *)addr; - req.a4.rta_l.rta_len = RTA_LENGTH(sizeof(req.a4.l)); - req.a4.rta_l.rta_type = IFA_LOCAL; - req.a4.rta_a.rta_len = RTA_LENGTH(sizeof(req.a4.a)); - req.a4.rta_a.rta_type = IFA_ADDRESS; + req.set.a4.l = req.set.a4.a = *(uint32_t *)addr; + req.set.a4.rta_l.rta_len = rta_len; + req.set.a4.rta_l.rta_type = IFA_LOCAL; + req.set.a4.rta_a.rta_len = rta_len; + req.set.a4.rta_a.rta_type = IFA_ADDRESS; } req.ifa.ifa_scope = RT_SCOPE_UNIVERSE; @@ -475,7 +484,7 @@ void nl_link(int ns, unsigned int ifi, void *mac, int up, int mtu) union { unsigned char mac[ETH_ALEN]; unsigned int mtu; - }; + } set; } req = { .nlh.nlmsg_type = change ? RTM_NEWLINK : RTM_GETLINK, .nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)), @@ -494,7 +503,7 @@ void nl_link(int ns, unsigned int ifi, void *mac, int up, int mtu) if (!MAC_IS_ZERO(mac)) { req.nlh.nlmsg_len = sizeof(req); - memcpy(req.mac, mac, ETH_ALEN); + memcpy(req.set.mac, mac, ETH_ALEN); req.rta.rta_type = IFLA_ADDRESS; req.rta.rta_len = RTA_LENGTH(ETH_ALEN); nl_req(ns, buf, &req, req.nlh.nlmsg_len); @@ -503,7 +512,7 @@ void nl_link(int ns, unsigned int ifi, void *mac, int up, int mtu) if (mtu) { req.nlh.nlmsg_len = sizeof(req); - req.mtu = mtu; + req.set.mtu = mtu; req.rta.rta_type = IFLA_MTU; req.rta.rta_len = RTA_LENGTH(sizeof(unsigned int)); nl_req(ns, buf, &req, req.nlh.nlmsg_len); @@ -19,7 +19,6 @@ * created in a separate network namespace). */ -#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <sys/epoll.h> @@ -32,15 +31,7 @@ #include <sys/resource.h> #include <sys/uio.h> #include <sys/wait.h> -#include <linux/if_ether.h> -#include <linux/if_packet.h> -#include <linux/ip.h> -#include <linux/ipv6.h> -#include <linux/tcp.h> -#include <linux/udp.h> -#include <linux/icmpv6.h> -#include <linux/un.h> -#include <linux/if_link.h> +#include <netinet/ip.h> #include <net/ethernet.h> #include <stdlib.h> #include <unistd.h> @@ -51,14 +42,20 @@ #include <time.h> #include <syslog.h> #include <sys/stat.h> -#include <linux/seccomp.h> -#include <linux/audit.h> #include <sys/prctl.h> -#include <linux/filter.h> #include <stddef.h> -#include <linux/capability.h> #include <pwd.h> #include <grp.h> +#include <netinet/udp.h> +#include <netinet/tcp.h> +#include <netinet/if_ether.h> + +#include <linux/seccomp.h> +#include <linux/audit.h> +#include <linux/filter.h> +#include <linux/capability.h> +#include <linux/ipv6.h> +#include <linux/icmpv6.h> #include "seccomp.h" #include "util.h" @@ -100,14 +97,14 @@ static void sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, { debug("%s: %s packet from socket %i (events: 0x%08x)", c->mode == MODE_PASST ? "passt" : "pasta", - IP_PROTO_STR(ref.proto), ref.s, events); + IP_PROTO_STR(ref.r.proto), ref.r.s, events); - if (!c->no_tcp && ref.proto == IPPROTO_TCP) + if (!c->no_tcp && ref.r.proto == IPPROTO_TCP) tcp_sock_handler( c, ref, events, now); - else if (!c->no_udp && ref.proto == IPPROTO_UDP) + else if (!c->no_udp && ref.r.proto == IPPROTO_UDP) udp_sock_handler( c, ref, events, now); else if (!c->no_icmp && - (ref.proto == IPPROTO_ICMP || ref.proto == IPPROTO_ICMPV6)) + (ref.r.proto == IPPROTO_ICMP || ref.r.proto == IPPROTO_ICMPV6)) icmp_sock_handler(c, ref, events, now); } @@ -51,8 +51,8 @@ union epoll_ref { union udp_epoll_ref udp; union icmp_epoll_ref icmp; uint32_t data; - }; - }; + } p; + } r; uint64_t u64; }; @@ -15,7 +15,6 @@ * #syscalls:pasta geteuid getdents64 readlink setsid nanosleep clock_nanosleep */ -#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <string.h> @@ -36,6 +35,8 @@ #include <net/ethernet.h> #include <sys/syscall.h> +#include <linux/ipv6.h> + #include "util.h" #include "passt.h" #include "netlink.h" @@ -12,7 +12,6 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ -#define _GNU_SOURCE #include <stdio.h> #include <stddef.h> #include <stdint.h> @@ -29,6 +28,8 @@ #include <unistd.h> #include <net/if.h> +#include <linux/ipv6.h> + #include "util.h" #include "passt.h" @@ -19,14 +19,14 @@ #include <sys/types.h> #include <sys/socket.h> #include <errno.h> -#include <linux/if_ether.h> -#include <linux/ipv6.h> #include <linux/limits.h> -#include <linux/un.h> #include <limits.h> #include <fcntl.h> #include <net/if_arp.h> #include <netinet/in.h> +#include <netinet/if_ether.h> + +#include <linux/ipv6.h> #include "util.h" #include "passt.h" @@ -14,7 +14,6 @@ * #syscalls recvfrom sendto */ -#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <errno.h> @@ -34,14 +33,14 @@ #include <sys/uio.h> #include <stdlib.h> #include <unistd.h> -#include <linux/un.h> -#include <linux/if.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <netinet/ip_icmp.h> +#include <netinet/if_ether.h> + #include <linux/if_tun.h> -#include <linux/ip.h> #include <linux/ipv6.h> -#include <linux/tcp.h> -#include <linux/udp.h> -#include <linux/icmp.h> #include <linux/icmpv6.h> #include "checksum.h" @@ -307,7 +307,6 @@ * #syscalls pipe pipe2 */ -#define _GNU_SOURCE #include <sched.h> #include <fcntl.h> #include <stdio.h> @@ -317,6 +316,7 @@ #include <net/ethernet.h> #include <net/if.h> #include <netinet/in.h> +#include <netinet/ip.h> #include <stdint.h> #include <stddef.h> #include <string.h> @@ -326,11 +326,11 @@ #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> -#include <linux/ip.h> -#include <linux/ipv6.h> -#include <linux/tcp.h> #include <time.h> +#include <linux/ipv6.h> +#include <linux/tcp.h> /* For struct tcp_info */ + #include "checksum.h" #include "util.h" #include "passt.h" @@ -1019,14 +1019,14 @@ static void tcp_sock6_iov_init(void) * tcp_opt_get() - Get option, and value if any, from TCP header * @th: Pointer to TCP header * @len: Length of buffer, including TCP header - * @__type: Option type to look for - * @__optlen: Optional, filled with option length if passed - * @__value: Optional, set to start of option value if passed + * @type: Option type to look for + * @optlen_set: Optional, filled with option length if passed + * @value_set: Optional, set to start of option value if passed * * Return: Option value, meaningful for up to 4 bytes, -1 if not found */ -static int tcp_opt_get(struct tcphdr *th, size_t len, uint8_t __type, - uint8_t *__optlen, char **__value) +static int tcp_opt_get(struct tcphdr *th, size_t len, uint8_t type_search, + uint8_t *optlen_set, char **value_set) { uint8_t type, optlen; char *p; @@ -1049,13 +1049,13 @@ static int tcp_opt_get(struct tcphdr *th, size_t len, uint8_t __type, optlen = *(p++) - 2; len -= 2; - if (type != __type) + if (type != type_search) break; - if (__optlen) - *__optlen = optlen; - if (__value) - *__value = p; + if (optlen_set) + *optlen_set = optlen; + if (value_set) + *value_set = p; switch (optlen) { case 0: @@ -1249,9 +1249,9 @@ static struct tcp_tap_conn *tcp_hash_lookup(struct ctx *c, int af, void *addr, static void tcp_tap_epoll_mask(struct ctx *c, struct tcp_tap_conn *conn, uint32_t events) { - union epoll_ref ref = { .proto = IPPROTO_TCP, .s = conn->sock, - .tcp.index = conn - tt, - .tcp.v6 = CONN_V6(conn) }; + union epoll_ref ref = { .r.proto = IPPROTO_TCP, .r.s = conn->sock, + .r.p.tcp.tcp.index = conn - tt, + .r.p.tcp.tcp.v6 = CONN_V6(conn) }; struct epoll_event ev = { .data.u64 = ref.u64, .events = events }; if (conn->events == events) @@ -1547,7 +1547,7 @@ static int tcp_update_seqack_wnd(struct ctx *c, struct tcp_tap_conn *conn, uint32_t prev_ack_to_tap = conn->seq_ack_to_tap; uint32_t prev_wnd_to_tap = conn->wnd_to_tap; socklen_t sl = sizeof(*info); - struct tcp_info __info; + struct tcp_info info_new; int s = conn->sock; if (conn->state > ESTABLISHED || (flags & (DUP_ACK | FORCE_ACK)) || @@ -1556,7 +1556,7 @@ static int tcp_update_seqack_wnd(struct ctx *c, struct tcp_tap_conn *conn, conn->seq_ack_to_tap = conn->seq_from_tap; } else if (conn->seq_ack_to_tap != conn->seq_from_tap) { if (!info) { - info = &__info; + info = &info_new; if (getsockopt(s, SOL_TCP, TCP_INFO, info, &sl)) return 0; } @@ -1578,7 +1578,7 @@ static int tcp_update_seqack_wnd(struct ctx *c, struct tcp_tap_conn *conn, if (conn->wnd_to_tap > WINDOW_DEFAULT) goto out; - info = &__info; + info = &info_new; if (getsockopt(s, SOL_TCP, TCP_INFO, info, &sl)) goto out; } @@ -1876,6 +1876,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr, struct tcphdr *th, size_t len, struct timespec *now) { + union epoll_ref ref = { .r.proto = IPPROTO_TCP }; struct sockaddr_in addr4 = { .sin_family = AF_INET, .sin_port = th->dest, @@ -1886,7 +1887,6 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr, .sin6_port = th->dest, .sin6_addr = *(struct in6_addr *)addr, }; - union epoll_ref ref = { .proto = IPPROTO_TCP }; int i, s, *sock_pool_p, mss; const struct sockaddr *sa; struct tcp_tap_conn *conn; @@ -1901,15 +1901,16 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr, sock_pool_p = &init_sock_pool6[i]; else sock_pool_p = &init_sock_pool4[i]; - if ((ref.s = s = *sock_pool_p) >= 0) { + if ((ref.r.s = s = *sock_pool_p) >= 0) { *sock_pool_p = -1; break; } } - if (s < 0) - ref.s = s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, - IPPROTO_TCP); + if (s < 0) { + s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); + ref.r.s = s; + } if (s < 0) return; @@ -2016,7 +2017,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr, } conn->events = ev.events; - ref.tcp.index = conn - tt; + ref.r.p.tcp.tcp.index = conn - tt; ev.data.u64 = ref.u64; epoll_ctl(c->epollfd, EPOLL_CTL_ADD, s, &ev); } @@ -2029,10 +2030,12 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr, static void tcp_table_splice_compact(struct ctx *c, struct tcp_splice_conn *hole) { - union epoll_ref ref_from = { .proto = IPPROTO_TCP, .tcp.splice = 1, - .tcp.index = hole - ts }; - union epoll_ref ref_to = { .proto = IPPROTO_TCP, .tcp.splice = 1, - .tcp.index = hole - ts }; + union epoll_ref ref_from = { .r.proto = IPPROTO_TCP, + .r.p.tcp.tcp.splice = 1, + .r.p.tcp.tcp.index = hole - ts }; + union epoll_ref ref_to = { .r.proto = IPPROTO_TCP, + .r.p.tcp.tcp.splice = 1, + .r.p.tcp.tcp.index = hole - ts }; struct tcp_splice_conn *move; struct epoll_event ev_from; struct epoll_event ev_to; @@ -2057,10 +2060,10 @@ static void tcp_table_splice_compact(struct ctx *c, move->state = CLOSED; move = hole; - ref_from.s = move->from; - ref_from.tcp.v6 = move->v6; - ref_to.s = move->to; - ref_to.tcp.v6 = move->v6; + ref_from.r.s = move->from; + ref_from.r.p.tcp.tcp.v6 = move->v6; + ref_to.r.s = move->to; + ref_to.r.p.tcp.tcp.v6 = move->v6; if (move->state == SPLICE_ACCEPTED) { ev_from.events = ev_to.events = 0; @@ -2704,12 +2707,12 @@ static void tcp_connect_finish(struct ctx *c, struct tcp_tap_conn *conn, static void tcp_splice_connect_finish(struct ctx *c, struct tcp_splice_conn *conn, int v6) { - union epoll_ref ref_from = { .proto = IPPROTO_TCP, .s = conn->from, - .tcp = { .splice = 1, .v6 = v6, - .index = conn - ts } }; - union epoll_ref ref_to = { .proto = IPPROTO_TCP, .s = conn->to, - .tcp = { .splice = 1, .v6 = v6, - .index = conn - ts } }; + union epoll_ref ref_from = { .r.proto = IPPROTO_TCP, .r.s = conn->from, + .r.p.tcp.tcp = { .splice = 1, .v6 = v6, + .index = conn - ts } }; + union epoll_ref ref_to = { .r.proto = IPPROTO_TCP, .r.s = conn->to, + .r.p.tcp.tcp = { .splice = 1, .v6 = v6, + .index = conn - ts } }; struct epoll_event ev_from, ev_to; int i; @@ -2764,12 +2767,13 @@ static int tcp_splice_connect(struct ctx *c, struct tcp_splice_conn *conn, int sock_conn = (s >= 0) ? s : socket(v6 ? AF_INET6 : AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); - union epoll_ref ref_accept = { .proto = IPPROTO_TCP, .s = conn->from, - .tcp = { .splice = 1, .v6 = v6, - .index = conn - ts } }; - union epoll_ref ref_conn = { .proto = IPPROTO_TCP, .s = sock_conn, - .tcp = { .splice = 1, .v6 = v6, - .index = conn - ts } }; + union epoll_ref ref_accept = { .r.proto = IPPROTO_TCP, + .r.s = conn->from, + .r.p.tcp.tcp = { .splice = 1, .v6 = v6, + .index = conn - ts } }; + union epoll_ref ref_conn = { .r.proto = IPPROTO_TCP, .r.s = sock_conn, + .r.p.tcp.tcp = { .splice = 1, .v6 = v6, + .index = conn - ts } }; struct epoll_event ev_accept = { .data.u64 = ref_accept.u64 }; struct epoll_event ev_conn = { .data.u64 = ref_conn.u64 }; struct sockaddr_in6 addr6 = { @@ -2901,8 +2905,8 @@ static int tcp_splice_new(struct ctx *c, struct tcp_splice_conn *conn, static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref, struct timespec *now) { - union epoll_ref ref_conn = { .proto = IPPROTO_TCP, - .tcp.v6 = ref.tcp.v6 }; + union epoll_ref ref_conn = { .r.proto = IPPROTO_TCP, + .r.p.tcp.tcp.v6 = ref.r.p.tcp.tcp.v6 }; struct sockaddr_storage sa; struct tcp_tap_conn *conn; struct epoll_event ev; @@ -2913,15 +2917,15 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref, return; sl = sizeof(sa); - s = accept4(ref.s, (struct sockaddr *)&sa, &sl, SOCK_NONBLOCK); + s = accept4(ref.r.s, (struct sockaddr *)&sa, &sl, SOCK_NONBLOCK); if (s < 0) return; conn = &tt[c->tcp.tap_conn_count++]; - ref_conn.tcp.index = conn - tt; - ref_conn.s = conn->sock = s; + ref_conn.r.p.tcp.tcp.index = conn - tt; + ref_conn.r.s = conn->sock = s; - if (ref.tcp.v6) { + if (ref.r.p.tcp.tcp.v6) { struct sockaddr_in6 sa6; memcpy(&sa6, &sa, sizeof(sa6)); @@ -2942,7 +2946,7 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref, memcpy(&conn->a.a6, &sa6.sin6_addr, sizeof(conn->a.a6)); conn->sock_port = ntohs(sa6.sin6_port); - conn->tap_port = ref.tcp.index; + conn->tap_port = ref.r.p.tcp.tcp.index; conn->seq_to_tap = tcp_seq_init(c, AF_INET6, &sa6.sin6_addr, conn->sock_port, @@ -2968,7 +2972,7 @@ static void tcp_conn_from_sock(struct ctx *c, union epoll_ref ref, memcpy(&conn->a.a4.a, &s_addr, sizeof(conn->a.a4.a)); conn->sock_port = ntohs(sa4.sin_port); - conn->tap_port = ref.tcp.index; + conn->tap_port = ref.r.p.tcp.tcp.index; conn->seq_to_tap = tcp_seq_init(c, AF_INET, &s_addr, conn->sock_port, @@ -3014,13 +3018,13 @@ void tcp_sock_handler_splice(struct ctx *c, union epoll_ref ref, struct tcp_splice_conn *conn; struct epoll_event ev; - if (ref.tcp.listen) { + if (ref.r.p.tcp.tcp.listen) { int s, one = 1; if (c->tcp.splice_conn_count >= MAX_SPLICE_CONNS) return; - if ((s = accept4(ref.s, NULL, NULL, SOCK_NONBLOCK)) < 0) + if ((s = accept4(ref.r.s, NULL, NULL, SOCK_NONBLOCK)) < 0) return; setsockopt(s, SOL_TCP, TCP_QUICKACK, &one, sizeof(one)); @@ -3029,13 +3033,14 @@ void tcp_sock_handler_splice(struct ctx *c, union epoll_ref ref, conn->from = s; tcp_splice_state(conn, SPLICE_ACCEPTED); - if (tcp_splice_new(c, conn, ref.tcp.v6, ref.tcp.index)) + if (tcp_splice_new(c, conn, ref.r.p.tcp.tcp.v6, + ref.r.p.tcp.tcp.index)) tcp_splice_destroy(c, conn); return; } - conn = &ts[ref.tcp.index]; + conn = &ts[ref.r.p.tcp.tcp.index]; if (events & EPOLLERR) goto close; @@ -3050,12 +3055,12 @@ void tcp_sock_handler_splice(struct ctx *c, union epoll_ref ref, }; if (conn->state == SPLICE_CONNECT) - tcp_splice_connect_finish(c, conn, ref.tcp.v6); + tcp_splice_connect_finish(c, conn, ref.r.p.tcp.tcp.v6); else if (conn->state == SPLICE_ESTABLISHED) - epoll_ctl(c->epollfd, EPOLL_CTL_MOD, ref.s, &ev); + epoll_ctl(c->epollfd, EPOLL_CTL_MOD, ref.r.s, &ev); - move_to = ref.s; - if (ref.s == conn->to) { + move_to = ref.r.s; + if (ref.r.s == conn->to) { move_from = conn->from; pipes = conn->pipe_from_to; } else { @@ -3063,8 +3068,8 @@ void tcp_sock_handler_splice(struct ctx *c, union epoll_ref ref, pipes = conn->pipe_to_from; } } else { - move_from = ref.s; - if (ref.s == conn->from) { + move_from = ref.r.s; + if (ref.r.s == conn->from) { move_to = conn->to; pipes = conn->pipe_from_to; } else { @@ -3074,7 +3079,7 @@ void tcp_sock_handler_splice(struct ctx *c, union epoll_ref ref, } if (events & EPOLLRDHUP) { - if (ref.s == conn->from) { + if (ref.r.s == conn->from) { if (conn->state == SPLICE_ESTABLISHED) tcp_splice_state(conn, SPLICE_FIN_FROM); else if (conn->state == SPLICE_FIN_TO) @@ -3172,7 +3177,7 @@ eintr: goto retry; ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP; - ref.s = move_to; + ref.r.s = move_to; ev.data.u64 = ref.u64, epoll_ctl(c->epollfd, EPOLL_CTL_MOD, move_to, &ev); break; @@ -3199,7 +3204,7 @@ eintr: conn->from_fin_sent = 1; ev.events = 0; - ref.s = move_from; + ref.r.s = move_from; ev.data.u64 = ref.u64, epoll_ctl(c->epollfd, EPOLL_CTL_MOD, move_from, &ev); @@ -3215,7 +3220,7 @@ eintr: conn->to_fin_sent = 1; ev.events = 0; - ref.s = move_from; + ref.r.s = move_from; ev.data.u64 = ref.u64, epoll_ctl(c->epollfd, EPOLL_CTL_MOD, move_from, &ev); @@ -3258,17 +3263,17 @@ void tcp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, { struct tcp_tap_conn *conn; - if (ref.tcp.splice) { + if (ref.r.p.tcp.tcp.splice) { tcp_sock_handler_splice(c, ref, events); return; } - if (ref.tcp.listen) { + if (ref.r.p.tcp.tcp.listen) { tcp_conn_from_sock(c, ref, now); return; } - conn = &tt[ref.tcp.index]; + conn = &tt[ref.r.p.tcp.tcp.index]; conn->ts_sock_act = *now; @@ -3382,18 +3387,21 @@ smaller: */ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port) { - union tcp_epoll_ref tref = { .listen = 1 }; + union tcp_epoll_ref tref = { .tcp.listen = 1 }; int s; - if (ns) - tref.index = (in_port_t)(port + tcp_port_delta_to_init[port]); - else - tref.index = (in_port_t)(port + tcp_port_delta_to_tap[port]); + if (ns) { + tref.tcp.index = (in_port_t)(port + + tcp_port_delta_to_init[port]); + } else { + tref.tcp.index = (in_port_t)(port + + tcp_port_delta_to_tap[port]); + } if (c->v4) { - tref.v6 = 0; + tref.tcp.v6 = 0; - tref.splice = 0; + tref.tcp.splice = 0; if (!ns) { s = sock_l4(c, AF_INET, IPPROTO_TCP, port, c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY, @@ -3408,7 +3416,7 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port) } if (c->mode == MODE_PASTA) { - tref.splice = 1; + tref.tcp.splice = 1; s = sock_l4(c, AF_INET, IPPROTO_TCP, port, BIND_LOOPBACK, tref.u32); if (s >= 0) @@ -3426,9 +3434,9 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port) } if (c->v6) { - tref.v6 = 1; + tref.tcp.v6 = 1; - tref.splice = 0; + tref.tcp.splice = 0; if (!ns) { s = sock_l4(c, AF_INET6, IPPROTO_TCP, port, c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY, @@ -3443,7 +3451,7 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port) } if (c->mode == MODE_PASTA) { - tref.splice = 1; + tref.tcp.splice = 1; s = sock_l4(c, AF_INET6, IPPROTO_TCP, port, BIND_LOOPBACK, tref.u32); if (s >= 0) @@ -39,7 +39,7 @@ union tcp_epoll_ref { splice:1, v6:1, index:20; - }; + } tcp; uint32_t u32; }; @@ -91,7 +91,6 @@ * - otherwise, discard */ -#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <errno.h> @@ -99,6 +98,8 @@ #include <net/ethernet.h> #include <net/if.h> #include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> #include <stdint.h> #include <stddef.h> #include <string.h> @@ -107,11 +108,10 @@ #include <sys/socket.h> #include <sys/uio.h> #include <unistd.h> -#include <linux/ip.h> -#include <linux/ipv6.h> -#include <linux/udp.h> #include <time.h> +#include <linux/ipv6.h> + #include "checksum.h" #include "util.h" #include "passt.h" @@ -206,7 +206,7 @@ __extension__ static struct udp4_l2_buf_t { udp4_l2_buf[UDP_TAP_FRAMES] = { [ 0 ... UDP_TAP_FRAMES - 1 ] = { { 0 }, 0, 0, L2_BUF_ETH_IP4_INIT, L2_BUF_IP4_INIT(IPPROTO_UDP), - { 0 }, { 0 }, + {{{ 0 }}}, { 0 }, }, }; @@ -245,7 +245,7 @@ udp6_l2_buf[UDP_TAP_FRAMES] = { { 0 }, #endif 0, L2_BUF_ETH_IP6_INIT, L2_BUF_IP6_INIT(IPPROTO_UDP), - { 0 }, { 0 }, + {{{ 0 }}}, { 0 }, }, }; @@ -426,8 +426,8 @@ int udp_splice_connect(struct ctx *c, int v6, int bound_sock, in_port_t src, in_port_t dst, int splice) { struct epoll_event ev = { .events = EPOLLIN | EPOLLRDHUP | EPOLLHUP }; - union epoll_ref ref = { .proto = IPPROTO_UDP, - .udp = { .splice = splice, .v6 = v6 } + union epoll_ref ref = { .r.proto = IPPROTO_UDP, + .r.p.udp.udp = { .splice = splice, .v6 = v6 } }; struct sockaddr_storage sa; struct udp_splice_port *sp; @@ -438,7 +438,7 @@ int udp_splice_connect(struct ctx *c, int v6, int bound_sock, IPPROTO_UDP); if (s < 0) return s; - ref.s = s; + ref.r.s = s; if (v6) { struct sockaddr_in6 addr6 = { @@ -465,15 +465,15 @@ int udp_splice_connect(struct ctx *c, int v6, int bound_sock, struct sockaddr_in6 sa6; memcpy(&sa6, &sa, sizeof(sa6)); - ref.udp.port = ntohs(sa6.sin6_port); + ref.r.p.udp.udp.port = ntohs(sa6.sin6_port); } else { struct sockaddr_in sa4; memcpy(&sa4, &sa, sizeof(sa4)); - ref.udp.port = ntohs(sa4.sin_port); + ref.r.p.udp.udp.port = ntohs(sa4.sin_port); } - sp = &udp_splice_map[v6 ? V6 : V4][ref.udp.port]; + sp = &udp_splice_map[v6 ? V6 : V4][ref.r.p.udp.udp.port]; if (splice == UDP_BACK_TO_INIT) { sp->init_bound_sock = bound_sock; sp->init_dst_port = src; @@ -542,15 +542,15 @@ static int udp_splice_connect_ns(void *arg) static void udp_sock_handler_splice(struct ctx *c, union epoll_ref ref, uint32_t events, struct timespec *now) { + in_port_t src, dst = ref.r.p.udp.udp.port, send_dst = 0; struct msghdr *mh = &udp_splice_mmh_recv[0].msg_hdr; - in_port_t src, dst = ref.udp.port, send_dst = 0; struct sockaddr_storage *sa_s = mh->msg_name; - int s, v6 = ref.udp.v6, n, i; + int s, v6 = ref.r.p.udp.udp.v6, n, i; if (!(events & EPOLLIN)) return; - n = recvmmsg(ref.s, udp_splice_mmh_recv, UDP_SPLICE_FRAMES, 0, NULL); + n = recvmmsg(ref.r.s, udp_splice_mmh_recv, UDP_SPLICE_FRAMES, 0, NULL); if (n <= 0) return; @@ -565,13 +565,13 @@ static void udp_sock_handler_splice(struct ctx *c, union epoll_ref ref, src = ntohs(sa->sin_port); } - switch (ref.udp.splice) { + switch (ref.r.p.udp.udp.splice) { case UDP_TO_NS: src += udp_port_delta_from_init[src]; if (!(s = udp_splice_map[v6][src].ns_conn_sock)) { struct udp_splice_connect_ns_arg arg = { - c, v6, ref.s, src, dst, -1, + c, v6, ref.r.s, src, dst, -1, }; NS_CALL(udp_splice_connect_ns, &arg); @@ -590,7 +590,7 @@ static void udp_sock_handler_splice(struct ctx *c, union epoll_ref ref, src += udp_port_delta_from_tap[src]; if (!(s = udp_splice_map[v6][src].init_conn_sock)) { - s = udp_splice_connect(c, v6, ref.s, src, dst, + s = udp_splice_connect(c, v6, ref.r.s, src, dst, UDP_BACK_TO_NS); if (s < 0) return; @@ -607,7 +607,8 @@ static void udp_sock_handler_splice(struct ctx *c, union epoll_ref ref, return; } - if (ref.udp.splice == UDP_TO_NS || ref.udp.splice == UDP_TO_INIT) { + if (ref.r.p.udp.udp.splice == UDP_TO_NS || + ref.r.p.udp.udp.splice == UDP_TO_INIT) { for (i = 0; i < n; i++) { struct msghdr *mh = &udp_splice_mmh_send[i].msg_hdr; @@ -665,13 +666,13 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, if (events == EPOLLERR) return; - if (ref.udp.splice) { + if (ref.r.p.udp.udp.splice) { udp_sock_handler_splice(c, ref, events, now); return; } - if (ref.udp.v6) { - n = recvmmsg(ref.s, udp6_l2_mh_sock, UDP_TAP_FRAMES, 0, NULL); + if (ref.r.p.udp.udp.v6) { + n = recvmmsg(ref.r.s, udp6_l2_mh_sock, UDP_TAP_FRAMES, 0, NULL); if (n <= 0) return; @@ -719,7 +720,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, } b->uh.source = b->s_in6.sin6_port; - b->uh.dest = htons(ref.udp.port); + b->uh.dest = htons(ref.r.p.udp.udp.port); b->uh.len = b->ip6h.payload_len; b->ip6h.hop_limit = IPPROTO_UDP; @@ -759,7 +760,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, tap_mmh = udp6_l2_mh_tap; } else { - n = recvmmsg(ref.s, udp4_l2_mh_sock, UDP_TAP_FRAMES, 0, NULL); + n = recvmmsg(ref.r.s, udp4_l2_mh_sock, UDP_TAP_FRAMES, 0, NULL); if (n <= 0) return; @@ -798,7 +799,7 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events, udp_update_check4(b); b->uh.source = b->s_in.sin_port; - b->uh.dest = htons(ref.udp.port); + b->uh.dest = htons(ref.r.p.udp.udp.port); b->uh.len = ntohs(udp4_l2_mh_sock[i].msg_len + sizeof(b->uh)); @@ -934,7 +935,8 @@ int udp_tap_handler(struct ctx *c, int af, void *addr, sl = sizeof(s_in); if (!(s = udp_tap_map[V4][src].sock)) { - union udp_epoll_ref uref = { .bound = 1, .port = src }; + union udp_epoll_ref uref = { .udp.bound = 1, + .udp.port = src }; s = sock_l4(c, AF_INET, IPPROTO_UDP, src, 0, uref.u32); if (s <= 0) @@ -975,9 +977,9 @@ int udp_tap_handler(struct ctx *c, int af, void *addr, } if (!(s = udp_tap_map[V6][src].sock)) { - union udp_epoll_ref uref = { .bound = 1, .v6 = 1, - .port = src - }; + union udp_epoll_ref uref = { .udp.bound = 1, + .udp.v6 = 1, + .udp.port = src }; s = sock_l4(c, AF_INET6, IPPROTO_UDP, src, bind_to, uref.u32); @@ -1020,7 +1022,8 @@ int udp_tap_handler(struct ctx *c, int af, void *addr, */ int udp_sock_init_ns(void *arg) { - union udp_epoll_ref uref = { .bound = 1, .splice = UDP_TO_INIT }; + union udp_epoll_ref uref = { .udp.bound = 1, + .udp.splice = UDP_TO_INIT }; struct ctx *c = (struct ctx *)arg; int dst; @@ -1030,16 +1033,16 @@ int udp_sock_init_ns(void *arg) if (!bitmap_isset(c->udp.port_to_init, dst)) continue; - uref.port = dst + udp_port_delta_to_init[dst]; + uref.udp.port = dst + udp_port_delta_to_init[dst]; if (c->v4) { - uref.v6 = 0; + uref.udp.v6 = 0; sock_l4(c, AF_INET, IPPROTO_UDP, dst, BIND_LOOPBACK, uref.u32); } if (c->v6) { - uref.v6 = 1; + uref.udp.v6 = 1; sock_l4(c, AF_INET6, IPPROTO_UDP, dst, BIND_LOOPBACK, uref.u32); } @@ -1109,7 +1112,7 @@ static void udp_splice_iov_init(void) */ int udp_sock_init(struct ctx *c, struct timespec *now) { - union udp_epoll_ref uref = { .bound = 1 }; + union udp_epoll_ref uref = { .udp.bound = 1 }; int dst, s; (void)now; @@ -1118,34 +1121,34 @@ int udp_sock_init(struct ctx *c, struct timespec *now) if (!bitmap_isset(c->udp.port_to_tap, dst)) continue; - uref.port = dst + udp_port_delta_to_tap[dst]; + uref.udp.port = dst + udp_port_delta_to_tap[dst]; if (c->v4) { - uref.splice = 0; - uref.v6 = 0; + uref.udp.splice = 0; + uref.udp.v6 = 0; s = sock_l4(c, AF_INET, IPPROTO_UDP, dst, c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY, uref.u32); if (s > 0) - udp_tap_map[V4][uref.port].sock = s; + udp_tap_map[V4][uref.udp.port].sock = s; if (c->mode == MODE_PASTA) { - uref.splice = UDP_TO_NS; + uref.udp.splice = UDP_TO_NS; sock_l4(c, AF_INET, IPPROTO_UDP, dst, BIND_LOOPBACK, uref.u32); } } if (c->v6) { - uref.splice = 0; - uref.v6 = 1; + uref.udp.splice = 0; + uref.udp.v6 = 1; s = sock_l4(c, AF_INET6, IPPROTO_UDP, dst, c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY, uref.u32); if (s > 0) - udp_tap_map[V6][uref.port].sock = s; + udp_tap_map[V6][uref.udp.port].sock = s; if (c->mode == MODE_PASTA) { - uref.splice = UDP_TO_NS; + uref.udp.splice = UDP_TO_NS; sock_l4(c, AF_INET6, IPPROTO_UDP, dst, BIND_LOOPBACK, uref.u32); } @@ -38,7 +38,7 @@ union udp_epoll_ref { v6:1, port:16; - }; + } udp; uint32_t u32; }; @@ -12,13 +12,11 @@ * Author: Stefano Brivio <sbrivio@redhat.com> */ -#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdint.h> #include <stddef.h> #include <unistd.h> -#include <linux/ipv6.h> #include <arpa/inet.h> #include <net/ethernet.h> #include <net/if.h> @@ -34,6 +32,8 @@ #include <time.h> #include <errno.h> +#include <linux/ipv6.h> + #include "util.h" #include "passt.h" @@ -204,14 +204,16 @@ char *ipv6_l4hdr(struct ipv6hdr *ip6h, uint8_t *proto) int sock_l4(struct ctx *c, int af, uint8_t proto, uint16_t port, enum bind_type bind_addr, uint32_t data) { - union epoll_ref ref = { .proto = proto, .data = data }; + union epoll_ref ref = { .r.proto = proto, .r.p.data = data }; struct sockaddr_in addr4 = { .sin_family = AF_INET, .sin_port = htons(port), + { 0 }, { 0 }, }; struct sockaddr_in6 addr6 = { .sin6_family = AF_INET6, .sin6_port = htons(port), + 0, IN6ADDR_ANY_INIT, 0, }; const struct sockaddr *sa; struct epoll_event ev; @@ -229,7 +231,7 @@ int sock_l4(struct ctx *c, int af, uint8_t proto, uint16_t port, perror("L4 socket"); return -1; } - ref.s = fd; + ref.r.s = fd; if (af == AF_INET) { if (bind_addr == BIND_LOOPBACK) @@ -136,9 +136,7 @@ enum { #define SNDBUF_BIG (4 * 1024 * 1024) #define SNDBUF_SMALL (128 * 1024) -#include <linux/ipv6.h> #include <net/if.h> -#include <linux/ip.h> #include <limits.h> #include <stdarg.h> @@ -151,6 +149,7 @@ enum bind_type { struct ctx; +__attribute__ ((weak)) int ffsl(long int i) { return __builtin_ffsl(i); } void __openlog(const char *ident, int option, int facility); void passt_vsyslog(int pri, const char *format, va_list ap); void __setlogmask(int mask); |