00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "timer_queue.h"
00027
00028
00029
00030
00031
00032
00033
00034 struct timer_list aodv_timer;
00035
00036 struct timer_queue_entry *timer_queue=NULL;
00037 extern struct route_table_entry *g_my_entry;
00038 extern u_int32_t g_broadcast_ip;
00039 extern u_int32_t g_my_ip;
00040 rwlock_t timer_lock = RW_LOCK_UNLOCKED;
00041 unsigned long flags;
00042
00043 void timer_read_lock()
00044 {
00045 read_lock_irqsave(&timer_lock,flags);
00046 }
00047
00048 void timer_read_unlock()
00049 {
00050 read_unlock_irqrestore(&timer_lock,flags);
00051 }
00052
00053 void timer_write_lock()
00054 {
00055 write_lock_irqsave(&timer_lock,flags);
00056 }
00057
00058 void timer_write_unlock()
00059 {
00060 write_unlock_irqrestore(&timer_lock,flags);
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 int read_timer_queue_proc(char *buffer, char **buffer_location, off_t offset, int buffer_length,int *eof,void *data)
00073 {
00074 struct timer_queue_entry *tmp;
00075 u_int64_t remainder, numerator;
00076 u_int64_t tmp_time;
00077 int len;
00078 static char *my_buffer;
00079 char temp_buffer[80];
00080
00081
00082
00083 timer_read_lock();
00084
00085 my_buffer=buffer;
00086 sprintf(my_buffer,"\nTimer Queue\n---------------------------------\n");
00087
00088 tmp = timer_queue;
00089
00090 while (tmp != NULL)
00091 {
00092 tmp_time=tmp->tv-getcurrtime();
00093
00094
00095
00096 numerator = (tmp_time);
00097 remainder = do_div( numerator, 1000 );
00098 sprintf(temp_buffer,"sec/msec: %lu/%lu\t id:%s\t retries: %u\t ttl: %u\t Type: %d\n", (unsigned long)numerator, (unsigned long)remainder, inet_ntoa(tmp->id), tmp->retries, tmp->ttl,tmp->flags);
00099
00100 strcat(my_buffer,temp_buffer);
00101 tmp = tmp->next;
00102 }
00103
00104 sprintf(temp_buffer,"\n---------------------------------\n");
00105 strcat(my_buffer,temp_buffer);
00106
00107
00108 timer_read_unlock();
00109
00110 len = strlen(my_buffer);
00111 if (len <= offset+buffer_length) *eof = 1;
00112 *buffer_location = my_buffer + offset;
00113 len -= offset;
00114 if (len>buffer_length) len = buffer_length;
00115 if (len<0) len = 0;
00116 return len;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 void print_timer_queue()
00129 {
00130 struct timer_queue_entry *tmp;
00131 u_int64_t tmp_time;
00132 u_int64_t remainder, numerator;
00133
00134
00135 tmp = timer_queue;
00136
00137 while (tmp != NULL)
00138 {
00139 tmp_time=tmp->tv-getcurrtime();
00140
00141
00142
00143
00144 numerator = tmp_time;
00145 remainder = do_div( numerator, 1000 );
00146 printk("sec/msec: %lu/%lu id:%lu size: %d retries: %u ttl: %u\n", (unsigned long)numerator, (unsigned long)remainder, (unsigned long)tmp->id, tmp->size, tmp->retries, tmp->ttl);
00147
00148 tmp = tmp->next;
00149 }
00150
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 int timer_rreq(struct timer_queue_entry *tmp_entry)
00162 {
00163 struct route_table_entry *tmp_route;
00164 struct rreq *tmp_rreq;
00165 u_int32_t rreq_id;
00166
00167 tmp_rreq=tmp_entry->data;
00168
00169
00170 if (tmp_entry->retries >= RREQ_RETRIES)
00171 {
00172
00173
00174 ipq_drop_ip(tmp_rreq->dst_ip);
00175 kfree(tmp_entry->data);
00176
00177
00178 return 0;
00179 }
00180 else
00181 {
00182
00183 tmp_entry->retries++;
00184
00185
00186 if (tmp_entry->ttl > TTL_THRESHOLD)
00187 tmp_entry->ttl = NET_DIAMETER;
00188 else
00189 tmp_entry->ttl += TTL_INCREMENT;
00190
00191
00192 tmp_route = (find_interface_by_ip(tmp_rreq->src_ip))->route_entry;
00193
00194 (tmp_route->rreq_id)++;
00195
00196
00197
00198 tmp_rreq->rreq_id = htonl(tmp_route->rreq_id);
00199
00200 if (insert_flood_id_queue_entry(tmp_rreq->src_ip, tmp_rreq->dst_ip,tmp_route->rreq_id,getcurrtime() + tmp_entry->ttl * 2 * NODE_TRAVERSAL_TIME ) <0)
00201 {
00202 printk(KERN_WARNING "AODV: Could not insert into broadcast list\n");
00203 kfree(tmp_entry->data);
00204
00205
00206 return -ENOMEM;
00207 }
00208
00209
00210 local_broadcast( tmp_entry->ttl,tmp_rreq, tmp_entry->size);
00211
00212
00213
00214
00215 insert_timer_queue_entry(getcurrtime() + NET_TRAVERSAL_TIME, tmp_rreq,tmp_entry->size,tmp_rreq->dst_ip,tmp_entry->retries,tmp_entry->ttl, EVENT_RREQ);
00216
00217
00218
00219 }
00220
00221 return 0;
00222 }
00223
00224
00225
00226 void timer_neighbor(struct timer_queue_entry *timer_entry)
00227 {
00228 struct neighbor_list_entry *tmp_entry;
00229 struct route_table_entry *tmp_route;
00230
00231 tmp_entry = find_neighbor_list_entry(timer_entry->id);
00232
00233 if (tmp_entry!=NULL)
00234 {
00235 tmp_route=find_route_table_entry(tmp_entry->ip);
00236 if (tmp_route!=NULL)
00237 {
00238
00239
00240
00241 tmp_route->lifetime=getcurrtime()-1;
00242
00243 delete_neighbor_list_entry(tmp_entry->ip);
00244 }
00245 }
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 int hello_resend(struct timer_queue_entry *tmp_entry)
00257 {
00258 struct rrep *tmp_rrep;
00259 struct interface_list_entry *tmp_interface;
00260 u_int64_t curr_time=getcurrtime();
00261 u_int16_t random_number;
00262
00263
00264 tmp_rrep=tmp_entry->data;
00265
00266 tmp_interface=find_interface_by_ip(tmp_rrep->dst_ip);
00267 if (tmp_interface==NULL)
00268 {
00269
00270 printk(KERN_WARNING "AODV: HELLO error retrieveing interface\n");
00271
00272 kfree(tmp_rrep);
00273
00274 return 0;
00275 }
00276
00277 tmp_rrep->dst_seq = htonl(tmp_interface->route_entry->dst_seq);
00278
00279 local_broadcast(1,tmp_rrep, sizeof(struct rrep));
00280
00281
00282
00283 tmp_interface->last_hello=curr_time;
00284 insert_timer_queue_entry(tmp_entry->tv + HELLO_INTERVAL, tmp_rrep,tmp_entry->size,tmp_rrep->dst_ip,tmp_entry->retries,tmp_entry->ttl, EVENT_HELLO);
00285
00286 return 0;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void timer_cleanup()
00299 {
00300 insert_event_queue_entry(EVENT_CLEANUP,NULL);
00301 insert_timer_queue_entry(getcurrtime() + ACTIVE_ROUTE_TIMEOUT, NULL,0,g_my_ip,0,0, EVENT_CLEANUP);
00302
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 int init_timer_queue()
00312 {
00313
00314 init_timer(&aodv_timer);
00315 timer_queue=NULL;
00316 return 0;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 static unsigned long tvtojiffies(struct timeval *value)
00356 {
00357 unsigned long sec = (unsigned) value->tv_sec;
00358 unsigned long usec = (unsigned) value->tv_usec;
00359
00360 if (sec > (ULONG_MAX / HZ))
00361 return ULONG_MAX;
00362 usec += 1000000 / HZ - 1;
00363 usec /= 1000000 / HZ;
00364 return HZ*sec+usec;
00365 }
00366
00367
00368 void update_timer_queue()
00369 {
00370 struct timeval delay_time;
00371 u_int64_t currtime;
00372 u_int64_t tv;
00373 u_int64_t remainder, numerator;
00374
00375 delay_time.tv_sec = 0;
00376 delay_time.tv_usec = 0;
00377
00378
00379 timer_read_lock();
00380
00381 if (timer_queue == NULL)
00382 {
00383
00384 delay_time.tv_sec = 0;
00385 delay_time.tv_usec = 0;
00386 }
00387 else
00388 {
00389
00390 tv = timer_queue->tv;
00391
00392 currtime = getcurrtime();
00393
00394 if (tv <= currtime)
00395 {
00396
00397
00398
00399 delay_time.tv_sec = 0;
00400 delay_time.tv_usec = 1;
00401 }
00402 else
00403 {
00404
00405
00406
00407
00408
00409 numerator = ( tv - currtime );
00410 remainder = do_div( numerator, 1000 );
00411
00412 delay_time.tv_sec = numerator;
00413 delay_time.tv_usec = remainder * 1000;
00414
00415 }
00416
00417 }
00418
00419 if (!timer_pending(&aodv_timer))
00420 {
00421 aodv_timer.function=&timer_queue_signal;
00422 aodv_timer.expires=jiffies + tvtojiffies(&delay_time);
00423 add_timer(&aodv_timer);
00424 }
00425 else
00426 {
00427 mod_timer(&aodv_timer,jiffies + tvtojiffies(&delay_time));
00428 }
00429
00430
00431 timer_read_unlock();
00432
00433
00434 return;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void timer_queue_signal()
00448 {
00449 struct timer_queue_entry *tmp_entry;
00450 u_int64_t currtime;
00451
00452
00453
00454
00455 currtime = getcurrtime();
00456 tmp_entry = find_first_timer_queue_entry_due(currtime);
00457
00458
00459 while (tmp_entry != NULL)
00460 {
00461 switch (tmp_entry->flags)
00462 {
00463 case EVENT_RREQ:
00464 timer_rreq(tmp_entry);
00465 break;
00466
00467 case EVENT_HELLO:
00468 hello_resend(tmp_entry);
00469 break;
00470
00471 case EVENT_CLEANUP:
00472 timer_cleanup();
00473 break;
00474
00475 case EVENT_NEIGHBOR:
00476 timer_neighbor(tmp_entry);
00477 break;
00478
00479 default:
00480 break;
00481 }
00482
00483
00484
00485 kfree(tmp_entry);
00486
00487
00488 currtime = getcurrtime();
00489 tmp_entry = find_first_timer_queue_entry_due(currtime);
00490 }
00491 update_timer_queue();
00492
00493
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 int insert_timer_queue_entry(u_int64_t msec,void *data,int size,u_int32_t id,u_int16_t retries,u_int8_t ttl,unsigned char flags)
00505 {
00506 struct timer_queue_entry *prev_entry;
00507 struct timer_queue_entry *tmp_entry;
00508 struct timer_queue_entry *new_entry;
00509
00510
00511
00512 if ((new_entry = kmalloc(sizeof(struct timer_queue_entry), GFP_ATOMIC)) == NULL)
00513 {
00514 printk(KERN_WARNING "AODV: Error allocating timer!\n");
00515
00516 return -ENOMEM;
00517 }
00518
00519
00520 new_entry->tv = msec;
00521 new_entry->id = id;
00522 new_entry->flags = flags;
00523 new_entry->retries=retries;
00524 new_entry->ttl=ttl;
00525 new_entry->size=size;
00526 new_entry->data=data;
00527
00528 prev_entry=NULL;
00529
00530
00531 timer_write_lock();
00532
00533
00534 tmp_entry=timer_queue;
00535
00536
00537 while (tmp_entry!=NULL && new_entry->tv > tmp_entry ->tv)
00538 {
00539 prev_entry=tmp_entry;
00540 tmp_entry=tmp_entry->next;
00541 }
00542
00543
00544
00545 if (timer_queue==tmp_entry)
00546 {
00547 new_entry->next=timer_queue;
00548 timer_queue=new_entry;
00549 }
00550 else
00551 {
00552 if (tmp_entry==NULL)
00553 {
00554 new_entry->next=NULL;
00555 prev_entry->next=new_entry;
00556 }
00557 else
00558 {
00559 new_entry->next=prev_entry->next;
00560 prev_entry->next=new_entry;
00561 }
00562 }
00563
00564
00565 timer_write_unlock();
00566
00567
00568
00569
00570
00571
00572 return 0;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582 struct timer_queue_entry *find_first_timer_queue_entry()
00583 {
00584
00585 return timer_queue;
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 struct timer_queue_entry * find_first_timer_queue_entry_of_id(u_int32_t id)
00597 {
00598 struct timer_queue_entry *tmp_entry;
00599
00600
00601 timer_read_lock();
00602
00603
00604 tmp_entry=timer_queue;
00605
00606 while (tmp_entry != NULL && tmp_entry->id != id)
00607 tmp_entry=tmp_entry->next;
00608
00609
00610 timer_read_unlock();
00611
00612 return tmp_entry;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622 struct timer_queue_entry * find_first_timer_queue_entry_of_id_and_flag(u_int32_t id, unsigned char flags)
00623 {
00624 struct timer_queue_entry *tmp_entry;
00625
00626
00627 timer_read_lock();
00628
00629 tmp_entry=timer_queue;
00630
00631
00632 while (tmp_entry != NULL && tmp_entry->id != id && tmp_entry->flags!=flags)
00633 tmp_entry=tmp_entry->next;
00634
00635
00636 timer_read_unlock();
00637
00638 return tmp_entry;
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648 void delete_timer_queue_entry_of_id(u_int32_t id, unsigned char flags)
00649 {
00650 struct timer_queue_entry *tmp_entry;
00651 struct timer_queue_entry *prev_entry;
00652 struct timer_queue_entry *dead_entry;
00653 int deleted=0;
00654
00655
00656 timer_write_lock();
00657
00658 tmp_entry=timer_queue;
00659 prev_entry=NULL;
00660
00661 while (tmp_entry != NULL)
00662 {
00663 if (tmp_entry->id == id && tmp_entry->flags == flags)
00664 {
00665 if (prev_entry==NULL)
00666 timer_queue=tmp_entry->next;
00667 else
00668 prev_entry->next=tmp_entry->next;
00669
00670 dead_entry=tmp_entry;
00671 tmp_entry=tmp_entry->next;
00672 kfree(dead_entry->data);
00673 kfree(dead_entry);
00674 deleted=1;
00675
00676 }
00677 else
00678 {
00679 prev_entry=tmp_entry;
00680 tmp_entry=tmp_entry->next;
00681 }
00682 }
00683
00684
00685
00686
00687 timer_write_unlock();
00688
00689 update_timer_queue();
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699 int delete_timer_queue_entry(struct timer_queue_entry *dead_entry)
00700 {
00701 struct timer_queue_entry *tmp_entry;
00702 struct timer_queue_entry *prev_entry;
00703
00704
00705
00706
00707 timer_write_lock();
00708
00709 tmp_entry=timer_queue;
00710 prev_entry=NULL;
00711
00712 while (tmp_entry!=NULL && tmp_entry!=dead_entry)
00713 {
00714 prev_entry=tmp_entry;
00715 tmp_entry=tmp_entry->next;
00716 }
00717 if (tmp_entry==NULL)
00718 {
00719 printk(KERN_WARNING "AODV: Could not find Timer Queue Entry to delete!\n");
00720 timer_write_unlock();
00721 return 1;
00722
00723 }
00724 if (prev_entry==NULL)
00725 timer_queue=tmp_entry->next;
00726 else
00727 prev_entry->next=tmp_entry->next;
00728
00729
00730 kfree(tmp_entry);
00731
00732
00733
00734
00735 timer_write_unlock();
00736
00737 return 0;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 void remove_first_timer_queue_entry()
00749 {
00750 struct timer_queue_entry *dead_entry;
00751
00752
00753 timer_write_lock();
00754
00755 if (timer_queue!=NULL)
00756 {
00757 dead_entry=timer_queue;
00758 timer_queue=timer_queue->next;
00759 kfree(dead_entry);
00760 }
00761
00762
00763 timer_write_unlock();
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 struct timer_queue_entry *find_first_timer_queue_entry_due(u_int64_t tv)
00775 {
00776 struct timer_queue_entry *tmp_entry;
00777
00778
00779
00780 timer_read_lock();
00781
00782
00783 if (timer_queue != NULL)
00784 {
00785
00786 if ((timer_queue->tv) < tv)
00787 {
00788 tmp_entry=timer_queue;
00789 timer_queue=timer_queue->next;
00790 return tmp_entry;
00791 }
00792 }
00793
00794
00795 timer_read_unlock();
00796
00797 return NULL;
00798 }