@@ -66,6 +66,7 @@ impl VarkRule {
66
66
& self . rule
67
67
}
68
68
}
69
+
69
70
// Varkchain is an iptable chain with extra info
70
71
pub struct VarkChain < ' a > {
71
72
// name of chain
@@ -192,17 +193,23 @@ pub fn create_network_chains(chains: Vec<VarkChain<'_>>) -> NetavarkResult<()> {
192
193
Ok ( ( ) )
193
194
}
194
195
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 < ' _ > > {
204
206
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
+ } ;
206
213
207
214
// NETAVARK-HASH
208
215
let mut hashed_network_chain = VarkChain :: new (
@@ -214,25 +221,45 @@ pub fn get_network_chains<'a>(
214
221
hashed_network_chain. create = true ;
215
222
216
223
hashed_network_chain. build_rule ( VarkRule :: new (
217
- format ! ( "-d {network } -j {ACCEPT}" ) ,
224
+ format ! ( "-d {} -j {}" , config . network , ACCEPT ) ,
218
225
Some ( TeardownPolicy :: OnComplete ) ,
219
226
) ) ;
220
227
221
228
let mut multicast_dest = MULTICAST_NET_V4 ;
222
229
if is_ipv6 {
223
230
multicast_dest = MULTICAST_NET_V6 ;
224
231
}
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
+ }
229
256
chains. push ( hashed_network_chain) ;
230
257
231
258
// POSTROUTING
232
259
let mut postrouting_chain =
233
260
VarkChain :: new ( conn, NAT . to_string ( ) , POSTROUTING . to_string ( ) , None ) ;
234
261
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 ) ,
236
263
Some ( TeardownPolicy :: OnComplete ) ,
237
264
) ) ;
238
265
chains. push ( postrouting_chain) ;
@@ -272,7 +299,7 @@ pub fn get_network_chains<'a>(
272
299
) ;
273
300
netavark_isolation_chain_3. create = true ;
274
301
275
- if let IsolateOption :: Normal | IsolateOption :: Strict = isolation {
302
+ if let IsolateOption :: Normal | IsolateOption :: Strict = config . isolation {
276
303
debug ! ( "Add extra isolate rules" ) ;
277
304
// NETAVARK_ISOLATION_1
278
305
let mut netavark_isolation_chain_1 = VarkChain :: new (
@@ -290,7 +317,7 @@ pub fn get_network_chains<'a>(
290
317
td_policy : Some ( TeardownPolicy :: OnComplete ) ,
291
318
} ) ;
292
319
293
- let netavark_isolation_1_target = if let IsolateOption :: Strict = isolation {
320
+ let netavark_isolation_1_target = if let IsolateOption :: Strict = config . isolation {
294
321
// NETAVARK_ISOLATION_1 -i bridge_name ! -o bridge_name -j NETAVARK_ISOLATION_3
295
322
NETAVARK_ISOLATION_3
296
323
} else {
@@ -299,15 +326,16 @@ pub fn get_network_chains<'a>(
299
326
} ;
300
327
netavark_isolation_chain_1. build_rule ( VarkRule {
301
328
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
303
331
) ,
304
332
position : Some ( ind) ,
305
333
td_policy : Some ( TeardownPolicy :: OnComplete ) ,
306
334
} ) ;
307
335
308
336
// NETAVARK_ISOLATION_2 -o bridge_name -j DROP
309
337
netavark_isolation_chain_2. build_rule ( VarkRule {
310
- rule : format ! ( "-o {} -j {}" , interface_name, "DROP" ) ,
338
+ rule : format ! ( "-o {} -j {}" , config . interface_name, "DROP" ) ,
311
339
position : Some ( ind) ,
312
340
td_policy : Some ( TeardownPolicy :: OnComplete ) ,
313
341
} ) ;
@@ -328,7 +356,7 @@ pub fn get_network_chains<'a>(
328
356
329
357
// NETAVARK_ISOLATION_3 -o bridge_name -j DROP
330
358
netavark_isolation_chain_3. build_rule ( VarkRule {
331
- rule : format ! ( "-o {} -j {}" , interface_name, "DROP" ) ,
359
+ rule : format ! ( "-o {} -j {}" , config . interface_name, "DROP" ) ,
332
360
position : Some ( ind) ,
333
361
td_policy : Some ( TeardownPolicy :: OnComplete ) ,
334
362
} ) ;
@@ -377,7 +405,7 @@ pub fn get_network_chains<'a>(
377
405
netavark_input_chain. build_rule ( VarkRule :: new (
378
406
format ! (
379
407
"-p {} -s {} --dport {} -j {}" ,
380
- proto, network, dns_port, ACCEPT
408
+ proto, config . network, config . dns_port, ACCEPT
381
409
) ,
382
410
Some ( TeardownPolicy :: OnComplete ) ,
383
411
) ) ;
@@ -395,14 +423,17 @@ pub fn get_network_chains<'a>(
395
423
// Create incoming traffic rule
396
424
// CNI did this by IP address, this is implemented per subnet
397
425
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
+ ) ,
399
430
Some ( TeardownPolicy :: OnComplete ) ,
400
431
) ) ;
401
432
402
433
// Create outgoing traffic rule
403
434
// CNI did this by IP address, this is implemented per subnet
404
435
netavark_forward_chain. build_rule ( VarkRule :: new (
405
- format ! ( "-s {network } -j ACCEPT" ) ,
436
+ format ! ( "-s {} -j ACCEPT" , config . network ) ,
406
437
Some ( TeardownPolicy :: OnComplete ) ,
407
438
) ) ;
408
439
chains. push ( netavark_forward_chain) ;
0 commit comments