mirror of https://passt.top/passt
Compare commits
12 Commits
4988e2b406
...
954589b64b
Author | SHA1 | Date |
---|---|---|
David Gibson | 954589b64b | |
David Gibson | 489b28e216 | |
David Gibson | f9fe3ae5dd | |
David Gibson | e8b78217bb | |
David Gibson | ef2cb13b49 | |
David Gibson | 97e8b33f87 | |
David Gibson | 67a6258918 | |
Stefano Brivio | f4e38b5cd2 | |
Danish Prakash | 88c2f08eba | |
Stefano Brivio | 100919ce74 | |
Stefano Brivio | dc7b7f28b7 | |
Stefano Brivio | bbea2752f6 |
2
Makefile
2
Makefile
|
@ -308,4 +308,4 @@ cppcheck: $(SRCS) $(HEADERS)
|
|||
--inline-suppr \
|
||||
--suppress=unusedStructMember \
|
||||
$(filter -D%,$(FLAGS) $(CFLAGS) $(CPPFLAGS)) \
|
||||
.
|
||||
$(SRCS) $(HEADERS)
|
||||
|
|
|
@ -342,16 +342,18 @@ speeding up local connections, and usually requiring NAT. _pasta_:
|
|||
|
||||
### Availability
|
||||
* 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))
|
||||
* ✅ [CentOS Stream](https://gitlab.com/redhat/centos-stream/rpms/passt)
|
||||
* ✅ [Debian](https://tracker.debian.org/pkg/passt)
|
||||
* ✅ [Fedora](https://src.fedoraproject.org/rpms/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)
|
||||
* ✅ [Void Linux](https://voidlinux.org/packages/?q=passt)
|
||||
* unofficial packages for:
|
||||
* ✅ [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
|
||||
static builds for other RPM-based distributions
|
||||
* ✅ unofficial [packages](https://passt.top/builds/latest/x86_64/) from x86_64
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
/ r, # isolate_prefork(), isolation.c
|
||||
mount options=(rw, runbindable) /,
|
||||
mount "" -> "/",
|
||||
mount "" -> "/tmp/",
|
||||
pivot_root "/tmp/" -> "/tmp/",
|
||||
umount "/",
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
@{PROC}/@{pid}/net/udp 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/user r, # conf_pasta_ns()
|
||||
|
||||
|
@ -42,3 +43,5 @@
|
|||
/{usr/,}bin/** Ux,
|
||||
|
||||
/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 \
|
||||
{ .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) \
|
||||
{ \
|
||||
.version = 4, \
|
||||
|
@ -40,6 +45,10 @@
|
|||
#define L2_BUF_IP4_PSUM(proto) ((uint32_t)htons_constant(0x4500) + \
|
||||
(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) \
|
||||
{ \
|
||||
.priority = 0, \
|
||||
|
|
34
netlink.c
34
netlink.c
|
@ -33,6 +33,7 @@
|
|||
#include "util.h"
|
||||
#include "passt.h"
|
||||
#include "log.h"
|
||||
#include "ip.h"
|
||||
#include "netlink.h"
|
||||
|
||||
/* 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));
|
||||
nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) {
|
||||
struct rtmsg *rtm = (struct rtmsg *)NLMSG_DATA(nh);
|
||||
const void *dst = NULL;
|
||||
unsigned thisifi = 0;
|
||||
|
||||
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);
|
||||
thisifi = rtnh->rtnh_ifindex;
|
||||
} else if (rta->rta_type == RTA_DST) {
|
||||
dst = RTA_DATA(rta);
|
||||
}
|
||||
}
|
||||
|
||||
if (!thisifi)
|
||||
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) {
|
||||
/* Default route */
|
||||
ndef++;
|
||||
|
@ -309,7 +322,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
|||
if (defifi) {
|
||||
if (ndef > 1)
|
||||
info("Multiple default %s routes, picked first",
|
||||
af == AF_INET ? "IPv4" : "IPv6");
|
||||
af_name(af));
|
||||
return defifi;
|
||||
}
|
||||
|
||||
|
@ -318,11 +331,11 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
|
|||
return anyifi;
|
||||
|
||||
info("Multiple interfaces with %s routes, use -i to select one",
|
||||
af == AF_INET ? "IPv4" : "IPv6");
|
||||
af_name(af));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
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) {
|
||||
/* 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;
|
||||
} 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) {
|
||||
/* Host routes might include a preferred source
|
||||
* 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
|
||||
PRE='
|
||||
struct sock_filter filter_@PROFILE@[] = {
|
||||
/* cppcheck-suppress badBitmaskCheck */
|
||||
/* cppcheck-suppress [badBitmaskCheck, unmatchedSuppression] */
|
||||
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
|
||||
(offsetof(struct seccomp_data, arch))),
|
||||
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,
|
||||
(offsetof(struct seccomp_data, nr))),
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
test_logs/
|
||||
mbuto/
|
||||
podman/
|
||||
*.img
|
||||
QEMU_EFI.fd
|
||||
*.qcow2
|
||||
|
|
|
@ -52,10 +52,10 @@ UBUNTU_NEW_IMGS = xenial-server-cloudimg-powerpc-disk1.img \
|
|||
jammy-server-cloudimg-s390x.img
|
||||
UBUNTU_IMGS = $(UBUNTU_OLD_IMGS) $(UBUNTU_NEW_IMGS)
|
||||
|
||||
DOWNLOAD_ASSETS = mbuto \
|
||||
DOWNLOAD_ASSETS = mbuto podman \
|
||||
$(DEBIAN_IMGS) $(FEDORA_IMGS) $(OPENSUSE_IMGS) $(UBUNTU_IMGS)
|
||||
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-%) \
|
||||
$(UBUNTU_NEW_IMGS:%=prepared-%) \
|
||||
nstool guest-key guest-key.pub \
|
||||
|
@ -67,13 +67,27 @@ CFLAGS = -Wall -Werror -Wextra -pedantic -std=c99
|
|||
|
||||
assets: $(ASSETS)
|
||||
|
||||
.PHONY: pull-%
|
||||
pull-%: %
|
||||
git -C $* pull
|
||||
|
||||
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:
|
||||
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.mem.img: passt.mem.mbuto mbuto ../passt.avx2
|
||||
|
|
|
@ -11,11 +11,16 @@
|
|||
# Copyright (c) 2022 Red Hat GmbH
|
||||
# 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
|
||||
|
||||
host git -C __STATEDIR__ clone https://github.com/containers/podman.git
|
||||
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
|
||||
host PODMAN="__PODMAN__" CONTAINERS_HELPER_BINARY_DIR="__WD__" bats test/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_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
|
||||
* @a: Minued, unsigned value < @m
|
||||
|
|
Loading…
Reference in New Issue