1#![allow(non_snake_case)]
2#![allow(non_upper_case_globals)]
3#![allow(non_camel_case_types)]
4
5use super::*;
7use std::net::IpAddr;
8use crate::common::{errcode,tsmap::TsHashMap};
9use super::ipnetwork::IpNetwork;
10
11pub const ROUTE_SRC_STATIC:u8=0; pub const ROUTE_SRC_CONTROLLER:u8=1;pub 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#[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#[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#[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 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 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 pub fn get_result_count(&self)->usize {
117 self.result_set.len()
118 }
119 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 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}