11use std:: process:: Command ;
2- use std:: net:: Ipv4Addr ;
32
4- use anyhow:: { anyhow, Result } ;
3+ use anyhow:: { anyhow, Context , Result } ;
54use default_net;
65use pnet:: datalink:: NetworkInterface ;
76use pnet:: ipnetwork:: { IpNetwork , Ipv4Network } ;
@@ -88,7 +87,10 @@ impl NetEnv {
8887 } ;
8988 let save = format ! ( "ip route save table all > {}" , & self . ip_route_store) ;
9089 let save_dns = "cp /etc/resolv.conf /etc/resolv.conf.bak" ;
91- let net: Ipv4Network = self . ip . parse ( ) . unwrap ( ) ;
90+ let net: Ipv4Network = self
91+ . ip
92+ . parse ( )
93+ . context ( format ! ( "ip {} parsed error" , self . ip) ) ?;
9294 let net_ip32 = net. ip ( ) . to_string ( ) + "/32" ;
9395 let rp_filter_br2 = format ! ( "net.ipv4.conf.{}.rp_filter=0" , & self . bridge2) ;
9496 let rp_filter_v2 = format ! ( "net.ipv4.conf.{}.rp_filter=0" , & self . veth2) ;
@@ -115,6 +117,7 @@ impl NetEnv {
115117 ip_address( "del" , & self . ip, & self . device) ,
116118 ip_address( "add" , & self . ip, & self . veth4) ,
117119 arp_set( & gateway_ip, & gateway_mac, & self . veth1) ,
120+ arp_set( & gateway_ip, & gateway_mac, & self . veth4) ,
118121 ip_netns( & self . netns, arp_set( & gateway_ip, & gateway_mac, & self . veth2) ) ,
119122 ip_netns(
120123 & self . netns,
@@ -174,36 +177,42 @@ impl NetEnv {
174177 ) ,
175178 ] ;
176179 execute_all ( cmdvv) ?;
180+ let interfaces = pnet:: datalink:: interfaces ( ) ;
181+ let veth4_mac = interfaces
182+ . iter ( )
183+ . find ( |p| p. name == self . veth4 )
184+ . context ( format ! ( "interface {} not found" , self . veth4. clone( ) ) ) ?
185+ . mac
186+ . context ( format ! ( "mac {} not found" , self . veth4. clone( ) ) ) ?
187+ . to_string ( ) ;
188+ let _ = execute ( ip_netns (
189+ & self . netns ,
190+ arp_set ( & net. ip ( ) . to_string ( ) , & veth4_mac, & self . bridge2 ) ,
191+ ) ) ?;
177192 Ok ( ( ) )
178193 }
179194
180195 pub fn clear_bridge ( & self ) -> Result < ( ) > {
181196 let restore_dns = "cp /etc/resolv.conf.bak /etc/resolv.conf" ;
182197 let remove_store = format ! ( "rm -f {}" , & self . ip_route_store) ;
183198
184- let net: Ipv4Network = self . ip . parse ( ) . unwrap ( ) ;
185- let net_domain = Ipv4Addr :: from ( u32:: from ( net. ip ( ) ) & u32:: from ( net. mask ( ) ) ) . to_string ( )
186- + "/"
187- + & net. prefix ( ) . to_string ( ) ;
188- let del_default_route = format ! ( "ip route del {} dev {} proto kernel scope link src {}" , & net_domain, & self . device, & net. ip( ) . to_string( ) ) ;
199+ let flush_main_route = "ip route flush table main" ;
189200
190201 let cmdvv = vec ! [
191202 ip_netns_del( & self . netns) ,
192203 ip_link_del_bridge( & self . bridge1) ,
193204 ip_address( "add" , & self . ip, & self . device) ,
194205 bash_c( restore_dns) ,
195- bash_c( & del_default_route ) ,
206+ bash_c( flush_main_route ) ,
196207 clear_ebtables( ) ,
197208 ] ;
198209 execute_all_with_log_error ( cmdvv) ?;
199210
200- let ip_routes= restore_all_ip_routes ( & self . ip_route_store ) ?;
211+ let ip_routes = restore_all_ip_routes ( & self . ip_route_store ) ?;
201212 let iproute_cmds: Vec < Vec < & str > > = ip_routes. iter ( ) . map ( |s| bash_c ( & * * s) ) . collect ( ) ;
202213 execute_all_with_log_error ( iproute_cmds) ?;
203214
204- let cmdvv = vec ! [
205- bash_c( & remove_store) ,
206- ] ;
215+ let cmdvv = vec ! [ bash_c( & remove_store) ] ;
207216 execute_all_with_log_error ( cmdvv) ?;
208217 Ok ( ( ) )
209218 }
@@ -346,7 +355,13 @@ pub fn execute(cmdv: Vec<&str>) -> Result<()> {
346355 for s in iter {
347356 cmd. arg ( * s) ;
348357 }
349- os_err ( cmd. output ( ) . unwrap ( ) . stderr )
358+ let out = cmd
359+ . output ( )
360+ . context ( format ! ( "cmd output meet error : {:?}" , cmdv) ) ?;
361+ if !out. stdout . is_empty ( ) {
362+ tracing:: debug!( "stdout : {}" , String :: from_utf8_lossy( & out. stdout) ) ;
363+ }
364+ os_err ( out. stderr )
350365}
351366
352367pub fn get_interface ( name : String ) -> Result < NetworkInterface > {
@@ -369,11 +384,10 @@ pub fn get_default_interface() -> Result<NetworkInterface> {
369384 Err ( anyhow ! ( "no valid interface" ) )
370385}
371386
372- pub fn restore_all_ip_routes ( path : & str ) -> Result < Vec < String > > {
387+ pub fn restore_all_ip_routes ( path : & str ) -> Result < Vec < String > > {
373388 let cmd_string = format ! ( "ip route showdump < {}" , path) ;
374389 let mut cmd = Command :: new ( "sh" ) ;
375- cmd. arg ( "-c" )
376- . arg ( cmd_string) ;
390+ cmd. arg ( "-c" ) . arg ( cmd_string) ;
377391 let stdo = cmd. output ( ) ?. stdout ;
378392 let out = String :: from_utf8_lossy ( stdo. as_slice ( ) ) ;
379393
0 commit comments