rebroadcast_queue.c

説明を見る。
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 #include "rebroadcast_queue.h"
00027 /****************************************************
00028 
00029    rebroadcast_queue
00030 ----------------------------------------------------
00031 This is a queue used to store multicast packets that
00032 have to be rebroadcast. They get queued until they
00033 should be rebroadcast. We don't want to do are 
00034 rebroadcasting on an interupt so the queued packets
00035 are rebroadcasted by a seperate thread which handles
00036 it at a later date... hopefully! :)
00037 ****************************************************/
00038 
00039 #ifdef AODV_MULTICAST
00040 
00041 extern u_int32_t g_broadcast_ip;
00042 struct rebroadcast_queue_entry *rebroadcast_queue;
00043 struct rebroadcast_queue_entry *end_rebroadcast_queue;
00044 spinlock_t rebroadcast_lock = SPIN_LOCK_UNLOCKED;
00045 static int rebroadcast_pid;
00046 static wait_queue_head_t  rebroadcast_wait;
00047 static atomic_t kill_thread;
00048 
00049 
00050 /****************************************************
00051 
00052    insert_rebroadcast_queue_entry
00053 ----------------------------------------------------
00054 Inserts an event into the event queue. dev is the
00055 device the event was recieved on. data points
00056 to the event itself.
00057 ****************************************************/
00058 
00059 void lock_rebroadcast()
00060 {
00061   spin_lock_bh(&rebroadcast_lock);
00062 }
00063 
00064 void unlock_rebroadcast()
00065 {
00066   spin_unlock_bh(&rebroadcast_lock);
00067 }
00068 
00069 int insert_rebroadcast_queue_entry( u_int32_t dst_ip, unsigned int size,void *data,u_int8_t ttl)
00070 {
00071     struct rebroadcast_queue_entry *new_entry;
00072     
00073 
00074     //create a new entry
00075  if ((new_entry = (struct rebroadcast_queue_entry*)kmalloc(sizeof(struct rebroadcast_queue_entry),GFP_ATOMIC)) == NULL)
00076     {
00077       printk(KERN_WARNING "AODV: Error trying to allocate Rebroadcast Queue Entry\n");
00078         return -ENOMEM;
00079     }
00080 
00081     new_entry->dst_ip = dst_ip;
00082     new_entry->size = size;
00083     new_entry->ttl=ttl-1;
00084     new_entry->time=getcurrtime();
00085     new_entry->prev=NULL;
00086 
00087     //create space for the data and copy it there
00088     if ((new_entry->data = kmalloc(size,GFP_ATOMIC)) ==  NULL)
00089     {
00090       kfree(new_entry);
00091       printk(KERN_WARNING "AODV: Error trying to allocate Rebroadcast Queue Entry Data\n");
00092       return -ENOMEM;
00093     }
00094 
00095     memcpy(new_entry->data,data,size);
00096 
00097 
00098     /*lock table*/
00099     lock_rebroadcast();
00100 
00101 
00102     //Set all the variables
00103     new_entry->next=rebroadcast_queue;
00104     if (rebroadcast_queue==NULL)
00105       {
00106         end_rebroadcast_queue=new_entry;
00107       }
00108     else
00109       {
00110         rebroadcast_queue->prev=new_entry;
00111       }
00112 
00113     rebroadcast_queue=new_entry;
00114    
00115     
00116     /*unlock table*/
00117     unlock_rebroadcast();
00118 
00119     kick_rebroadcast();
00120 
00121     return 0;
00122 }
00123 
00124 /****************************************************
00125 
00126    get_first_rebroadcast_queue_entry
00127 ----------------------------------------------------
00128 Gets the first entry from the event queue
00129 ****************************************************/
00130 
00131 struct rebroadcast_queue_entry *get_next_rebroadcast_queue_entry( void )
00132 {
00133   struct rebroadcast_queue_entry *temp_entry=NULL;
00134 
00135   /*lock table*/
00136   lock_rebroadcast();
00137   
00138   if (end_rebroadcast_queue!=NULL)
00139     {
00140       temp_entry=end_rebroadcast_queue;
00141       if (temp_entry->prev==NULL)
00142         {
00143           end_rebroadcast_queue=NULL;
00144           rebroadcast_queue=NULL;
00145         }
00146       else
00147         {
00148           end_rebroadcast_queue=temp_entry->prev;
00149           end_rebroadcast_queue->next=NULL;
00150         }
00151     }
00152 
00153   /*unlock table*/
00154   unlock_rebroadcast();
00155 
00156   return temp_entry;
00157   
00158 }
00159 
00160 
00161 
00162 /****************************************************
00163 
00164    init_rebroadcast_queue
00165 ----------------------------------------------------
00166 Initalizes the event queue
00167 ****************************************************/
00168 int init_rebroadcast_queue( void )
00169 {
00170     rebroadcast_queue = NULL;
00171     end_rebroadcast_queue = NULL;
00172     rebroadcast_pid=kernel_thread((void *) &rebroadcast_thread,NULL,0);
00173     return 0;
00174 }
00175 
00176 
00177 void kill_rebroadcast_thread()
00178 {
00179   wake_up_interruptible(&rebroadcast_wait);
00180  
00181   //lower semaphore for the thread
00182   atomic_set(&kill_thread,1);
00183   atomic_set(&kill_thread,1);
00184   atomic_set(&kill_thread,1);
00185  
00186 }
00187 
00188 
00189 
00190 void kick_rebroadcast()
00191 {
00192     //We are trying to wake up AODV!!!
00193     //AODV thread is an interupptible sleep state.... this interupts it
00194     wake_up_interruptible(&rebroadcast_wait);
00195 }
00196 
00197 void rebroadcast_thread()
00198 {
00199     //The queue holding all the events to be dealt with
00200     struct rebroadcast_queue_entry *working_event;
00201     struct timeval delay_time;
00202 
00203     delay_time.tv_sec = 0;
00204     delay_time.tv_usec = 100000;
00205 
00206     //Initalize the variables
00207     init_waitqueue_head(&rebroadcast_wait);
00208     atomic_set(&kill_thread,0);
00209 
00210 
00211 
00212     //Name our thread
00213     lock_kernel();
00214     sprintf(current->comm,"rebroadcast");
00215     exit_mm(current);
00216     unlock_kernel();
00217 
00218 
00219 
00220     //why would I ever want to stop ? :)
00221     for (;;)
00222     {
00223 
00224         //should the thread exit?
00225         if (atomic_read(&kill_thread))
00226         {
00227 
00228             return;
00229         }
00230 
00231         //goto sleep until we recieve an interupt
00232         interruptible_sleep_on(&rebroadcast_wait);
00233         
00234 
00235         //should the thread exit?
00236         if (atomic_read(&kill_thread))
00237         {
00238             return;
00239         }
00240 
00241         //While the buffer is not empty
00242         while((working_event=get_next_rebroadcast_queue_entry())!=NULL)
00243         {
00244 
00245           if ((getcurrtime() - working_event->time) < 50)
00246             {
00247           rebroadcast(working_event->dst_ip,working_event->size,working_event->data,working_event->ttl);
00248             }
00249           else
00250             {
00251               printk(KERN_NOTICE "AODV: Rebroadcast queue getting funky!\n");
00252             }
00253 
00254            kfree(working_event->data);
00255            kfree(working_event);
00256 
00257         }
00258     }
00259 
00260 }
00261 
00262 #endif
00263 
00264 
00265 

kernel_aodvmに対してThu Nov 10 18:53:11 2005に生成されました。  doxygen 1.4.5