@@ -212,13 +212,19 @@ pub struct IpRuleGuard {
212212
213213impl IpRuleGuard {
214214 pub fn new ( fwmark : u32 , table : u32 , ip_stack : IPStack ) -> Self {
215- fn update_local_ip_table ( ip_cmd : IPRoute2 , action : Action , table : & str , ip_stack : IPStack ) {
216- let local_ip = match ip_stack {
217- IPStack :: V4 => "0.0.0.0/0" ,
218- IPStack :: V6 => "::/0" ,
219- _ => unreachable ! ( ) ,
220- } ;
215+ let ipv4_cmd = IPRoute2Builder :: new ( ) . cmd_uid ( 0 ) . cmd_gid ( 0 ) . build ( ) ;
216+ let ipv6_cmd = IPRoute2Builder :: new ( ) . ipv6 ( ) . cmd_uid ( 0 ) . cmd_gid ( 0 ) . build ( ) ;
221217
218+ fn update_fwmark ( ip_cmd : & IPRoute2 , action : Action , fwmark : & str , table : & str ) {
219+ ip_cmd
220+ . object ( Object :: rule)
221+ . action ( action)
222+ . run ( [ "fwmark" , fwmark, "table" , table] )
223+ . expect ( "ip {action} rule failed" ) ;
224+ }
225+
226+ fn update_local_ip_table ( ip_cmd : & IPRoute2 , action : Action , table : & str ) {
227+ let local_ip = if ip_cmd. ipv6 { "::/0" } else { "0.0.0.0/0" } ;
222228 ip_cmd
223229 . object ( Object :: route)
224230 . action ( action)
@@ -230,21 +236,17 @@ impl IpRuleGuard {
230236 let thread = std:: thread:: spawn ( move || {
231237 let fwmark = fwmark. to_string ( ) ;
232238 let table = table. to_string ( ) ;
233- let ip_cmd = IPRoute2Builder :: new ( ) . cmd_uid ( 0 ) . cmd_gid ( 0 ) . build ( ) ;
234- ip_cmd
235- . object ( Object :: rule)
236- . add ( )
237- . run ( [ "fwmark" , & fwmark, "table" , & table] )
238- . expect ( "ip add rule failed" ) ;
239239 if ip_stack. has_v4 ( ) {
240- update_local_ip_table ( ip_cmd, Action :: Add , & table, IPStack :: V4 ) ;
240+ update_fwmark ( & ipv4_cmd, Action :: Add , & fwmark, & table) ;
241+ update_local_ip_table ( & ipv4_cmd, Action :: Add , & table) ;
241242 }
242243 if ip_stack. has_v6 ( ) {
243- update_local_ip_table ( ip_cmd, Action :: Add , & table, IPStack :: V6 ) ;
244+ update_fwmark ( & ipv6_cmd, Action :: Add , & fwmark, & table) ;
245+ update_local_ip_table ( & ipv6_cmd, Action :: Add , & table) ;
244246 }
245247
246248 loop {
247- if ip_cmd
249+ if ipv4_cmd
248250 . object ( Object :: rule)
249251 . list ( )
250252 . run ( [ "fwmark" , & fwmark] )
@@ -255,11 +257,12 @@ impl IpRuleGuard {
255257 tracing:: warn!(
256258 "detected disappearing routing policy, possibly due to interruped network, resetting"
257259 ) ;
258- ip_cmd
259- . object ( Object :: rule)
260- . add ( )
261- . run ( [ "fwmark" , & fwmark, "table" , & table] )
262- . expect ( "ip add routing rules failed" ) ;
260+ if ip_stack. has_v4 ( ) {
261+ update_fwmark ( & ipv4_cmd, Action :: Add , & fwmark, & table) ;
262+ }
263+ if ip_stack. has_v6 ( ) {
264+ update_fwmark ( & ipv6_cmd, Action :: Add , & fwmark, & table) ;
265+ }
263266 }
264267 if receiver. recv_timeout ( Duration :: from_secs ( 1 ) ) . is_ok ( ) {
265268 break ;
@@ -278,17 +281,15 @@ impl IpRuleGuard {
278281 x. guard_thread . join ( ) . unwrap ( ) ;
279282 let mark = x. fwmark . to_string ( ) ;
280283 let table = x. table . to_string ( ) ;
281- let ip_cmd = IPRoute2Builder :: new ( ) . cmd_uid ( 0 ) . cmd_gid ( 0 ) . build ( ) ;
282- ip_cmd
283- . object ( Object :: rule)
284- . delete ( )
285- . run ( [ "fwmark" , & mark, "table" , & table] )
286- . expect ( "ip drop routing rules failed" ) ;
287284 if x. ip_stack . has_v4 ( ) {
288- update_local_ip_table ( ip_cmd, Action :: Delete , & table, IPStack :: V4 ) ;
285+ let ipv4_cmd = IPRoute2Builder :: new ( ) . cmd_uid ( 0 ) . cmd_gid ( 0 ) . build ( ) ;
286+ update_fwmark ( & ipv4_cmd, Action :: Delete , & mark, & table) ;
287+ update_local_ip_table ( & ipv4_cmd, Action :: Delete , & table) ;
289288 }
290289 if x. ip_stack . has_v6 ( ) {
291- update_local_ip_table ( ip_cmd, Action :: Delete , & table, IPStack :: V6 ) ;
290+ let ipv6_cmd = IPRoute2Builder :: new ( ) . ipv6 ( ) . cmd_uid ( 0 ) . cmd_gid ( 0 ) . build ( ) ;
291+ update_fwmark ( & ipv6_cmd, Action :: Delete , & mark, & table) ;
292+ update_local_ip_table ( & ipv6_cmd, Action :: Delete , & table) ;
292293 }
293294 } ) ;
294295 Self {
0 commit comments