summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-04-14 16:05:24 +0200
committerDavid Lönnhager <david.l@mullvad.net>2020-06-02 10:05:02 +0200
commita612c583a3a0524ecac09c78f740d4eadad2960a (patch)
tree6af084016d29aba7446263c2d64c77f88881b7eb
parent2b2f27936950e004f24a2861642bd85cff17d82c (diff)
downloadmullvadvpn-a612c583a3a0524ecac09c78f740d4eadad2960a.tar.xz
mullvadvpn-a612c583a3a0524ecac09c78f740d4eadad2960a.zip
Force outgoing packets to use the correct source IP
-rw-r--r--talpid-core/src/firewall/linux.rs17
1 files changed, 17 insertions, 0 deletions
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 47752d0dac..c9e35f9c2f 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -66,6 +66,7 @@ lazy_static! {
static ref MANGLE_TABLE_NAME_V4: CString = CString::new("mullvadmangle4").unwrap();
static ref MANGLE_TABLE_NAME_V6: CString = CString::new("mullvadmangle6").unwrap();
static ref MANGLE_CHAIN_NAME: CString = CString::new("mangle").unwrap();
+ static ref NAT_CHAIN_NAME: CString = CString::new("nat").unwrap();
/// Allows controlling whether firewall rules should have packet counters or not from an env
/// variable. Useful for debugging the rules.
@@ -209,6 +210,7 @@ struct PolicyBatch<'a> {
out_chain: Chain<'a>,
mangle_chain_v4: Chain<'a>,
mangle_chain_v6: Chain<'a>,
+ nat_chain: Chain<'a>,
}
impl<'a> PolicyBatch<'a> {
@@ -242,12 +244,19 @@ impl<'a> PolicyBatch<'a> {
let mangle_chain_v4 = add_mangle_chain(&tables.mangle_v4);
let mangle_chain_v6 = add_mangle_chain(&tables.mangle_v6);
+ let mut nat_chain = Chain::new(&*NAT_CHAIN_NAME, &tables.main);
+ nat_chain.set_hook(nftnl::Hook::PostRouting, libc::NF_IP_PRI_NAT_SRC);
+ nat_chain.set_type(nftnl::ChainType::Nat);
+ nat_chain.set_policy(nftnl::Policy::Accept);
+ batch.add(&nat_chain, nftnl::MsgType::Add);
+
PolicyBatch {
batch,
in_chain,
out_chain,
mangle_chain_v4,
mangle_chain_v6,
+ nat_chain,
}
}
@@ -292,6 +301,14 @@ impl<'a> PolicyBatch<'a> {
rule.add_expr(&nft_expr!(cmp == split::MARK));
add_verdict(&mut rule, &Verdict::Accept);
self.batch.add(&rule, nftnl::MsgType::Add);
+
+ let mut rule = Rule::new(&self.nat_chain);
+ rule.add_expr(&nft_expr!(ct mark));
+ rule.add_expr(&nft_expr!(cmp == split::MARK));
+ // TODO: match oif interface
+ rule.add_expr(&nft_expr!(masquerade));
+ add_verdict(&mut rule, &Verdict::Accept);
+ self.batch.add(&rule, nftnl::MsgType::Add);
}
fn add_loopback_rules(&mut self) -> Result<()> {