@@ -16,13 +16,42 @@ use std::{
1616 net:: { IpAddr , Ipv4Addr } ,
1717 str:: FromStr ,
1818} ;
19- use tracing:: { debug, info, instrument, span, trace, Level } ;
19+ use tracing:: { debug, error , info, instrument, span, trace, Level } ;
2020
2121// ns-client ns-rattan ns-server
2222// +-----------+ veth pair +--------------------+ veth pair +-----------+
2323// | rc-left| <-------------> |rc-right [P] rs-left| <-------------> |rs-right |
24- // | .11.1/24 | |.11.2/24 .12.2/24 | |.12.1/24 |
24+ // | .11.x/32 | |.11.2/32 .12.2/32 | |.12.x/32 |
2525// +-----------+ +--------------------+ +-----------+
26+ //
27+ // Use /32 to avoid route conflict between multiple rattan instances
28+ //
29+
30+ fn get_addresses_in_use ( ) -> Vec < IpAddr > {
31+ debug ! ( "Get addresses in use" ) ;
32+ let rt = tokio:: runtime:: Builder :: new_current_thread ( )
33+ . enable_all ( )
34+ . build ( )
35+ . unwrap ( ) ;
36+ let _guard = rt. enter ( ) ;
37+ let ( conn, rtnl_handle, _) = rtnetlink:: new_connection ( ) . unwrap ( ) ;
38+ rt. spawn ( conn) ;
39+
40+ let mut addresses = vec ! [ ] ;
41+ rt. block_on ( async {
42+ let mut links = rtnl_handle. address ( ) . get ( ) . execute ( ) ;
43+ while let Ok ( Some ( address_msg) ) = links. try_next ( ) . await {
44+ for address_attr in address_msg. attributes {
45+ if let AddressAttribute :: Address ( address) = address_attr {
46+ debug ! ( ?address, ?address_msg. header. prefix_len, "Get address" ) ;
47+ addresses. push ( address) ;
48+ }
49+ }
50+ }
51+ } ) ;
52+ debug ! ( ?addresses, "Addresses in use" ) ;
53+ addresses
54+ }
2655
2756lazy_static:: lazy_static! {
2857 static ref STD_ENV_LOCK : Arc <parking_lot:: Mutex <( ) >> = Arc :: new( parking_lot:: Mutex :: new( ( ) ) ) ;
@@ -59,6 +88,7 @@ pub struct StdNetEnv {
5988#[ instrument( skip_all, level = "debug" ) ]
6089pub fn get_std_env ( config : StdNetEnvConfig ) -> anyhow:: Result < StdNetEnv > {
6190 trace ! ( ?config) ;
91+ get_addresses_in_use ( ) ;
6292 let _guard = STD_ENV_LOCK . lock ( ) ;
6393 let rand_string: String = thread_rng ( )
6494 . sample_iter ( & Alphanumeric )
@@ -79,19 +109,45 @@ pub fn get_std_env(config: StdNetEnvConfig) -> anyhow::Result<StdNetEnv> {
79109 let rattan_netns = NetNs :: new ( & rattan_netns_name) ?;
80110 trace ! ( ?rattan_netns, "Rattan netns {} created" , rattan_netns_name) ;
81111
112+ // Get server veth address
113+ let veth_addr_suffix = match config. mode {
114+ StdNetEnvMode :: Compatible => {
115+ let addresses_in_use = get_addresses_in_use ( ) ;
116+ let mut addr_suffix = 1 ;
117+ while addresses_in_use. contains ( & IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 12 , addr_suffix) ) )
118+ || addresses_in_use. contains ( & IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 11 , addr_suffix) ) )
119+ {
120+ addr_suffix += 1 ;
121+ if addr_suffix == 2 {
122+ addr_suffix += 1 ;
123+ }
124+ if addr_suffix == 255 {
125+ error ! ( "No available address suffix for server veth" ) ;
126+ return Err ( anyhow:: anyhow!(
127+ "No available address suffix for server veth"
128+ ) ) ;
129+ }
130+ }
131+ addr_suffix
132+ }
133+ _ => 1 ,
134+ } ;
82135 let veth_pair_client = VethPairBuilder :: new ( )
83136 . name (
84137 format ! ( "rc-left-{}" , rand_string) ,
85138 format ! ( "rc-right-{}" , rand_string) ,
86139 )
87140 . namespace ( Some ( client_netns. clone ( ) ) , Some ( rattan_netns. clone ( ) ) )
88141 . mac_addr (
89- [ 0x38 , 0x7e , 0x58 , 0xe7 , 0x87 , 0x2a ] . into ( ) ,
90- [ 0x38 , 0x7e , 0x58 , 0xe7 , 0x87 , 0x2b ] . into ( ) ,
142+ [ 0x38 , 0x7e , 0x58 , 0xe7 , 11 , veth_addr_suffix ] . into ( ) ,
143+ [ 0x38 , 0x7e , 0x58 , 0xe7 , 11 , 2 ] . into ( ) ,
91144 )
92145 . ip_addr (
93- ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 11 , 1 ) ) , 24 ) ,
94- ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 11 , 2 ) ) , 24 ) ,
146+ (
147+ IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 11 , veth_addr_suffix) ) ,
148+ 32 ,
149+ ) ,
150+ ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 11 , 2 ) ) , 32 ) ,
95151 )
96152 . build ( ) ?;
97153
@@ -102,12 +158,15 @@ pub fn get_std_env(config: StdNetEnvConfig) -> anyhow::Result<StdNetEnv> {
102158 )
103159 . namespace ( Some ( rattan_netns. clone ( ) ) , Some ( server_netns. clone ( ) ) )
104160 . mac_addr (
105- [ 0x38 , 0x7e , 0x58 , 0xe7 , 0x87 , 0x2c ] . into ( ) ,
106- [ 0x38 , 0x7e , 0x58 , 0xe7 , 0x87 , 0x2d ] . into ( ) ,
161+ [ 0x38 , 0x7e , 0x58 , 0xe7 , 12 , 2 ] . into ( ) ,
162+ [ 0x38 , 0x7e , 0x58 , 0xe7 , 12 , veth_addr_suffix ] . into ( ) ,
107163 )
108164 . ip_addr (
109- ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 12 , 2 ) ) , 24 ) ,
110- ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 12 , 1 ) ) , 24 ) ,
165+ ( IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 12 , 2 ) ) , 32 ) ,
166+ (
167+ IpAddr :: V4 ( Ipv4Addr :: new ( 192 , 168 , 12 , veth_addr_suffix) ) ,
168+ 32 ,
169+ ) ,
111170 )
112171 . build ( ) ?;
113172
0 commit comments