forked from wujingbang/aodv-Android
/
brk_list.c
336 lines (258 loc) · 7.21 KB
/
brk_list.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/***************************************************************************
brk_list.h - description
-------------------
begin : Thu May 15 2014
copyright : (C) 2014 by Cai Bingying
email :
***************************************************************************/
//#ifdef RECOVERYPATH
//manage the brk_list
//处理断路表,添加条目,删除条目,寻找指定条目等
#include "brk_list.h"
brk_link *brk_list;
extern u_int32_t g_broadcast_ip;
extern u_int32_t g_mesh_ip;
extern u_int8_t g_routing_metric;
extern aodv_dev *g_mesh_dev;
DEFINE_RWLOCK(brk_list_lock);
//read & write lock & unlock -- 读写锁
inline void brk_list_read_lock(void) {
read_lock_bh(&brk_list_lock);
}
inline void brk_list_read_unlock(void) {
read_unlock_bh(&brk_list_lock);
}
inline void brk_list_write_lock(void) {
write_lock_bh(&brk_list_lock);
}
inline void brk_list_write_unlock(void) {
write_unlock_bh(&brk_list_lock);
}
//find first brk entry
brk_link *first_brk_link(void) {
return brk_list;
}
//initiate the brk list--empty
void init_brk_list(void) {
brk_list = NULL;
}
//expire some brk link -- 使某个断路条目过期
void expire_brk_link(brk_link * tmp_link) {
brk_list_write_lock();
tmp_link->lifetime = (getcurrtime() + DELETE_PERIOD);
tmp_link->state = INVALID;
brk_list_write_unlock();
}
//remove brk link -- 删除某个断路条目
void remove_brk_link(brk_link *dead_link) {
brk_list_write_lock(); //to avoid conflicts
//对此有疑问,dead_link的后继与表中的是一致的么?奇怪
if (brk_list == dead_link) {
brk_list = dead_link->next;
}
if (dead_link->prev != NULL) {
dead_link->prev->next = dead_link->next;
}
if (dead_link->next!=NULL) {
dead_link->next->prev = dead_link->prev;
}
brk_list_write_unlock();
kfree(dead_link);
}
//find brk link by dst--记得测试一下返回后其下一跳长什么样
brk_link *find_first_brk_link_with_dst(u_int32_t dst_ip){
brk_link *tmp_link;
brk_list_read_lock();
tmp_link = brk_list;
while((tmp_link != NULL) && (tmp_link->dst_ip < dst_ip)){
tmp_link = tmp_link->next;
}
if((tmp_link == NULL) || (tmp_link->dst_ip != dst_ip) ){//not found
brk_list_read_unlock();
return NULL;
}
else
{
brk_list_read_unlock();
return tmp_link;
}
}
//find brk link by src & dst -- 寻找指定的断路条目
brk_link *find_brk_link(u_int32_t src_ip, u_int32_t dst_ip) {
brk_link *tmp_link;
/*lock list */
brk_list_read_lock();
tmp_link = brk_list;
while ((tmp_link != NULL) && (tmp_link->dst_ip < dst_ip)) { //serching(sorted by dst_ip in insert)
tmp_link = tmp_link->next;
}
if ((tmp_link == NULL) || (tmp_link->dst_ip != dst_ip)) { //not found!
brk_list_read_unlock();
return NULL;
}
else {
while ((tmp_link != NULL) && (tmp_link->dst_ip == dst_ip)) {
if (tmp_link->src_ip == src_ip) {
brk_list_read_unlock();
//found it
return tmp_link;
}
tmp_link = tmp_link->next;
}
}
brk_list_read_unlock();
return NULL;//not found
}
/*
int is_overlapped_with_brk_link(aodv_route *tmp_route){
brk_link *tmp_link;
brk_list_read_lock();
tmp_link = brk_list;
while(tmp_link != NULL){
if( (tmp_link->src_ip==tmp_route->src_ip)
&& (tmp_link->last_avail_ip==tmp_route->dst_ip) ){
//data link has overlap part
break;
}
tmp_link = tmp_link->next;
}
if(tmp_link){
brk_list_read_unlock();
return 1;
}
brk_list_read_unlock();
return 0;//no overlap
}
*/
//clean up the brk list -- 此功能保留,brk_list的清空应无需与内核交互
int cleanup_brk_list(void) {
brk_link *dead_link, *tmp_link;
int error;
tmp_link = brk_list;
//如果断路表不为空,直接一个一个删除,无需像路由表一样跟内核交互
while (tmp_link != NULL) {
dead_link = tmp_link;
tmp_link = tmp_link->next;
kfree(dead_link);
}
brk_list = NULL;
return 0;
}
//创建新的断路条目
brk_link *create_brk_link(u_int32_t src_ip, u_int32_t dst_ip,
u_int32_t lasthop,u_int32_t lastavail) {
brk_link *tmp_entry;
#ifdef CaiDebug
char src[20];
char dst[20];
char lhop[20];
char lavail[20];
strcpy(src, inet_ntoa(src_ip));
strcpy(dst, inet_ntoa(dst_ip));
strcpy(lhop, inet_ntoa(lasthop));
strcpy(lavail, inet_ntoa(lastavail));
printk ("create_brk_link: Creating %s to %s via %s,last DTN is %s\n", src,dst,lhop,lavail);
#endif
/* Allocate memory for new entry */
if ((tmp_entry = (brk_link *) kmalloc(sizeof(brk_link), GFP_ATOMIC)) == NULL) {
printk("Error getting memory for new brk link\n");
return NULL;
}
tmp_entry->dst_ip = dst_ip;
tmp_entry->dst_id = htonl(dst_ip);
tmp_entry->src_ip = src_ip;
tmp_entry->last_hop = lasthop;
tmp_entry->state = ACTIVE;
//tmp_entry->last_avail_ip = NULL;
//#ifdef DTN
tmp_entry->last_avail_ip = lastavail;//若没有则为空,该字段不能缺少
//#endif
tmp_entry->prev = NULL;
tmp_entry->next = NULL;
tmp_entry->lifetime = getcurrtime() + BRK_LINK_TIMEOUT;//该删除时间是否应该调整到稍微大一点???
insert_brk_link(tmp_entry);
#ifdef CaiDebug
if (brk_list == NULL) // if the brk_list is empty
{
printk ("brk list still NULL after insert!! ");
}
#endif
return tmp_entry;
}
//insert a new brk link entry,and sort it first by dst
//插入新的断路条目,并先按dst排序
void insert_brk_link(brk_link *new_link) { //ordenamos por dst_ip
brk_link *tmp_link;
brk_link *prev_link = NULL;
brk_list_write_lock(); //to avoid conflicts
tmp_link = brk_list;
while ((tmp_link != NULL) && (tmp_link->dst_ip < new_link->dst_ip)) //entries ordered by dst_ip
{
prev_link = tmp_link;
tmp_link = tmp_link->next;
}
if (brk_list && (tmp_link == brk_list)) // if it goes in the first spot in the list
{
brk_list->prev = new_link;
new_link->next = brk_list;
brk_list = new_link;
#ifdef CaiDebug
printk("New link should be put in the head of the list in brk_list.c\n");
#endif
brk_list_write_unlock();
return ;
}
if (brk_list == NULL) // if the brk_list is empty
{
brk_list = new_link;
brk_list_write_unlock();
#ifdef CaiDebug
printk("The list is empty in brk_list.c\n");
#endif
return;
}
if (tmp_link == NULL) //i'm going in next spot in the list and it is empty
{
new_link->next = NULL;
new_link->prev = prev_link;
prev_link->next = new_link;
brk_list_write_unlock();
#ifdef CaiDebug
printk("New link should be put in the last of the list in brk_list.c\n");
#endif
return;
}
//found it in somewhere of the list
tmp_link->prev = new_link;
new_link->next = tmp_link;
new_link->prev = prev_link;
prev_link->next = new_link;
brk_list_write_unlock();
return;
}
int flush_brk_list(void) {
u_int64_t currtime = getcurrtime();
brk_link *dead_link, *tmp_link, *prev_link=NULL;
tmp_link = brk_list;
while (tmp_link!=NULL) {
prev_link = tmp_link;
if (time_before((unsigned long) tmp_link->lifetime,
(unsigned long) currtime)) {//生命周期在当前时间之前
if (tmp_link->state != INVALID) {//未过期则使其过期
expire_brk_link(tmp_link);
tmp_link = tmp_link->next;
}
else {//已标志过期,则删除。
}
dead_link = tmp_link;
prev_link = tmp_link->prev;
tmp_link = tmp_link->next;
remove_brk_link(dead_link);
}
tmp_link = tmp_link->next;
}
//insert_timer_simple(TASK_CLEANUP, HELLO_INTERVAL, g_mesh_ip);
//update_timer_queue();
return 1;
}
//#endif