rust_rsm/net_ext/
iprt.rs

1#![allow(non_snake_case)]
2#![allow(non_upper_case_globals)]
3#![allow(non_camel_case_types)]
4
5///IP route table implementation
6use super::*;
7use std::net::IpAddr;
8use crate::common::{errcode,tsmap::TsHashMap};
9use super::ipnetwork::IpNetwork;
10
11///Route Source, can be extend to any value
12pub const ROUTE_SRC_STATIC:u8=0; //static route
13pub const ROUTE_SRC_CONTROLLER:u8=1;//route entry from sdn controller
14pub const ROUTE_SRC_OSPF:u8=2;
15pub const ROUTE_SRC_BGP:u8=3;
16pub const ROUTE_SRC_ISIS:u8=4;
17pub const ROUTE_SRC_OTHER_IGP:u8=5;
18
19/// 
20#[derive(Clone,Hash,PartialEq,Eq)]
21pub struct ip_route_key_t {
22    pub vrf:i32,
23    pub subnet:IpAddr,
24    pub mask_len:u8,
25}
26impl ip_route_key_t {
27    pub fn new(vrf:i32,prefix:&IpAddr,mask_len:u8)->Self {
28        let subnet = ipnetwork::IpNetwork::get_ip_subnet(prefix, mask_len);
29        return Self {
30            vrf,
31            subnet,
32            mask_len,
33        }
34    }
35}
36
37///路由结果,T为用户定义的路由结果,priority越大表示优先级越高
38#[derive(Clone,PartialEq)]
39pub struct ip_route_result_t<T> {
40    pub rt_key:ip_route_key_t,
41    pub priority:u16,
42    pub route_src:u16,
43    pub user_result:T,
44}
45
46impl <T> ip_route_result_t<T> 
47where T: Clone+Eq {
48    pub fn new(key:&ip_route_key_t, priority:u16,route_src:u16,route_result:&T)->Self {
49        return Self {
50            rt_key:key.clone(),
51            priority:priority,
52            route_src:route_src,
53            user_result:(*route_result).clone(),
54        }
55    }
56}
57
58///路由结果集,T为用户定义的路由结果,priority越大表示优先级越高
59#[derive(Clone,PartialEq)]
60pub struct ip_route_result_set_t<T> {
61    pub result_set:Vec<ip_route_result_t<T>>,
62    pub valid_index:Vec<usize>,
63}
64
65impl <T> ip_route_result_set_t<T> 
66where T: Clone+Eq {
67    pub fn new()->Self {
68        return Self {
69            result_set:Vec::new(),
70            valid_index:Vec::new(),
71        }
72    }
73
74    pub fn len(&self)->usize {
75        self.result_set.len()
76    }
77
78    ///判断某个路由结果是否已经存在
79    pub fn is_result_exist(&self,key:&ip_route_key_t, priority:u16,route_src:u16,route_result:&T)->bool {
80        for item in &self.result_set {
81            if item.rt_key.eq(key) && item.priority==priority && item.route_src==route_src && item.user_result.eq(route_result){
82                return true
83            }
84        }
85        false
86    }
87    ///添加一个route result
88    pub fn add_route_result(&mut self,key:&ip_route_key_t, priority:u16,route_src:u16,route_result:&T)->errcode::RESULT {
89        if self.is_result_exist(key,priority,route_src,route_result) {
90            return errcode::ERROR_ALREADY_EXIST;
91        }
92        let result = ip_route_result_t::new(key,priority,route_src,route_result);
93        self.result_set.push(result);
94        self.set_max_route_priority_index();
95        errcode::RESULT_SUCCESS
96    }
97
98    pub fn delete_route_result(&mut self,key:&ip_route_key_t, priority:u16,route_src:u16,route_result:&T)->errcode::RESULT {
99        let mut idx:usize = usize::MAX;
100        for i in 0..self.result_set.len() {
101            let pitem = &self.result_set[i];
102            if pitem.rt_key.eq(key) && pitem.priority==priority && pitem.route_src==route_src && pitem.user_result.eq(route_result) {
103                idx=i;
104                break;
105            }
106        }
107        if idx< self.result_set.len() {
108            self.result_set.remove(idx);
109            self.set_max_route_priority_index();
110            return  errcode::RESULT_SUCCESS
111        }
112        return errcode::ERROR_NOT_FOUND
113    }
114
115    ///获取Result Count
116    pub fn get_result_count(&self)->usize {
117        self.result_set.len()
118    }
119    ///根据priority 求最高优先级的route条目
120    pub fn set_max_route_priority_index(&mut self) {
121        self.valid_index.clear();
122        if self.result_set.len()==0 {
123            return;
124        }
125        let mut max_prio =0;
126        for i in 0..self.result_set.len() {
127            if self.result_set[i].priority >=max_prio {
128                max_prio = self.result_set[i].priority;
129            }
130        }
131
132        for i in 0..self.result_set.len() {
133            if self.result_set[i].priority ==max_prio {
134                self.valid_index.push(i);
135            }
136        }
137    }
138    
139}
140
141
142const MAX_ROUTE_PREFIX_LEN:usize = IPV6_ADDR_LEN*8;
143const IPV4_ROUTE_PREFIX_LEN:usize = IPV4_ADDR_LEN*8;
144
145pub struct ip_route_table_t<T> 
146where T: Clone+Eq  {
147    routes_count:[usize;MAX_ROUTE_PREFIX_LEN+1],
148    routes:TsHashMap<ip_route_key_t,ip_route_result_set_t<T>>
149}
150
151
152impl <T> ip_route_table_t<T> 
153    where T: Clone+Eq {
154    pub fn new(capacity:usize)->Self {
155        let rt_table = Self{
156            routes_count:[0;MAX_ROUTE_PREFIX_LEN+1],
157            routes:TsHashMap::new(capacity)
158        };
159        return rt_table
160    }
161
162    ///添加一条路由条目,priority是优先级,数值越大表示优先级越高
163    pub fn add_ip_route(&mut self,vrf:i32,prefix:&IpAddr,mask_len:u8,priority:u16,route_src:u16,route_result:&T)->errcode::RESULT {
164        if !IpNetwork::is_valid_ipmask(prefix,mask_len) {
165            return errcode::ERROR_INVALID_PARAM
166        }
167
168        let rt_key = ip_route_key_t::new(vrf, prefix, mask_len);
169        match self.routes.get_mut(&rt_key) {
170            None=> {
171                let mut rs_set = ip_route_result_set_t::new();
172                rs_set.add_route_result(&rt_key,priority,route_src,route_result);
173                let res = self.routes.insert(rt_key,rs_set);
174                if res==errcode::RESULT_SUCCESS {
175                    self.routes_count[mask_len as usize]+=1;
176                }
177                return res;
178                
179            },
180            Some(r)=> {
181                return r.add_route_result(&rt_key,priority,route_src,route_result);
182            },
183        }
184    }
185
186    pub fn delete_ip_route(&mut self,vrf:i32,prefix:&IpAddr,mask_len:u8,priority:u16,route_src:u16,user_result:&T)->errcode::RESULT {
187        if !IpNetwork::is_valid_ipmask(prefix,mask_len) {
188            return errcode::ERROR_INVALID_PARAM
189        }
190        let rt_key = ip_route_key_t::new(vrf, prefix, mask_len);
191        let (res,rset) = match self.routes.get_mut(&rt_key) {
192            None=>return errcode::ERROR_NOT_FOUND,
193            Some(r)=> {
194                let res = r.delete_route_result(&rt_key,priority,route_src,user_result);
195                (res,r)                
196            },
197        };
198        if res==errcode::RESULT_SUCCESS && rset.len()==0{
199            self.routes_count[mask_len as usize]-=1;
200            self.routes.remove(&rt_key);
201        }
202        return res
203       
204    }
205
206    pub fn lookup_ip_route(&self,vrf:i32,dst_ip:&IpAddr)->Option<&ip_route_result_set_t<T>> {
207        let prefix_len = if dst_ip.is_ipv6() {MAX_ROUTE_PREFIX_LEN} else {IPV4_ROUTE_PREFIX_LEN};
208
209        for i in 0..prefix_len+1 {
210            let mask_len = prefix_len-i;
211            if self.routes_count[mask_len]==0 {
212                continue
213            }
214            let rt_key = ip_route_key_t::new(vrf,dst_ip,mask_len as u8);
215            if let Some(res) = self.routes.get(&rt_key) {
216                return Some(&res)
217            }
218        } 
219        None
220    }
221
222        pub fn lookup_ip_one_route(&self,vrf:i32,dst_ip:&IpAddr)->Option<ip_route_result_t<T>> {
223            let prefix_len = if dst_ip.is_ipv6() {MAX_ROUTE_PREFIX_LEN} else {IPV4_ROUTE_PREFIX_LEN};
224    
225            for i in 0..prefix_len+1 {
226                let mask_len = prefix_len-i;
227                if self.routes_count[mask_len]==0 {
228                    continue
229                }
230                let rt_key = ip_route_key_t::new(vrf,dst_ip,mask_len as u8);
231                if let Some(res) = self.routes.get(&rt_key) {
232                    if res.valid_index.len()>0 {
233                        return Some(res.result_set[res.valid_index[0]].clone())
234                    } else {
235                        return None;
236                    }
237                   
238                }
239            } 
240            None
241        }
242    
243    pub fn len(&self)->usize {
244        self.routes.len()
245    }
246
247    pub fn capacity(&self)->usize {
248        self.routes.capacity()
249    }
250
251    pub fn clear(&mut self) {
252        self.routes.clear();
253        self.routes_count.fill(0);
254    }
255
256    pub fn print_stats(&self) {
257        println!("Ip route table: capacity={},used={}",self.routes.capacity(),self.routes.len());
258        let mut sub_total=0;
259        for i in 0..MAX_ROUTE_PREFIX_LEN+1 {
260            if self.routes_count[i]>0 {
261                println!("prefix_len={},route entries={}",i,self.routes_count[i]);
262                sub_total+=self.routes_count[i];
263            }            
264        }
265
266        println!("Ip route table sub entries total={}",sub_total);
267    }
268}