/* Kernel AODV v2.1 National Institute of Standards and Technology Luke Klein-Berndt ----------------------------------------------------- Version 2.1 new features: * Much more stable! * Added locks around important areas * Multihop Internet gatewaying now works * Multicast hack added * Many bug fixes! ----------------------------------------------------- Originally based upon MadHoc code. I am not sure how much of it is left anymore, but MadHoc proved to be a great starting point. MadHoc was written by - Fredrik Lilieblad, Oskar Mattsson, Petra Nylund, Dan Ouchterlony and Anders Roxenhag Mail: mad-hoc@flyinglinux.net This software is Open Source under the GNU General Public Licence. */ #include "event_queue.h" /**************************************************** event_queue ---------------------------------------------------- This is a queue used to store events which have to be dealt with. They are queued instead of being acted on directly because a lot of the events are recieved on interupts and you want to limit the amount of work being done on interupts! ****************************************************/ extern u_int32_t g_broadcast_ip; struct event_queue_entry *event_queue; struct event_queue_entry *end_event_queue; spinlock_t event_lock = SPIN_LOCK_UNLOCKED; void lock_event() { spin_lock_bh(&event_lock); } void unlock_event() { spin_unlock_bh(&event_lock); } /**************************************************** insert_event_queue_entry ---------------------------------------------------- Inserts an event into the event queue. dev is the device the event was recieved on. data points to the event itself. ****************************************************/ int insert_event_queue_entry(int type,struct sk_buff *packet) { struct event_queue_entry *new_entry; struct interface_list_entry *tmp_interface; struct iphdr *ip; int start_point=sizeof(struct udphdr)+sizeof(struct iphdr); if ((new_entry = (struct event_queue_entry*)kmalloc(sizeof(struct event_queue_entry),GFP_ATOMIC)) == NULL) { printk(KERN_WARNING "AODV: Not enough memory to create Event Queue Entry\n"); return -ENOMEM; } new_entry->time = getcurrtime(); new_entry->type = type; new_entry->prev = NULL; if (type<100) { ip = packet->nh.iph; new_entry->src_ip = ip->saddr; new_entry->dst_ip = ip->daddr; new_entry->ttl = ip->ttl; new_entry->dev = packet->dev; new_entry->size = packet->len-start_point; //create space for the data and copy it there if ((new_entry->data = kmalloc(new_entry->size,GFP_ATOMIC)) == NULL) { kfree(new_entry); printk(KERN_WARNING "AODV: Not enough memory to create Event Queue Data Entry\n"); return -ENOMEM; } memcpy(new_entry->data,packet->data+start_point,new_entry->size); } switch (type) { //RREP case EVENT_RREP: memcpy(&(new_entry->src_hw_addr),&(packet->mac.ethernet->h_source),sizeof(unsigned char)*ETH_ALEN); break; default: break; } /*lock table*/ lock_event(); //Set all the variables new_entry->next=event_queue; if (event_queue==NULL) end_event_queue=new_entry; else event_queue->prev=new_entry; event_queue=new_entry; /*unlock table*/ unlock_event(); //wake up the AODV thread kick_aodv(); return 0; } /**************************************************** get_last_event_queue_entry ---------------------------------------------------- Gets the last entry from the event queue ****************************************************/ struct event_queue_entry *get_next_event_queue_entry( void ) { struct event_queue_entry *temp_entry=NULL; /*lock table*/ lock_event(); if (end_event_queue!=NULL) { temp_entry=end_event_queue; if (temp_entry->prev==NULL) { end_event_queue=NULL; event_queue=NULL; } else { end_event_queue=temp_entry->prev; end_event_queue->next=NULL; } } /*unlock table*/ unlock_event(); return temp_entry; } /**************************************************** init_event_queue ---------------------------------------------------- Initalizes the event queue ****************************************************/ int init_event_queue( void ) { event_queue = NULL; end_event_queue = NULL; return 0; } /**************************************************** cleanup_event_queue ---------------------------------------------------- Deletes eveything in the event queue! ****************************************************/ int cleanup_event_queue(void ) { struct event_queue_entry *temp_entry=NULL; while ((temp_entry=get_next_event_queue_entry())!=NULL) { kfree(temp_entry->data); kfree(temp_entry); } return 0; }