00001 /* 00002 Kernel AODV v2.1 00003 National Institute of Standards and Technology 00004 Luke Klein-Berndt 00005 ----------------------------------------------------- 00006 Version 2.1 new features: 00007 * Much more stable! 00008 * Added locks around important areas 00009 * Multihop Internet gatewaying now works 00010 * Multicast hack added 00011 * Many bug fixes! 00012 ----------------------------------------------------- 00013 00014 Originally based upon MadHoc code. I am not 00015 sure how much of it is left anymore, but MadHoc 00016 proved to be a great starting point. 00017 00018 MadHoc was written by - Fredrik Lilieblad, 00019 Oskar Mattsson, Petra Nylund, Dan Ouchterlony 00020 and Anders Roxenhag Mail: mad-hoc@flyinglinux.net 00021 00022 This software is Open Source under the GNU General Public Licence. 00023 00024 */ 00025 00026 00027 00028 /**************************************************** 00029 00030 aodv_thread 00031 ---------------------------------------------------- 00032 This is the main thread which handles the 00033 processing of packets which are placed in its 00034 queue. After netfilter calls packet_in on an 00035 interuppt, packet_in takes the packet and if it 00036 is an AODV packet it places into the event 00037 queue. It then kicks aodv_thread. Aodv_thread 00038 processes the event and pass it along to 00039 the correct function. 00040 ****************************************************/ 00041 00042 #include "aodv_thread.h" 00043 00044 static int aodv_pid; 00045 static wait_queue_head_t aodv_wait; 00046 static atomic_t kill_thread; 00047 static atomic_t aodv_is_dead; 00048 00049 00050 00051 00052 /**************************************************** 00053 00054 kick_aodv 00055 ---------------------------------------------------- 00056 Wakes up the aodv_thread. You call this after 00057 you have placed something on the event queue. 00058 ****************************************************/ 00059 00060 void kick_aodv() 00061 { 00062 //We are trying to wake up AODV!!! 00063 //AODV thread is an interupptible sleep state.... this interupts it 00064 wake_up_interruptible(&aodv_wait); 00065 } 00066 00067 /**************************************************** 00068 00069 kill_aodv 00070 ---------------------------------------------------- 00071 This will kill the AODV Thread. It sets the kill 00072 flag and then wakes up AODV thread. If it 00073 does not get confirmation that AODV is dead 00074 it will try again! 00075 ****************************************************/ 00076 void kill_aodv() 00077 { 00078 wait_queue_head_t queue; 00079 int count=0; 00080 //starts a wait queue 00081 00082 init_waitqueue_head(&queue); 00083 00084 //sets a flag letting the thread know it should die 00085 //wait for the thread to set flag saying it is dead 00086 while ((atomic_read(&aodv_is_dead)==0) && (count<5)) 00087 { 00088 //lower semaphore for the thread 00089 atomic_set(&kill_thread,1); 00090 wake_up_interruptible(&aodv_wait); 00091 interruptible_sleep_on_timeout(&queue,HZ); 00092 00093 //sleep for a bit and then check on the thread again 00094 count++; 00095 00096 } 00097 00098 if (count>4) 00099 printk(KERN_WARNING "AODV_THREAD: Tried to kill AODV Thread, but failed. It may have crashed. \n"); 00100 00101 } 00102 00103 /**************************************************** 00104 00105 aodv 00106 ---------------------------------------------------- 00107 This is the main section of the thread. The main 00108 loop! The big enchilada! It is a big loop which 00109 will handle everything in the Event queue and 00110 then goto sleep. 00111 ****************************************************/ 00112 void aodv() 00113 { 00114 //The queue holding all the events to be dealt with 00115 struct event_queue_entry *working_event; 00116 00117 //Initalize the variables 00118 init_waitqueue_head(&aodv_wait); 00119 atomic_set(&kill_thread,0); 00120 atomic_set(&aodv_is_dead,0); 00121 00122 00123 //Name our thread 00124 lock_kernel(); 00125 sprintf(current->comm,"kernel-aodv"); 00126 exit_mm(current); 00127 unlock_kernel(); 00128 00129 00130 //why would I ever want to stop ? :) 00131 for (;;) 00132 { 00133 00134 //should the thread exit? 00135 if (atomic_read(&kill_thread)) 00136 { 00137 goto exit; 00138 } 00139 00140 //goto sleep until we recieve an interupt 00141 interruptible_sleep_on(&aodv_wait); 00142 00143 //should the thread exit? 00144 if (atomic_read(&kill_thread)) 00145 { 00146 goto exit; 00147 } 00148 00149 00150 //While the buffer is not empty 00151 while((working_event=get_next_event_queue_entry())!=NULL) 00152 { 00153 00154 if ((getcurrtime() - working_event->time) > 1000) 00155 { 00156 printk(KERN_INFO "AODV_THREAD: AODV packet queued too long\n"); 00157 } 00158 00159 //takes a different action depending on what type of event is recieved 00160 switch (working_event->type) 00161 { 00162 //RREQ 00163 case EVENT_RREQ: 00164 monitor.rreq++; 00165 recv_rreq(working_event); 00166 kfree(working_event->data); 00167 break; 00168 00169 //RREP 00170 case EVENT_RREP: 00171 monitor.rrep++; 00172 recv_rrep(working_event); 00173 kfree(working_event->data); 00174 break; 00175 00176 case EVENT_RREP_ACK: 00177 recv_rrep_ack(working_event); 00178 kfree(working_event->data); 00179 break; 00180 00181 //RERR 00182 case EVENT_RERR: 00183 monitor.rrer++; 00184 recv_rerr(working_event); 00185 kfree(working_event->data); 00186 break; 00187 00188 //Cleanup the Route Table and Flood ID queue 00189 case EVENT_CLEANUP: 00190 find_inactive_route_table_entries(); 00191 delete_old_flood_id_queue_entries(); 00192 break; 00193 00194 default: 00195 break; 00196 } 00197 00198 00199 kfree(working_event); 00200 00201 } 00202 00203 00204 } 00205 00206 exit: 00207 //Set the flag that shows you are dead 00208 atomic_set(&aodv_is_dead,1); 00209 00210 } 00211 00212 00213 00214 00215 00216 /**************************************************** 00217 00218 startup_aodv 00219 ---------------------------------------------------- 00220 Creates AODV thread and tells it to start in the 00221 function aodv() 00222 ****************************************************/ 00223 void startup_aodv() 00224 { 00225 //start the thread and have it start in the aodv function 00226 aodv_pid=kernel_thread((void *) &aodv,NULL,0); 00227 }