mirror of
https://passt.top/passt
synced 2024-11-10 14:40:17 +00:00
Compare commits
12 Commits
4988e2b406
...
954589b64b
Author | SHA1 | Date | |
---|---|---|---|
|
954589b64b | ||
|
489b28e216 | ||
|
f9fe3ae5dd | ||
|
e8b78217bb | ||
|
ef2cb13b49 | ||
|
97e8b33f87 | ||
|
67a6258918 | ||
|
f4e38b5cd2 | ||
|
88c2f08eba | ||
|
100919ce74 | ||
|
dc7b7f28b7 | ||
|
bbea2752f6 |
2
Makefile
2
Makefile
@ -308,4 +308,4 @@ cppcheck: $(SRCS) $(HEADERS)
|
|||||||
--inline-suppr \
|
--inline-suppr \
|
||||||
--suppress=unusedStructMember \
|
--suppress=unusedStructMember \
|
||||||
$(filter -D%,$(FLAGS) $(CFLAGS) $(CPPFLAGS)) \
|
$(filter -D%,$(FLAGS) $(CFLAGS) $(CPPFLAGS)) \
|
||||||
.
|
$(SRCS) $(HEADERS)
|
||||||
|
@ -342,16 +342,18 @@ speeding up local connections, and usually requiring NAT. _pasta_:
|
|||||||
|
|
||||||
### Availability
|
### Availability
|
||||||
* official packages for:
|
* official packages for:
|
||||||
|
* ✅ [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=passt)
|
||||||
* ✅ [Arch Linux](https://archlinux.org/packages/extra/x86_64/passt/) ([aarch64](https://archlinuxarm.org/packages/aarch64/passt), [i486](https://www.archlinux32.org/packages/?q=passt))
|
* ✅ [Arch Linux](https://archlinux.org/packages/extra/x86_64/passt/) ([aarch64](https://archlinuxarm.org/packages/aarch64/passt), [i486](https://www.archlinux32.org/packages/?q=passt))
|
||||||
* ✅ [CentOS Stream](https://gitlab.com/redhat/centos-stream/rpms/passt)
|
* ✅ [CentOS Stream](https://gitlab.com/redhat/centos-stream/rpms/passt)
|
||||||
* ✅ [Debian](https://tracker.debian.org/pkg/passt)
|
* ✅ [Debian](https://tracker.debian.org/pkg/passt)
|
||||||
* ✅ [Fedora](https://src.fedoraproject.org/rpms/passt)
|
* ✅ [Fedora](https://src.fedoraproject.org/rpms/passt)
|
||||||
* ✅ [Gentoo](https://packages.gentoo.org/packages/net-misc/passt)
|
* ✅ [Gentoo](https://packages.gentoo.org/packages/net-misc/passt)
|
||||||
|
* ✅ [GNU Guix](https://packages.guix.gnu.org/packages/passt/)
|
||||||
|
* ✅ [OpenSUSE](https://build.opensuse.org/package/requests/Virtualization:containers/passt)
|
||||||
* ✅ [Ubuntu](https://launchpad.net/ubuntu/+source/passt)
|
* ✅ [Ubuntu](https://launchpad.net/ubuntu/+source/passt)
|
||||||
* ✅ [Void Linux](https://voidlinux.org/packages/?q=passt)
|
* ✅ [Void Linux](https://voidlinux.org/packages/?q=passt)
|
||||||
* unofficial packages for:
|
* unofficial packages for:
|
||||||
* ✅ [EPEL, Mageia](https://copr.fedorainfracloud.org/coprs/sbrivio/passt/)
|
* ✅ [EPEL, Mageia](https://copr.fedorainfracloud.org/coprs/sbrivio/passt/)
|
||||||
* 🛠 [openSUSE](https://build.opensuse.org/package/show/Virtualization:containers/passt)
|
|
||||||
* ✅ unofficial [packages](https://passt.top/builds/latest/x86_64/) from x86_64
|
* ✅ unofficial [packages](https://passt.top/builds/latest/x86_64/) from x86_64
|
||||||
static builds for other RPM-based distributions
|
static builds for other RPM-based distributions
|
||||||
* ✅ unofficial [packages](https://passt.top/builds/latest/x86_64/) from x86_64
|
* ✅ unofficial [packages](https://passt.top/builds/latest/x86_64/) from x86_64
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
/ r, # isolate_prefork(), isolation.c
|
/ r, # isolate_prefork(), isolation.c
|
||||||
mount options=(rw, runbindable) /,
|
mount options=(rw, runbindable) /,
|
||||||
|
mount "" -> "/",
|
||||||
mount "" -> "/tmp/",
|
mount "" -> "/tmp/",
|
||||||
pivot_root "/tmp/" -> "/tmp/",
|
pivot_root "/tmp/" -> "/tmp/",
|
||||||
umount "/",
|
umount "/",
|
||||||
|
@ -27,8 +27,9 @@
|
|||||||
@{PROC}/@{pid}/net/udp r,
|
@{PROC}/@{pid}/net/udp r,
|
||||||
@{PROC}/@{pid}/net/udp6 r,
|
@{PROC}/@{pid}/net/udp6 r,
|
||||||
|
|
||||||
@{run}/user/@{uid}/netns/* r, # pasta_open_ns(), pasta.c
|
@{run}/user/@{uid}/** rw, # pasta_open_ns(), main()
|
||||||
|
|
||||||
|
@{PROC}/[0-9]*/ns/ r, # pasta_netns_quit_init(),
|
||||||
@{PROC}/[0-9]*/ns/net r, # pasta_wait_for_ns(),
|
@{PROC}/[0-9]*/ns/net r, # pasta_wait_for_ns(),
|
||||||
@{PROC}/[0-9]*/ns/user r, # conf_pasta_ns()
|
@{PROC}/[0-9]*/ns/user r, # conf_pasta_ns()
|
||||||
|
|
||||||
@ -42,3 +43,5 @@
|
|||||||
/{usr/,}bin/** Ux,
|
/{usr/,}bin/** Ux,
|
||||||
|
|
||||||
/usr/bin/pasta.avx2 ix, # arch_avx2_exec(), arch.c
|
/usr/bin/pasta.avx2 ix, # arch_avx2_exec(), arch.c
|
||||||
|
|
||||||
|
ptrace r, # pasta_open_ns()
|
||||||
|
9
ip.h
9
ip.h
@ -24,6 +24,11 @@
|
|||||||
#define IN4ADDR_ANY_INIT \
|
#define IN4ADDR_ANY_INIT \
|
||||||
{ .s_addr = htonl_constant(INADDR_ANY) }
|
{ .s_addr = htonl_constant(INADDR_ANY) }
|
||||||
|
|
||||||
|
#define IN4_IS_ADDR_LINKLOCAL(a) \
|
||||||
|
((ntohl(((struct in_addr *)(a))->s_addr) >> 16) == 0xa9fe)
|
||||||
|
#define IN4_IS_PREFIX_LINKLOCAL(a, len) \
|
||||||
|
((len) >= 16 && IN4_IS_ADDR_LINKLOCAL(a))
|
||||||
|
|
||||||
#define L2_BUF_IP4_INIT(proto) \
|
#define L2_BUF_IP4_INIT(proto) \
|
||||||
{ \
|
{ \
|
||||||
.version = 4, \
|
.version = 4, \
|
||||||
@ -40,6 +45,10 @@
|
|||||||
#define L2_BUF_IP4_PSUM(proto) ((uint32_t)htons_constant(0x4500) + \
|
#define L2_BUF_IP4_PSUM(proto) ((uint32_t)htons_constant(0x4500) + \
|
||||||
(uint32_t)htons(0xff00 | (proto)))
|
(uint32_t)htons(0xff00 | (proto)))
|
||||||
|
|
||||||
|
|
||||||
|
#define IN6_IS_PREFIX_LINKLOCAL(a, len) \
|
||||||
|
((len) >= 10 && IN6_IS_ADDR_LINKLOCAL(a))
|
||||||
|
|
||||||
#define L2_BUF_IP6_INIT(proto) \
|
#define L2_BUF_IP6_INIT(proto) \
|
||||||
{ \
|
{ \
|
||||||
.priority = 0, \
|
.priority = 0, \
|
||||||
|
34
netlink.c
34
netlink.c
@ -33,6 +33,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "passt.h"
|
#include "passt.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "ip.h"
|
||||||
#include "netlink.h"
|
#include "netlink.h"
|
||||||
|
|
||||||
/* Netlink expects a buffer of at least 8kiB or the system page size,
|
/* Netlink expects a buffer of at least 8kiB or the system page size,
|
||||||
@ -270,6 +271,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
|||||||
seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req));
|
seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req));
|
||||||
nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) {
|
nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) {
|
||||||
struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh);
|
struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh);
|
||||||
|
const void *dst = NULL;
|
||||||
unsigned thisifi = 0;
|
unsigned thisifi = 0;
|
||||||
|
|
||||||
if (rtm->rtm_family != af)
|
if (rtm->rtm_family != af)
|
||||||
@ -284,12 +286,23 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
|||||||
|
|
||||||
rtnh = (struct rtnexthop *)RTA_DATA(rta);
|
rtnh = (struct rtnexthop *)RTA_DATA(rta);
|
||||||
thisifi = rtnh->rtnh_ifindex;
|
thisifi = rtnh->rtnh_ifindex;
|
||||||
|
} else if (rta->rta_type == RTA_DST) {
|
||||||
|
dst = RTA_DATA(rta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thisifi)
|
if (!thisifi)
|
||||||
continue; /* No interface for this route */
|
continue; /* No interface for this route */
|
||||||
|
|
||||||
|
/* Skip routes to link-local addresses */
|
||||||
|
if (af == AF_INET && dst &&
|
||||||
|
IN4_IS_PREFIX_LINKLOCAL(dst, rtm->rtm_dst_len))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (af == AF_INET6 && dst &&
|
||||||
|
IN6_IS_PREFIX_LINKLOCAL(dst, rtm->rtm_dst_len))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (rtm->rtm_dst_len == 0) {
|
if (rtm->rtm_dst_len == 0) {
|
||||||
/* Default route */
|
/* Default route */
|
||||||
ndef++;
|
ndef++;
|
||||||
@ -309,7 +322,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
|||||||
if (defifi) {
|
if (defifi) {
|
||||||
if (ndef > 1)
|
if (ndef > 1)
|
||||||
info("Multiple default %s routes, picked first",
|
info("Multiple default %s routes, picked first",
|
||||||
af == AF_INET ? "IPv4" : "IPv6");
|
af_name(af));
|
||||||
return defifi;
|
return defifi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,11 +331,11 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
|||||||
return anyifi;
|
return anyifi;
|
||||||
|
|
||||||
info("Multiple interfaces with %s routes, use -i to select one",
|
info("Multiple interfaces with %s routes, use -i to select one",
|
||||||
af == AF_INET ? "IPv4" : "IPv6");
|
af_name(af));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nany)
|
if (!nany)
|
||||||
info("No interfaces with %s routes", af == AF_INET ? "IPv4" : "IPv6");
|
info("No interfaces with usable %s routes", af_name(af));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -546,12 +559,19 @@ int nl_route_dup(int s_src, unsigned int ifi_src,
|
|||||||
|
|
||||||
for (rta = RTM_RTA(rtm), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
|
for (rta = RTM_RTA(rtm), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
|
||||||
rta = RTA_NEXT(rta, na)) {
|
rta = RTA_NEXT(rta, na)) {
|
||||||
|
/* RTA_OIF and RTA_MULTIPATH attributes carry the
|
||||||
|
* identifier of a host interface. Change them to match
|
||||||
|
* the corresponding identifier in the target namespace.
|
||||||
|
*/
|
||||||
if (rta->rta_type == RTA_OIF) {
|
if (rta->rta_type == RTA_OIF) {
|
||||||
/* The host obviously list's the host interface
|
|
||||||
* id here, we need to change it to the
|
|
||||||
* namespace's interface id
|
|
||||||
*/
|
|
||||||
*(unsigned int *)RTA_DATA(rta) = ifi_dst;
|
*(unsigned int *)RTA_DATA(rta) = ifi_dst;
|
||||||
|
} else if (rta->rta_type == RTA_MULTIPATH) {
|
||||||
|
struct rtnexthop *rtnh;
|
||||||
|
|
||||||
|
for (rtnh = (struct rtnexthop *)RTA_DATA(rta);
|
||||||
|
RTNH_OK(rtnh, RTA_PAYLOAD(rta));
|
||||||
|
rtnh = RTNH_NEXT(rtnh))
|
||||||
|
rtnh->rtnh_ifindex = ifi_dst;
|
||||||
} else if (rta->rta_type == RTA_PREFSRC) {
|
} else if (rta->rta_type == RTA_PREFSRC) {
|
||||||
/* Host routes might include a preferred source
|
/* Host routes might include a preferred source
|
||||||
* address, which must be one of the host's
|
* address, which must be one of the host's
|
||||||
|
@ -29,11 +29,11 @@ HEADER="/* This file was automatically generated by $(basename ${0}) */
|
|||||||
# Prefix for each profile: check that 'arch' in seccomp_data is matching
|
# Prefix for each profile: check that 'arch' in seccomp_data is matching
|
||||||
PRE='
|
PRE='
|
||||||
struct sock_filter filter_@PROFILE@[] = {
|
struct sock_filter filter_@PROFILE@[] = {
|
||||||
/* cppcheck-suppress badBitmaskCheck */
|
/* cppcheck-suppress [badBitmaskCheck, unmatchedSuppression] */
|
||||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
||||||
(offsetof(struct seccomp_data, arch))),
|
(offsetof(struct seccomp_data, arch))),
|
||||||
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, PASST_AUDIT_ARCH, 0, @KILL@),
|
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, PASST_AUDIT_ARCH, 0, @KILL@),
|
||||||
/* cppcheck-suppress badBitmaskCheck */
|
/* cppcheck-suppress [badBitmaskCheck, unmatchedSuppression] */
|
||||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
||||||
(offsetof(struct seccomp_data, nr))),
|
(offsetof(struct seccomp_data, nr))),
|
||||||
|
|
||||||
|
1
test/.gitignore
vendored
1
test/.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
test_logs/
|
test_logs/
|
||||||
mbuto/
|
mbuto/
|
||||||
|
podman/
|
||||||
*.img
|
*.img
|
||||||
QEMU_EFI.fd
|
QEMU_EFI.fd
|
||||||
*.qcow2
|
*.qcow2
|
||||||
|
@ -52,10 +52,10 @@ UBUNTU_NEW_IMGS = xenial-server-cloudimg-powerpc-disk1.img \
|
|||||||
jammy-server-cloudimg-s390x.img
|
jammy-server-cloudimg-s390x.img
|
||||||
UBUNTU_IMGS = $(UBUNTU_OLD_IMGS) $(UBUNTU_NEW_IMGS)
|
UBUNTU_IMGS = $(UBUNTU_OLD_IMGS) $(UBUNTU_NEW_IMGS)
|
||||||
|
|
||||||
DOWNLOAD_ASSETS = mbuto \
|
DOWNLOAD_ASSETS = mbuto podman \
|
||||||
$(DEBIAN_IMGS) $(FEDORA_IMGS) $(OPENSUSE_IMGS) $(UBUNTU_IMGS)
|
$(DEBIAN_IMGS) $(FEDORA_IMGS) $(OPENSUSE_IMGS) $(UBUNTU_IMGS)
|
||||||
TESTDATA_ASSETS = small.bin big.bin medium.bin
|
TESTDATA_ASSETS = small.bin big.bin medium.bin
|
||||||
LOCAL_ASSETS = mbuto.img mbuto.mem.img QEMU_EFI.fd \
|
LOCAL_ASSETS = mbuto.img mbuto.mem.img podman/bin/podman QEMU_EFI.fd \
|
||||||
$(DEBIAN_IMGS:%=prepared-%) $(FEDORA_IMGS:%=prepared-%) \
|
$(DEBIAN_IMGS:%=prepared-%) $(FEDORA_IMGS:%=prepared-%) \
|
||||||
$(UBUNTU_NEW_IMGS:%=prepared-%) \
|
$(UBUNTU_NEW_IMGS:%=prepared-%) \
|
||||||
nstool guest-key guest-key.pub \
|
nstool guest-key guest-key.pub \
|
||||||
@ -67,13 +67,27 @@ CFLAGS = -Wall -Werror -Wextra -pedantic -std=c99
|
|||||||
|
|
||||||
assets: $(ASSETS)
|
assets: $(ASSETS)
|
||||||
|
|
||||||
|
.PHONY: pull-%
|
||||||
|
pull-%: %
|
||||||
|
git -C $* pull
|
||||||
|
|
||||||
mbuto:
|
mbuto:
|
||||||
git clone git://mbuto.sh/mbuto
|
git clone git://mbuto.sh/mbuto
|
||||||
|
|
||||||
|
mbuto/mbuto: pull-mbuto
|
||||||
|
|
||||||
|
podman:
|
||||||
|
git clone https://github.com/containers/podman.git
|
||||||
|
|
||||||
|
# To succesfully build podman, you will need gpgme and systemd
|
||||||
|
# development packages
|
||||||
|
podman/bin/podman: pull-podman
|
||||||
|
$(MAKE) -C podman
|
||||||
|
|
||||||
guest-key guest-key.pub:
|
guest-key guest-key.pub:
|
||||||
ssh-keygen -f guest-key -N ''
|
ssh-keygen -f guest-key -N ''
|
||||||
|
|
||||||
mbuto.img: passt.mbuto mbuto guest-key.pub $(TESTDATA_ASSETS)
|
mbuto.img: passt.mbuto mbuto/mbuto guest-key.pub $(TESTDATA_ASSETS)
|
||||||
./mbuto/mbuto -p ./$< -c lz4 -f $@
|
./mbuto/mbuto -p ./$< -c lz4 -f $@
|
||||||
|
|
||||||
mbuto.mem.img: passt.mem.mbuto mbuto ../passt.avx2
|
mbuto.mem.img: passt.mem.mbuto mbuto ../passt.avx2
|
||||||
|
@ -11,11 +11,16 @@
|
|||||||
# Copyright (c) 2022 Red Hat GmbH
|
# Copyright (c) 2022 Red Hat GmbH
|
||||||
# Author: Stefano Brivio <sbrivio@redhat.com>
|
# Author: Stefano Brivio <sbrivio@redhat.com>
|
||||||
|
|
||||||
htools git make go bats catatonit ip jq socat
|
htools git make go bats ip jq socat ./test/podman/bin/podman
|
||||||
|
|
||||||
|
set PODMAN test/podman/bin/podman
|
||||||
|
hout WD pwd
|
||||||
|
|
||||||
|
test Podman pasta path
|
||||||
|
|
||||||
|
hout PASTA_BIN CONTAINERS_HELPER_BINARY_DIR="__WD__" __PODMAN__ info --format "{{.Host.Pasta.Executable}}"
|
||||||
|
check [ "__PASTA_BIN__" = "__WD__/pasta" ]
|
||||||
|
|
||||||
test Podman system test with bats
|
test Podman system test with bats
|
||||||
|
|
||||||
host git -C __STATEDIR__ clone https://github.com/containers/podman.git
|
host PODMAN="__PODMAN__" CONTAINERS_HELPER_BINARY_DIR="__WD__" bats test/podman/test/system/505-networking-pasta.bats
|
||||||
host make -C __STATEDIR__/podman
|
|
||||||
hout WD pwd
|
|
||||||
host PODMAN="__STATEDIR__/podman/bin/podman" CONTAINERS_HELPER_BINARY_DIR="__WD__" bats __STATEDIR__/podman/test/system/505-networking-pasta.bats
|
|
||||||
|
18
util.h
18
util.h
@ -156,6 +156,24 @@ int fls(unsigned long x);
|
|||||||
int write_file(const char *path, const char *buf);
|
int write_file(const char *path, const char *buf);
|
||||||
int write_remainder(int fd, const struct iovec *iov, int iovcnt, size_t skip);
|
int write_remainder(int fd, const struct iovec *iov, int iovcnt, size_t skip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* af_name() - Return name of an address family
|
||||||
|
* @af: Address/protocol family (AF_INET or AF_INET6)
|
||||||
|
*
|
||||||
|
* Returns: Name of the protocol family as a string
|
||||||
|
*/
|
||||||
|
static inline const char *af_name(sa_family_t af)
|
||||||
|
{
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
return "IPv4";
|
||||||
|
case AF_INET6:
|
||||||
|
return "IPv6";
|
||||||
|
default:
|
||||||
|
return "<unknown address family>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mod_sub() - Modular arithmetic subtraction
|
* mod_sub() - Modular arithmetic subtraction
|
||||||
* @a: Minued, unsigned value < @m
|
* @a: Minued, unsigned value < @m
|
||||||
|
Loading…
Reference in New Issue
Block a user