mullvadvpn: update to 2025.8-beta1.

This commit is contained in:
dkwo 2025-07-11 17:35:27 -04:00
parent ed01e2f7df
commit e5474a65ed
6 changed files with 4 additions and 514 deletions

View file

@ -1,72 +0,0 @@
From 267087b3255e2748693d52728dadfdd69c6cb761 Mon Sep 17 00:00:00 2001
From: Joakim Hulthe <joakim.hulthe@mullvad.net>
Date: Thu, 19 Jun 2025 15:22:53 +0200
Subject: [PATCH] Do not add split-tunneling fw rules if no net_cls
---
talpid-core/src/firewall/linux.rs | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 26d3a5cb5a68..b72b4c12d6ea 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -12,9 +12,12 @@ use std::{
net::{IpAddr, Ipv4Addr},
sync::LazyLock,
};
-use talpid_types::net::{
- AllowedEndpoint, AllowedTunnelTraffic, Endpoint, TransportProtocol, ALLOWED_LAN_MULTICAST_NETS,
- ALLOWED_LAN_NETS,
+use talpid_types::{
+ cgroup::find_net_cls_mount,
+ net::{
+ AllowedEndpoint, AllowedTunnelTraffic, Endpoint, TransportProtocol,
+ ALLOWED_LAN_MULTICAST_NETS, ALLOWED_LAN_NETS,
+ },
};
/// Priority for rules that tag split tunneling packets. Equals NF_IP_PRI_MANGLE.
@@ -52,6 +55,10 @@ pub enum Error {
/// Unable to translate network interface name into index.
#[error("Unable to translate network interface name \"{0}\" into index")]
LookupIfaceIndexError(String, #[source] crate::linux::IfaceIndexLookupError),
+
+ /// Failed to check if the net_cls mount exists.
+ #[error("An error occurred when checking for net_cls")]
+ FindNetClsMount(#[source] io::Error),
}
/// TODO(linus): This crate is not supposed to be Mullvad-aware. So at some point this should be
@@ -303,7 +310,19 @@ impl<'a> PolicyBatch<'a> {
/// policy.
pub fn finalize(mut self, policy: &FirewallPolicy, fwmark: u32) -> Result<FinalizedBatch> {
self.add_loopback_rules()?;
- self.add_split_tunneling_rules(policy, fwmark)?;
+
+ // if cgroups v1 doesn't exist, split tunneling won't work.
+ // checking if the `net_cls` mount exists is a cheeky way of checking this.
+ if find_net_cls_mount()
+ .map_err(Error::FindNetClsMount)?
+ .is_some()
+ {
+ self.add_split_tunneling_rules(policy, fwmark)?;
+ } else {
+ // skipping add_split_tunneling_rules as it won't cause traffic to leak
+ log::warn!("net_cls mount not found, skipping add_split_tunneling_rules");
+ }
+
self.add_dhcp_client_rules();
self.add_ndp_rules();
self.add_policy_specific_rules(policy, fwmark)?;
@@ -311,6 +330,10 @@ impl<'a> PolicyBatch<'a> {
Ok(self.batch.finalize())
}
+ /// Allow split-tunneled traffic outside the tunnel.
+ ///
+ /// This is acheived by setting `fwmark` on connections initated by processes in the cgroup
+ /// defined by [split_tunnel::NET_CLS_CLASSID].
fn add_split_tunneling_rules(&mut self, policy: &FirewallPolicy, fwmark: u32) -> Result<()> {
// Send select DNS requests in the tunnel
if let FirewallPolicy::Connected {

View file

@ -1,65 +0,0 @@
From 5b62921a73d54fbc43908bce220601a6438993d7 Mon Sep 17 00:00:00 2001
From: Markus Pettersson <markus.pettersson@mullvad.net>
Date: Mon, 30 Jun 2025 22:23:26 +0200
Subject: [PATCH] Fix type error for musl targets
---
talpid-net/src/unix.rs | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/talpid-net/src/unix.rs b/talpid-net/src/unix.rs
index 48d65c45f076..a6e11b196825 100644
--- a/talpid-net/src/unix.rs
+++ b/talpid-net/src/unix.rs
@@ -1,5 +1,7 @@
#![cfg(any(target_os = "linux", target_os = "macos"))]
+#[cfg(target_os = "linux")]
+use std::ffi::c_ulong;
use std::{ffi::c_uint, io, os::fd::AsRawFd};
use nix::{errno::Errno, net::if_::if_nametoindex};
@@ -26,9 +28,9 @@ const SIOCSIFMTU: u64 = 0x80206934;
#[cfg(target_os = "macos")]
const SIOCGIFMTU: u64 = 0xc0206933;
#[cfg(target_os = "linux")]
-const SIOCSIFMTU: u64 = libc::SIOCSIFMTU;
+const SIOCSIFMTU: c_ulong = libc::SIOCSIFMTU;
#[cfg(target_os = "linux")]
-const SIOCGIFMTU: u64 = libc::SIOCSIFMTU;
+const SIOCGIFMTU: c_ulong = libc::SIOCSIFMTU;
pub fn set_mtu(interface_name: &str, mtu: u16) -> Result<(), io::Error> {
let sock = socket2::Socket::new(
@@ -56,8 +58,14 @@ pub fn set_mtu(interface_name: &str, mtu: u16) -> Result<(), io::Error> {
};
ifr.ifr_ifru.ifru_mtu = mtu as i32;
+ // For some reason, libc crate defines ioctl to take a c_int (which is defined as i32), but the c_ulong type is defined as u64:
+ // https://docs.rs/libc/latest/x86_64-unknown-linux-musl/libc/fn.ioctl.html
+ // https://docs.rs/libc/latest/x86_64-unknown-linux-musl/libc/type.c_ulong.html
+ // https://docs.rs/libc/latest/x86_64-unknown-linux-musl/libc/constant.SIOCSIFMTU.html
+ #[allow(clippy::useless_conversion)]
+ let request = SIOCSIFMTU.try_into().unwrap();
// SAFETY: SIOCSIFMTU expects an ifreq with an MTU and interface set
- if unsafe { libc::ioctl(sock.as_raw_fd(), SIOCSIFMTU, &ifr) } < 0 {
+ if unsafe { libc::ioctl(sock.as_raw_fd(), request, &ifr) } < 0 {
let e = std::io::Error::last_os_error();
log::error!("{}", e.display_chain_with_msg("SIOCSIFMTU failed"));
return Err(e);
@@ -90,8 +98,14 @@ pub fn get_mtu(interface_name: &str) -> Result<u16, io::Error> {
)
};
+ // For some reason, libc crate defines ioctl to take a c_int (which is defined as i32), but the c_ulong type is defined as u64:
+ // https://docs.rs/libc/latest/x86_64-unknown-linux-musl/libc/fn.ioctl.html
+ // https://docs.rs/libc/latest/x86_64-unknown-linux-musl/libc/type.c_ulong.html
+ // https://docs.rs/libc/latest/x86_64-unknown-linux-musl/libc/constant.SIOCGIFMTU.html
+ #[allow(clippy::useless_conversion)]
+ let request = SIOCGIFMTU.try_into().unwrap();
// SAFETY: SIOCGIFMTU expects an ifreq with an interface set
- if unsafe { libc::ioctl(sock.as_raw_fd(), SIOCGIFMTU, &ifr) } < 0 {
+ if unsafe { libc::ioctl(sock.as_raw_fd(), request, &ifr) } < 0 {
let e = std::io::Error::last_os_error();
log::error!("{}", e.display_chain_with_msg("SIOCGIFMTU failed"));
return Err(e);

View file

@ -1,167 +0,0 @@
From 69ebc3b8f16d1427c197b2951690bd1f4682362b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20L=C3=B6nnhager?= <david.l@mullvad.net>
Date: Mon, 9 Jun 2025 16:53:47 +0200
Subject: [PATCH] Make daemon start without split tunneling
---
mullvad-daemon/src/lib.rs | 2 +-
talpid-core/src/split_tunnel/linux.rs | 64 +++++++++++++++++++--------
2 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 79fbe1bb7cf0..edb770ec5809 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -945,7 +945,7 @@ impl Daemon {
},
target_state,
#[cfg(target_os = "linux")]
- exclude_pids: split_tunnel::PidManager::new().map_err(Error::InitSplitTunneling)?,
+ exclude_pids: split_tunnel::PidManager::default(),
rx: internal_event_rx,
tx: internal_event_tx,
reconnection_job: None,
diff --git a/talpid-core/src/split_tunnel/linux.rs b/talpid-core/src/split_tunnel/linux.rs
index e96a0293defc..dfbf8fc479a4 100644
--- a/talpid-core/src/split_tunnel/linux.rs
+++ b/talpid-core/src/split_tunnel/linux.rs
@@ -1,7 +1,7 @@
use std::{
env, fs,
io::{self, BufRead, BufReader, Write},
- path::PathBuf,
+ path::{Path, PathBuf},
};
use talpid_types::cgroup::{find_net_cls_mount, SPLIT_TUNNEL_CGROUP_NAME};
@@ -26,6 +26,10 @@ pub enum Error {
#[error("Unable to create cgroup for excluded processes")]
CreateCGroup(#[source] io::Error),
+ /// Split tunneling is unavailable
+ #[error("Failed to set up split tunneling")]
+ Unavailable,
+
/// Unable to set class ID for cgroup.
#[error("Unable to set cgroup class ID")]
SetCGroupClassId(#[source] io::Error),
@@ -49,20 +53,36 @@ pub enum Error {
/// Manages PIDs in the Linux Cgroup excluded from the VPN tunnel.
pub struct PidManager {
- net_cls_path: PathBuf,
+ inner: Inner,
}
-impl PidManager {
+enum Inner {
+ Ok { net_cls_path: PathBuf },
+ Failed { err: Error },
+}
+
+impl Default for PidManager {
/// Creates a new PID Cgroup manager.
///
/// Finds the corresponding Cgroup to use. Will mount a `net_cls` filesystem
/// if none exists.
- pub fn new() -> Result<PidManager, Error> {
- let manager = PidManager {
- net_cls_path: Self::create_cgroup()?,
+ fn default() -> Self {
+ let inner = match Self::new_inner() {
+ Ok(net_cls_path) => Inner::Ok { net_cls_path },
+ Err(err) => {
+ log::error!("{}", err.display_chain_with_msg("Failed to enable split tunneling"));
+ Inner::Failed { err }
+ }
};
- manager.setup_exclusion_group()?;
- Ok(manager)
+ PidManager { inner }
+ }
+}
+
+impl PidManager {
+ fn new_inner() -> Result<PathBuf, Error> {
+ let net_cls_path = Self::create_cgroup()?;
+ Self::setup_exclusion_group(&net_cls_path)?;
+ Ok(net_cls_path)
}
/// Set up cgroup used to track PIDs for split tunneling.
@@ -92,8 +112,8 @@ impl PidManager {
Ok(net_cls_dir)
}
- fn setup_exclusion_group(&self) -> Result<(), Error> {
- let exclusions_dir = self.net_cls_path.join(SPLIT_TUNNEL_CGROUP_NAME);
+ fn setup_exclusion_group(net_cls_path: &Path) -> Result<(), Error> {
+ let exclusions_dir = net_cls_path.join(SPLIT_TUNNEL_CGROUP_NAME);
if !exclusions_dir.exists() {
fs::create_dir(exclusions_dir.clone()).map_err(Error::CreateCGroup)?;
}
@@ -103,10 +123,20 @@ impl PidManager {
.map_err(Error::SetCGroupClassId)
}
+ fn get_net_cls_path(&self) -> Result<&Path, Error> {
+ match &self.inner {
+ Inner::Ok { net_cls_path } => Ok(net_cls_path),
+ Inner::Failed { err } => {
+ log::error!("Failed to get netcls path: {err}");
+ Err(Error::Unavailable)
+ }
+ }
+ }
+
/// Add a PID to the Cgroup to have it excluded from the tunnel.
pub fn add(&self, pid: i32) -> Result<(), Error> {
let exclusions_path = self
- .net_cls_path
+ .get_net_cls_path()?
.join(SPLIT_TUNNEL_CGROUP_NAME)
.join("cgroup.procs");
@@ -125,8 +155,7 @@ impl PidManager {
pub fn remove(&self, pid: i32) -> Result<(), Error> {
// FIXME: We remove PIDs from our cgroup here by adding
// them to the parent cgroup. This seems wrong.
- let mut file = self
- .open_parent_cgroup_handle()
+ let mut file = Self::open_parent_cgroup_handle(self.get_net_cls_path()?)
.map_err(Error::RemoveCGroupPid)?;
file.write_all(pid.to_string().as_bytes())
@@ -136,7 +165,7 @@ impl PidManager {
/// Return a list of all PIDs currently in the Cgroup excluded from the tunnel.
pub fn list(&self) -> Result<Vec<i32>, Error> {
let exclusions_path = self
- .net_cls_path
+ .get_net_cls_path()?
.join(SPLIT_TUNNEL_CGROUP_NAME)
.join("cgroup.procs");
@@ -158,8 +187,7 @@ impl PidManager {
pub fn clear(&self) -> Result<(), Error> {
let pids = self.list()?;
- let mut file = self
- .open_parent_cgroup_handle()
+ let mut file = Self::open_parent_cgroup_handle(self.get_net_cls_path()?)
.map_err(Error::RemoveCGroupPid)?;
for pid in pids {
file.write_all(pid.to_string().as_bytes())
@@ -169,11 +197,11 @@ impl PidManager {
Ok(())
}
- fn open_parent_cgroup_handle(&self) -> io::Result<fs::File> {
+ fn open_parent_cgroup_handle(net_cls_path: &Path) -> io::Result<fs::File> {
fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(false)
- .open(self.net_cls_path.join("cgroup.procs"))
+ .open(net_cls_path.join("cgroup.procs"))
}
}

View file

@ -1,143 +0,0 @@
From a33f5961780f4d3831fc4a1ddf72b433e3fb4740 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20L=C3=B6nnhager?= <david.l@mullvad.net>
Date: Tue, 10 Jun 2025 09:36:48 +0200
Subject: [PATCH] Add RPC for checking if split tunneling is available on Linux
---
.../packages/mullvad-vpn/src/main/daemon-rpc.ts | 5 +++++
mullvad-daemon/src/lib.rs | 11 +++++++++++
mullvad-daemon/src/management_interface.rs | 15 +++++++++++++++
.../proto/management_interface.proto | 1 +
talpid-core/src/split_tunnel/linux.rs | 15 +++++++++++++--
5 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/desktop/packages/mullvad-vpn/src/main/daemon-rpc.ts b/desktop/packages/mullvad-vpn/src/main/daemon-rpc.ts
index d0d424418616..206070598c25 100644
--- a/desktop/packages/mullvad-vpn/src/main/daemon-rpc.ts
+++ b/desktop/packages/mullvad-vpn/src/main/daemon-rpc.ts
@@ -510,6 +510,11 @@ export class DaemonRpc extends GrpcClient {
await this.callBool(this.client.setSplitTunnelState, enabled);
}
+ public async splitTunnelIsEnabled(): Promise<boolean> {
+ const isEnabled = await this.callEmpty<BoolValue>(this.client.splitTunnelIsEnabled);
+ return isEnabled.getValue();
+ }
+
public async needFullDiskPermissions(): Promise<boolean> {
const needFullDiskPermissions = await this.callEmpty<BoolValue>(
this.client.needFullDiskPermissions,
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index edb770ec5809..70db828aa3aa 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -344,6 +344,9 @@ pub enum DaemonCommand {
/// Remove settings and clear the cache
#[cfg(not(target_os = "android"))]
FactoryReset(ResponseTx<(), Error>),
+ /// Return whether split tunneling is available
+ #[cfg(target_os = "linux")]
+ SplitTunnelIsEnabled(oneshot::Sender<bool>),
/// Request list of processes excluded from the tunnel
#[cfg(target_os = "linux")]
GetSplitTunnelProcesses(ResponseTx<Vec<i32>, split_tunnel::Error>),
@@ -1454,6 +1457,8 @@ impl Daemon {
#[cfg(not(target_os = "android"))]
FactoryReset(tx) => self.on_factory_reset(tx).await,
#[cfg(target_os = "linux")]
+ SplitTunnelIsEnabled(tx) => self.on_split_tunnel_is_enabled(tx),
+ #[cfg(target_os = "linux")]
GetSplitTunnelProcesses(tx) => self.on_get_split_tunnel_processes(tx),
#[cfg(target_os = "linux")]
AddSplitTunnelProcess(tx, pid) => self.on_add_split_tunnel_process(tx, pid),
@@ -2029,6 +2034,12 @@ impl Daemon {
}));
}
+ #[cfg(target_os = "linux")]
+ fn on_split_tunnel_is_enabled(&mut self, tx: oneshot::Sender<bool>) {
+ let enabled = self.exclude_pids.is_enabled();
+ Self::oneshot_send(tx, enabled, "split_tunnel_is_enabled response");
+ }
+
#[cfg(target_os = "linux")]
fn on_get_split_tunnel_processes(&mut self, tx: ResponseTx<Vec<i32>, split_tunnel::Error>) {
let result = self.exclude_pids.list().inspect_err(|error| {
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 7beadb3ddd38..5695683fcf15 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -833,6 +833,21 @@ impl ManagementService for ManagementServiceImpl {
// Split tunneling
//
+ async fn split_tunnel_is_enabled(&self, _: Request<()>) -> ServiceResult<bool> {
+ #[cfg(target_os = "linux")]
+ {
+ log::debug!("split_tunnel_is_enabled");
+ let (tx, rx) = oneshot::channel();
+ self.send_command_to_daemon(DaemonCommand::SplitTunnelIsEnabled(tx))?;
+ Ok(self.wait_for_result(rx).await.map(Response::new)?)
+ }
+ #[cfg(not(target_os = "linux"))]
+ {
+ log::error!("split_tunnel_is_enabled is only available on Linux");
+ Ok(Response::new(false))
+ }
+ }
+
async fn get_split_tunnel_processes(
&self,
_: Request<()>,
diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto
index f3be6708220e..ab9883c1efdd 100644
--- a/mullvad-management-interface/proto/management_interface.proto
+++ b/mullvad-management-interface/proto/management_interface.proto
@@ -97,6 +97,7 @@ service ManagementService {
rpc TestApiAccessMethodById(UUID) returns (google.protobuf.BoolValue) {}
// Split tunneling (Linux)
+ rpc SplitTunnelIsEnabled(google.protobuf.Empty) returns (google.protobuf.BoolValue) {}
rpc GetSplitTunnelProcesses(google.protobuf.Empty) returns (stream google.protobuf.Int32Value) {}
rpc AddSplitTunnelProcess(google.protobuf.Int32Value) returns (google.protobuf.Empty) {}
rpc RemoveSplitTunnelProcess(google.protobuf.Int32Value) returns (google.protobuf.Empty) {}
diff --git a/talpid-core/src/split_tunnel/linux.rs b/talpid-core/src/split_tunnel/linux.rs
index dfbf8fc479a4..1efb1dc60bf0 100644
--- a/talpid-core/src/split_tunnel/linux.rs
+++ b/talpid-core/src/split_tunnel/linux.rs
@@ -3,7 +3,10 @@ use std::{
io::{self, BufRead, BufReader, Write},
path::{Path, PathBuf},
};
-use talpid_types::cgroup::{find_net_cls_mount, SPLIT_TUNNEL_CGROUP_NAME};
+use talpid_types::{
+ cgroup::{find_net_cls_mount, SPLIT_TUNNEL_CGROUP_NAME},
+ ErrorExt,
+};
const DEFAULT_NET_CLS_DIR: &str = "/sys/fs/cgroup/net_cls";
const NET_CLS_DIR_OVERRIDE_ENV_VAR: &str = "TALPID_NET_CLS_MOUNT_DIR";
@@ -70,7 +73,10 @@ impl Default for PidManager {
let inner = match Self::new_inner() {
Ok(net_cls_path) => Inner::Ok { net_cls_path },
Err(err) => {
- log::error!("{}", err.display_chain_with_msg("Failed to enable split tunneling"));
+ log::error!(
+ "{}",
+ err.display_chain_with_msg("Failed to enable split tunneling")
+ );
Inner::Failed { err }
}
};
@@ -197,6 +203,11 @@ impl PidManager {
Ok(())
}
+ /// Return whether it is enabled
+ pub fn is_enabled(&self) -> bool {
+ matches!(self.inner, Inner::Ok { .. })
+ }
+
fn open_parent_cgroup_handle(net_cls_path: &Path) -> io::Result<fs::File> {
fs::OpenOptions::new()
.write(true)

View file

@ -1,63 +0,0 @@
From ecd6066dabb3ff321bedc2b025ad76bb99622836 Mon Sep 17 00:00:00 2001
From: Markus Pettersson <markus.pettersson@mullvad.net>
Date: Fri, 4 Jul 2025 21:12:51 +0200
Subject: [PATCH] Add musl as a target ABI for wireguard-go-rs
Do not assume target ABI to be glibc. The current solution is not
directly extensible by the user, but it easily could be if we really
wanted to. At least we don't break cross-compilation to musl targets
though.
---
wireguard-go-rs/build.rs | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/wireguard-go-rs/build.rs b/wireguard-go-rs/build.rs
index a544e4e161e1..8978bef7b5b3 100644
--- a/wireguard-go-rs/build.rs
+++ b/wireguard-go-rs/build.rs
@@ -53,6 +53,14 @@ enum AndroidTarget {
I686, // "i686"
}
+#[derive(PartialEq, Eq, Clone, Copy)]
+enum Libc {
+ /// glibc
+ Gnu,
+ /// musl libc
+ Musl,
+}
+
impl AndroidTarget {
fn from_str(input: &str) -> anyhow::Result<Self> {
use AndroidTarget::*;
@@ -113,6 +121,16 @@ fn target_arch() -> anyhow::Result<Arch> {
}
}
+// https://doc.rust-lang.org/reference/conditional-compilation.html#target_env
+fn target_libc() -> anyhow::Result<Libc> {
+ let target_arch = env::var("CARGO_CFG_TARGET_ENV").context("Missing 'CARGO_CFG_TARGET_ENV")?;
+ match target_arch.as_str() {
+ "gnu" => Ok(Libc::Gnu),
+ "musl" => Ok(Libc::Musl),
+ _ => bail!("Unsupported target ABI/libc: {target_arch}"),
+ }
+}
+
/// Compile libwg and maybenot and place them in the target dir relative to `OUT_DIR`.
fn build_windows_dynamic_lib(out_dir: &str) -> anyhow::Result<()> {
let target_dir = Path::new(out_dir)
@@ -179,9 +197,10 @@ fn build_linux_static_lib(out_dir: &str) -> anyhow::Result<()> {
};
if is_cross_compiling()? {
- match target_arch {
- Arch::Arm64 => go_build.env("CC", "aarch64-linux-gnu-gcc"),
- Arch::Amd64 => bail!("cross-compiling to linux x86_64 is not implemented"),
+ match (target_arch, target_libc()?) {
+ (Arch::Arm64, Libc::Gnu) => go_build.env("CC", "aarch64-linux-gnu-gcc"),
+ (Arch::Arm64, Libc::Musl) => go_build.env("CC", "aarch64-linux-musl-gcc"),
+ (Arch::Amd64, _) => bail!("cross-compiling to linux x86_64 is not implemented"),
};
}

View file

@ -1,6 +1,6 @@
# Template file for 'mullvadvpn'
pkgname=mullvadvpn
version=2025.7
version=2025.8
revision=1
_wggover=0.0.20230223-mullvad-0.1.6
# archs set by upstream
@ -15,7 +15,7 @@ make_build_args="
-p talpid-openvpn-plugin --lib
-p mullvad-exclude --bin mullvad-exclude
-p mullvad-api --bin relay_list"
make_check_args="-- --skip version_check"
make_check_args="-- --skip version"
hostmakedepends="pkg-config go git protobuf protobuf-devel"
makedepends="dbus-devel libnftnl-devel"
short_desc="Mullvad VPN client app (cli only)"
@ -23,9 +23,9 @@ maintainer="dkwo <npiazza@disroot.org>"
license="GPL-3.0-or-later"
homepage="https://mullvad.net/"
changelog="https://raw.githubusercontent.com/mullvad/mullvadvpn-app/refs/heads/main/CHANGELOG.md"
distfiles="https://github.com/mullvad/mullvadvpn-app/archive/refs/tags/${version}.tar.gz
distfiles="https://github.com/mullvad/mullvadvpn-app/archive/refs/tags/${version}-beta1.tar.gz
https://github.com/mullvad/wireguard-go/archive/refs/tags/${_wggover}.tar.gz"
checksum="0231665feed54636fe088c18fdff08d2381cbbcb8f6c0ea97990b3b9d9438500
checksum="f2ef1d7d47b988c7b5803a23a29d75b94b943cc85185f0133e05685ec5eff71d
fd9fa45155098223a17ea934eaa6eb44ee990cd2a7ab638bce482f62fd8502e8"
skip_extraction="${_wggover}.tar.gz"
system_accounts="_mullvad"