@@ -66,6 +66,7 @@ impl VarkRule {
6666 & self . rule
6767 }
6868}
69+
6970// Varkchain is an iptable chain with extra info
7071pub struct VarkChain < ' a > {
7172 // name of chain
@@ -192,17 +193,23 @@ pub fn create_network_chains(chains: Vec<VarkChain<'_>>) -> NetavarkResult<()> {
192193 Ok ( ( ) )
193194}
194195
195- pub fn get_network_chains < ' a > (
196- conn : & ' a IPTables ,
197- network : IpNet ,
198- network_hash_name : & ' a str ,
199- is_ipv6 : bool ,
200- interface_name : String ,
201- isolation : IsolateOption ,
202- dns_port : u16 ,
203- ) -> Vec < VarkChain < ' a > > {
196+ pub struct NetworkChainConfig {
197+ pub network : IpNet ,
198+ pub network_hash_name : String ,
199+ pub interface_name : String ,
200+ pub isolation : IsolateOption ,
201+ pub dns_port : u16 ,
202+ pub outbound_addr : Option < IpAddr > ,
203+ }
204+
205+ pub fn get_network_chains ( conn : & IPTables , config : NetworkChainConfig ) -> Vec < VarkChain < ' _ > > {
204206 let mut chains = Vec :: new ( ) ;
205- let prefixed_network_hash_name = format ! ( "{}-{}" , "NETAVARK" , network_hash_name) ;
207+ let prefixed_network_hash_name = format ! ( "{}-{}" , "NETAVARK" , config. network_hash_name) ;
208+
209+ let is_ipv6 = match config. network {
210+ IpNet :: V4 ( _) => false ,
211+ IpNet :: V6 ( _) => true ,
212+ } ;
206213
207214 // NETAVARK-HASH
208215 let mut hashed_network_chain = VarkChain :: new (
@@ -214,25 +221,45 @@ pub fn get_network_chains<'a>(
214221 hashed_network_chain. create = true ;
215222
216223 hashed_network_chain. build_rule ( VarkRule :: new (
217- format ! ( "-d {network } -j {ACCEPT}" ) ,
224+ format ! ( "-d {} -j {}" , config . network , ACCEPT ) ,
218225 Some ( TeardownPolicy :: OnComplete ) ,
219226 ) ) ;
220227
221228 let mut multicast_dest = MULTICAST_NET_V4 ;
222229 if is_ipv6 {
223230 multicast_dest = MULTICAST_NET_V6 ;
224231 }
225- hashed_network_chain. build_rule ( VarkRule :: new (
226- format ! ( "! -d {multicast_dest} -j {MASQUERADE}" ) ,
227- Some ( TeardownPolicy :: OnComplete ) ,
228- ) ) ;
232+ if let Some ( addr) = config. outbound_addr {
233+ if !is_ipv6 && addr. is_ipv4 ( ) {
234+ log:: trace!( "Creating SNAT rule with outbound address {}" , addr) ;
235+ hashed_network_chain. build_rule ( VarkRule :: new (
236+ format ! ( "! -d {multicast_dest} -j SNAT --to-source {}" , addr) ,
237+ Some ( TeardownPolicy :: OnComplete ) ,
238+ ) ) ;
239+ } else {
240+ log:: trace!(
241+ "Outbound address {} is not IPv4, using default MASQUERADE rule" ,
242+ addr
243+ ) ;
244+ hashed_network_chain. build_rule ( VarkRule :: new (
245+ format ! ( "! -d {multicast_dest} -j {MASQUERADE}" ) ,
246+ Some ( TeardownPolicy :: OnComplete ) ,
247+ ) ) ;
248+ }
249+ } else {
250+ log:: trace!( "No outbound address set, using default MASQUERADE rule" ) ;
251+ hashed_network_chain. build_rule ( VarkRule :: new (
252+ format ! ( "! -d {multicast_dest} -j {MASQUERADE}" ) ,
253+ Some ( TeardownPolicy :: OnComplete ) ,
254+ ) ) ;
255+ }
229256 chains. push ( hashed_network_chain) ;
230257
231258 // POSTROUTING
232259 let mut postrouting_chain =
233260 VarkChain :: new ( conn, NAT . to_string ( ) , POSTROUTING . to_string ( ) , None ) ;
234261 postrouting_chain. build_rule ( VarkRule :: new (
235- format ! ( "-s {network } -j {prefixed_network_hash_name}" ) ,
262+ format ! ( "-s {} -j {}" , config . network , prefixed_network_hash_name ) ,
236263 Some ( TeardownPolicy :: OnComplete ) ,
237264 ) ) ;
238265 chains. push ( postrouting_chain) ;
@@ -272,7 +299,7 @@ pub fn get_network_chains<'a>(
272299 ) ;
273300 netavark_isolation_chain_3. create = true ;
274301
275- if let IsolateOption :: Normal | IsolateOption :: Strict = isolation {
302+ if let IsolateOption :: Normal | IsolateOption :: Strict = config . isolation {
276303 debug ! ( "Add extra isolate rules" ) ;
277304 // NETAVARK_ISOLATION_1
278305 let mut netavark_isolation_chain_1 = VarkChain :: new (
@@ -290,7 +317,7 @@ pub fn get_network_chains<'a>(
290317 td_policy : Some ( TeardownPolicy :: OnComplete ) ,
291318 } ) ;
292319
293- let netavark_isolation_1_target = if let IsolateOption :: Strict = isolation {
320+ let netavark_isolation_1_target = if let IsolateOption :: Strict = config . isolation {
294321 // NETAVARK_ISOLATION_1 -i bridge_name ! -o bridge_name -j NETAVARK_ISOLATION_3
295322 NETAVARK_ISOLATION_3
296323 } else {
@@ -299,15 +326,16 @@ pub fn get_network_chains<'a>(
299326 } ;
300327 netavark_isolation_chain_1. build_rule ( VarkRule {
301328 rule : format ! (
302- "-i {interface_name} ! -o {interface_name} -j {netavark_isolation_1_target}"
329+ "-i {} ! -o {} -j {}" ,
330+ config. interface_name, config. interface_name, netavark_isolation_1_target
303331 ) ,
304332 position : Some ( ind) ,
305333 td_policy : Some ( TeardownPolicy :: OnComplete ) ,
306334 } ) ;
307335
308336 // NETAVARK_ISOLATION_2 -o bridge_name -j DROP
309337 netavark_isolation_chain_2. build_rule ( VarkRule {
310- rule : format ! ( "-o {} -j {}" , interface_name, "DROP" ) ,
338+ rule : format ! ( "-o {} -j {}" , config . interface_name, "DROP" ) ,
311339 position : Some ( ind) ,
312340 td_policy : Some ( TeardownPolicy :: OnComplete ) ,
313341 } ) ;
@@ -328,7 +356,7 @@ pub fn get_network_chains<'a>(
328356
329357 // NETAVARK_ISOLATION_3 -o bridge_name -j DROP
330358 netavark_isolation_chain_3. build_rule ( VarkRule {
331- rule : format ! ( "-o {} -j {}" , interface_name, "DROP" ) ,
359+ rule : format ! ( "-o {} -j {}" , config . interface_name, "DROP" ) ,
332360 position : Some ( ind) ,
333361 td_policy : Some ( TeardownPolicy :: OnComplete ) ,
334362 } ) ;
@@ -377,7 +405,7 @@ pub fn get_network_chains<'a>(
377405 netavark_input_chain. build_rule ( VarkRule :: new (
378406 format ! (
379407 "-p {} -s {} --dport {} -j {}" ,
380- proto, network, dns_port, ACCEPT
408+ proto, config . network, config . dns_port, ACCEPT
381409 ) ,
382410 Some ( TeardownPolicy :: OnComplete ) ,
383411 ) ) ;
@@ -395,14 +423,17 @@ pub fn get_network_chains<'a>(
395423 // Create incoming traffic rule
396424 // CNI did this by IP address, this is implemented per subnet
397425 netavark_forward_chain. build_rule ( VarkRule :: new (
398- format ! ( "-d {network} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT" ) ,
426+ format ! (
427+ "-d {} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT" ,
428+ config. network
429+ ) ,
399430 Some ( TeardownPolicy :: OnComplete ) ,
400431 ) ) ;
401432
402433 // Create outgoing traffic rule
403434 // CNI did this by IP address, this is implemented per subnet
404435 netavark_forward_chain. build_rule ( VarkRule :: new (
405- format ! ( "-s {network } -j ACCEPT" ) ,
436+ format ! ( "-s {} -j ACCEPT" , config . network ) ,
406437 Some ( TeardownPolicy :: OnComplete ) ,
407438 ) ) ;
408439 chains. push ( netavark_forward_chain) ;
0 commit comments