Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Code format clean
[palacios.git] / palacios / src / devices / vnet.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu> 
11  * Copyright (c) 2009, Yuan Tang <ytang@northwestern.edu> 
12  * Copyright (c) 2009, Jack Lange <jarusl@cs.northwestern.edu> 
13  * Copyright (c) 2009, Peter Dinda <pdinda@northwestern.edu>
14  * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org> 
15  * All rights reserved.
16  *
17  * Author: Lei Xia <lxia@northwestern.edu>
18  *                Yuan Tang <ytang@northwestern.edu>
19  *                Jack Lange <jarusl@cs.northwestern.edu> 
20  *                Peter Dinda <pdinda@northwestern.edu
21  *
22  * This is free software.  You are permitted to use,
23  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
24  */
25  
26 #include <devices/vnet.h>
27
28 struct raw_ethernet_pkt {
29   int  size;
30   int type; // vm or link type:  INTERFACE|EDGE
31   char  data[ETHERNET_PACKET_LEN];
32 };
33
34 //static char *vnet_version = "0.9";
35 static int vnet_server = 0;
36 static bool use_tcp = false;
37
38 static uint_t vnet_udp_port = 22;
39
40 #define MAX_LINKS 1
41 #define MAX_ROUTES 1
42 #define MAX_DEVICES 16
43
44
45 static struct topology g_links[MAX_LINKS];
46 static int g_num_links; //The current number of links
47 static int g_first_link;
48 static int g_last_link;
49
50 static struct routing g_routes[MAX_ROUTES];
51 static int g_num_routes; //The current number of routes
52 static int g_first_route;
53 static int g_last_route;
54
55 static struct device_list g_devices[MAX_DEVICES];
56 static int g_num_devices;
57 static int g_first_device;
58 static int g_last_device;
59
60 static SOCK g_udp_sockfd;
61 static struct gen_queue * g_inpkt_q;//packet receiving queue
62
63
64 static void print_packet(char *pkt, int size)
65 {
66       int i;
67            
68         PrintDebug("Vnet: print_data_packet: size: %d\n", size);
69         for (i = 0; i < size; i ++)
70                 PrintDebug("%x ", pkt[i]);
71         PrintDebug("\n");
72 }
73
74 #if 0
75 static void print_packet_addr(char *pkt)
76 {
77        int i;
78            
79         PrintDebug("Vnet: print_packet_destination_addr: ");
80         for (i = 8; i < 14; i ++)
81                 PrintDebug("%x ", pkt[i]);
82         PrintDebug("\n");
83         
84         PrintDebug("Vnet: print_packet_source_addr: ");
85         for (i = 14; i < 20; i ++)
86                 PrintDebug("%x ", pkt[i]);
87         PrintDebug("\n");
88 }
89
90 static void print_device_addr(char *ethaddr)
91 {
92       int i;
93            
94         PrintDebug("Vnet: print_device_addr: ");
95         for (i = 0; i < 6; i ++)
96                 PrintDebug("%x ", ethaddr[i]);
97         PrintDebug("\n");
98
99 #endif
100
101 //network connection functions 
102
103 #if 0
104 static int CreateAndSetupTcpSocket(const int bufsize, const bool nodelay, const bool nonblocking)
105 {
106   int mysocket;
107
108   // create socket for connections
109   if ((mysocket = V3_Create_TCP_Socket()) < 0) {
110     return -1;
111   }
112
113   return mysocket;
114 }
115
116 static int BindSocketwPort(const int mysocket, const int myport)
117 {
118    if (V3_Bind_Socket(mysocket, myport) < 0) {
119     return -1;
120   }
121   
122   return 0;
123 }  
124
125 static int ListenSocket(const int mysocket, const int maxc)
126 {
127   return V3_Listen_Socket(mysocket, maxc);
128 }
129
130 static int ConnectToHost(const int mysocket, const int hostip, const int port)
131 {
132   return V3_Connect_To_IP(mysocket, hostip, port);
133 }
134
135
136 static void close(int mysocket)
137 {
138   V3_Close_Socket(mysocket);
139 }
140
141 static int raw_ethernet_pkt_sendUdp(struct raw_ethernet_pkt *pt, int sock_fd, int ip, short port)
142 {
143     int size;
144
145     PrintDebug("Vnet: sending by UDP socket %d  ip: %x,  port: %d\n", sock_fd, ip, port);
146   
147     if ((size = V3_SendTo_IP(sock_fd, ip, port, pt->data, pt->size)) != pt->size) {
148         PrintError("Vnet: sending by UDP Exception, %x\n", size);
149         return -1;
150     }
151  
152     return 0;
153 }
154
155 #endif
156
157 static void raw_ethernet_packet_init(struct raw_ethernet_pkt *pt, const char *data, const size_t size)
158 {
159   pt->size = size;
160   memcpy(pt->data, data, size);
161 }
162
163 #define in_range(c, lo, up)  ((char)c >= lo && (char)c <= up)
164 //#define islower(c)           in_range(c, 'a', 'z')
165
166
167 #define HASH_KEY_SIZE 16
168 #define MIN_CACHE_SIZE 100
169
170 /* Hash key format:
171  * 0-5:     src_eth_addr
172  * 6-11:    dest_eth_addr
173  * 12:      src type
174  * 13-16:   src index
175  */
176 typedef char * route_hashkey_t;
177
178 struct route_cache_entry  // This is the hash value, Format: 0: num_matched_routes, 1...n: matches[] -- TY
179 {
180     int num_matched_routes;
181     int *matches; 
182 };
183
184 static struct hashtable *g_route_cache; //Header of the route cache
185
186 static uint_t hash_from_key_fn(addr_t hashkey)
187 {
188     uint_t hash = 0;
189     uint_t temp = 0; 
190     int i;
191
192     char *key =(char *)hashkey;
193
194     for (i = 0; i < HASH_KEY_SIZE; i++) {
195         hash = (hash << 4) + *(key + i) + i;
196         if ((temp = (hash & 0xF0000000))) {
197               hash ^= (temp >> 24);
198         }
199         hash &= ~temp;
200     }
201     PrintDebug("Hash Value: %lu\n", (unsigned long)hash);
202         
203     return hash;
204 }
205
206 static int hash_key_equal(addr_t left, addr_t right)
207 {
208     int i;
209     char *key1, *key2;
210  
211     key1 = (char *)left;
212     key2 = (char *)right;
213         
214     for(i = 0; i < HASH_KEY_SIZE; i++) {
215         if (key1[i] != key2[i]) {
216               PrintDebug("HASHes not equal\n");
217
218               return -1;
219         }
220     }
221     return 0;
222 }
223
224 static int init_route_cache()
225 {
226     g_route_cache = v3_create_htable(MIN_CACHE_SIZE, &hash_from_key_fn, &hash_key_equal);
227
228     if (g_route_cache == NULL){
229         PrintError("Vnet: Route Cache Initiate Failurely\n");
230         return -1;
231     }
232
233     return 0;
234 }
235
236 static void make_hash_key(route_hashkey_t hashkey, char src_addr[6], char dest_addr[6], char src_type, int src_index) {
237         int j;
238
239         for(j = 0; j < 6; j++) {
240                 hashkey[j] = src_addr[j];
241                 hashkey[j + 6] = dest_addr[j] + 1;
242         }
243         hashkey[12] = src_type;
244         *(int *)(hashkey + 12) = src_index;
245 }
246
247 static int add_route_to_cache(route_hashkey_t hashkey, int num_matched_r, int *matches)
248 {
249       struct route_cache_entry *new_entry = (struct route_cache_entry *)V3_Malloc(sizeof(struct route_cache_entry));
250
251         if (new_entry == NULL){
252                 PrintError("Vnet: Malloc fails\n");
253                 return -1;
254         }
255
256         new_entry->num_matched_routes = num_matched_r;
257         int i;
258
259         new_entry->matches = (int *)V3_Malloc(num_matched_r*sizeof(int)); // TODO: Here need to consider where to release the memory when clear cache;
260
261         if (new_entry->matches == NULL){
262                 PrintError("Vnet: Malloc fails\n");
263                 return -1;
264         }
265  
266       for(i = 0; i < num_matched_r; i++) {
267                 new_entry->matches[i] = matches[i];
268       }
269
270         //here, when v3_htable_insert return 0, it means insert fails
271       if (v3_htable_insert(g_route_cache, (addr_t)hashkey, (addr_t)new_entry) == 0){
272                 PrintError("Vnet: Insert new route entry to cache failed\n");
273                 V3_Free(new_entry->matches);
274                 V3_Free(new_entry);
275         }
276           
277         return 0;
278 }
279
280 static int clear_hash_cache() 
281 {
282     v3_free_htable(g_route_cache, 1, 1);
283                 
284     g_route_cache = v3_create_htable(MIN_CACHE_SIZE, hash_from_key_fn, hash_key_equal);
285
286     if (g_route_cache == NULL){
287         PrintError("Vnet: Route Cache Create Failurely\n");
288         return -1;
289     }
290
291     return 0;
292 }
293
294 static int look_into_cache(route_hashkey_t hashkey, int *matches) 
295 {
296     int n_matches = -1;
297     int i;
298     struct route_cache_entry *found;
299
300     found = (struct route_cache_entry *)v3_htable_search(g_route_cache, (addr_t)hashkey);
301    
302     if (found != NULL) {
303         n_matches = found->num_matched_routes;
304         for (i = 0; i < n_matches; i++)
305             matches[i] = found->matches[i];
306     }
307
308     return n_matches;
309 }
310
311
312 static inline char vnet_toupper(char c)
313 {
314         if (islower(c))
315                 c -= 'a'-'A';
316         return c;
317 }
318
319 static inline char hexnybbletonybble(const char hexnybble) {
320   char x = vnet_toupper(hexnybble);
321   if ((x >= '0') && (x <= '9')) {
322     return x - '0';
323   } else {
324     return 10 + (x - 'A');
325   }
326 }
327
328 static inline void hexbytetobyte(const char hexbyte[2], char *byte) {
329   *byte = ((hexnybbletonybble(hexbyte[0]) << 4) + 
330            (hexnybbletonybble(hexbyte[1]) & 0xf));
331 }
332
333 static inline char nybbletohexnybble(const char nybble) {
334   return (nybble >= 10) ? (nybble - 10 + 'A') : (nybble + '0');
335 }
336
337 static inline void bytetohexbyte(const char byte, char hexbyte[2]) {
338   hexbyte[0] = nybbletohexnybble((byte >> 4) & 0xf);
339   hexbyte[1] = nybbletohexnybble(byte & 0xf);
340 }
341
342 static inline void string_to_mac(const char * str, char mac[6]) {
343   int k;
344   for(k = 0; k < 6; k++) {
345     hexbytetobyte(&(str[(2 * k) + k]), mac + k);
346   }
347 }
348
349 static inline void mac_to_string(char address[6], char * buf) {
350   int i;
351   for (i = 0; i < 6; i++) {
352     bytetohexbyte(address[i], &(buf[3 * i]));
353     buf[(3 * i) + 2] = ':';
354   }
355   buf[17] = 0;
356 }
357
358 /*
359 static void ip_to_string(ulong_t addr, char * buf) {
360   uint32_t addr_st;
361   char * tmp_str;
362
363   addr_st = v3_htonl(addr);
364   tmp_str = v3_inet_ntoa(addr_st);
365
366   memcpy(buf, tmp_str, strlen(tmp_str));
367 }
368 */
369
370 int find_link_by_fd(SOCK sock) {
371   int i;
372
373   FOREACH_LINK(i, g_links, g_first_link) {
374       if (g_links[i].link_sock == sock) {
375           return i;
376       }
377   }
378
379   return -1;
380 }
381
382 int vnet_add_link_entry(unsigned long dest, int type, int data_port,  SOCK fd) {
383   int i;
384
385   for(i = 0; i < MAX_LINKS; i++) {
386       if (g_links[i].use == 0) {
387           g_links[i].dest = dest;
388           g_links[i].type = type;
389           g_links[i].link_sock = fd;
390           g_links[i].remote_port = data_port;
391           g_links[i].use = 1;
392           if (g_first_link == -1) 
393                 g_first_link = i;
394
395           g_links[i].prev = g_last_link;
396           g_links[i].next = -1;
397       
398           if (g_last_link != -1) {
399                 g_links[g_last_link].next = i;
400           }
401
402           g_last_link = i;
403
404           g_num_links++;
405
406             return i;
407     }
408   }
409   
410   return -1;
411 }
412
413
414 int add_sock(struct sock_list *socks, int  len, int *first_sock, int *last_sock, SOCK fd) {
415   int i;
416
417   for (i = 0; i < len; i++) {
418       if (socks[i].sock == -1) {
419           socks[i].sock = fd;
420
421       if (*first_sock == -1) 
422             *first_sock = i;
423
424       socks[i].prev = *last_sock;
425       socks[i].next = -1;
426
427       if (*last_sock != -1) 
428             socks[*last_sock].next = i;
429
430       *last_sock = i;
431
432       return i;
433     }
434   }
435   return -1;
436 }
437
438
439 int vnet_add_route_entry(char src_mac[6], char dest_mac[6], int src_mac_qual, int dest_mac_qual, int dest, int type, int src, int src_type) {
440   int i;
441
442   for(i = 0; i < MAX_ROUTES; i++) {
443       if (g_routes[i].use == 0) {
444      
445           if ((src_mac_qual != ANY_TYPE) && (src_mac_qual != NONE_TYPE)) {
446                 memcpy(g_routes[i].src_mac, src_mac, 6);
447           } else {
448                 memset(g_routes[i].src_mac, 0, 6);
449           }
450       
451           if ((dest_mac_qual != ANY_TYPE) && (dest_mac_qual != NONE_TYPE)) {
452                 memcpy(g_routes[i].dest_mac, dest_mac, 6);
453           } else {
454                 memset(g_routes[i].dest_mac, 0, 6);
455           }
456
457            g_routes[i].src_mac_qual = src_mac_qual;
458            g_routes[i].dest_mac_qual = dest_mac_qual;
459            g_routes[i].dest = dest;
460            g_routes[i].type = type;
461            g_routes[i].src = src;
462            g_routes[i].src_type = src_type;
463            g_routes[i].use = 1;
464
465            if (g_first_route == -1) 
466                  g_first_route = i;
467
468            g_routes[i].prev = g_last_route;
469            g_routes[i].next = -1;
470
471            if (g_last_route != -1) {
472                 g_routes[g_last_route].next = i;
473            }
474
475            g_last_route = i;
476
477            g_num_routes++;
478
479              return i;
480     }
481   }
482
483   clear_hash_cache();
484   
485   return -1;
486 }
487
488
489 static int find_link_entry(unsigned long dest, int type) 
490 {
491   int i;
492
493   FOREACH_LINK(i, g_links, g_first_link) {
494       if ((g_links[i].dest == dest) && 
495             ((type == -1) || (g_links[i].type == type)) ) {
496           return i;
497       }
498   } 
499
500   return -1;
501 }
502
503 static int delete_link_entry(int index) 
504 {
505   int next_i;
506   int prev_i;
507
508   if (g_links[index].use == 0) {
509     return -1;
510   }
511
512   g_links[index].dest = 0;
513   g_links[index].type = 0;
514   g_links[index].link_sock = -1;
515   g_links[index].use = 0;
516
517   prev_i = g_links[index].prev;
518   next_i = g_links[index].next;
519
520   if (prev_i != -1)
521     g_links[prev_i].next = g_links[index].next;
522
523   if (next_i != -1) 
524     g_links[next_i].prev = g_links[index].prev;
525
526   if (g_first_link == index)
527     g_first_link = g_links[index].next;
528
529   if (g_last_link == index) 
530     g_last_link = g_links[index].prev;
531
532   g_links[index].next = -1;
533   g_links[index].prev = -1;
534
535   g_num_links--;
536
537   return 0;
538 }
539
540 int vnet_delete_link_entry_by_addr(unsigned long dest, int type) 
541 {
542   int index = find_link_entry(dest, type);
543   
544   if (index == -1) {
545        return -1;
546   }
547
548   return delete_link_entry(index);
549 }
550
551
552 static int find_route_entry(char src_mac[6], 
553                                                         char dest_mac[6], 
554                                                         int src_mac_qual, 
555                                                         int dest_mac_qual, 
556                                                         int dest, 
557                                                         int type, 
558                                                         int src, 
559                                                         int src_type) 
560 {
561   int i;
562   char temp_src_mac[6];
563   char temp_dest_mac[6];
564   
565   if ((src_mac_qual != ANY_TYPE) && (src_mac_qual != NONE_TYPE)) {
566       memcpy(temp_src_mac, src_mac, 6);
567   } else {
568       memset(temp_src_mac, 0, 6);
569   }
570   
571   if ((dest_mac_qual != ANY_TYPE) && (dest_mac_qual != NONE_TYPE)) {
572       memcpy(temp_dest_mac, dest_mac, 6);
573   } else {
574       memset(temp_dest_mac, 0, 6);
575   }
576
577   FOREACH_LINK(i, g_routes, g_first_route) {
578       if ((memcmp(temp_src_mac, g_routes[i].src_mac, 6) == 0) && 
579             (memcmp(temp_dest_mac, g_routes[i].dest_mac, 6) == 0) &&
580             (g_routes[i].src_mac_qual == src_mac_qual) &&
581             (g_routes[i].dest_mac_qual == dest_mac_qual)  &&
582             ((type == -1) || 
583             ((type == g_routes[i].type) && (g_routes[i].dest == dest))) &&
584             ((src_type == -1) || 
585             ((src_type == g_routes[i].src_type) && (g_routes[i].src == src))) ) 
586       {
587           return i;
588       }
589   } 
590
591   return -1;
592 }
593
594 static int delete_route_entry(int index) 
595 {
596   
597   int next_i;
598   int prev_i;
599
600   memset(g_routes[index].src_mac, 0, 6);
601   memset(g_routes[index].dest_mac, 0, 6);
602
603   g_routes[index].dest = 0;
604   g_routes[index].src = 0;
605   g_routes[index].src_mac_qual = 0;
606   g_routes[index].dest_mac_qual = 0;
607   g_routes[index].type = -1;
608   g_routes[index].src_type = -1;
609   g_routes[index].use = 0;
610
611   prev_i = g_routes[index].prev;
612   next_i = g_routes[index].next;
613
614   if (prev_i != -1)
615     g_routes[prev_i].next = g_routes[index].next;
616
617   if (next_i != -1) 
618     g_routes[next_i].prev = g_routes[index].prev;
619
620   if (g_first_route == index)
621     g_first_route = g_routes[index].next;
622
623   if (g_last_route == index) 
624     g_last_route = g_routes[index].prev;
625
626   g_routes[index].next = -1;
627   g_routes[index].prev = -1;
628
629   g_num_routes--;
630
631   clear_hash_cache();
632
633   return 0;
634 }
635
636 int vnet_delete_route_entry_by_addr(char src_mac[6], 
637                                                                                 char dest_mac[6], 
638                                                                                 int src_mac_qual, 
639                                                                                 int dest_mac_qual, 
640                                                                                 int dest, 
641                                                                                 int type, 
642                                                                                 int src, 
643                                                                                 int src_type) 
644 {
645   int index = find_route_entry(src_mac, dest_mac, src_mac_qual, 
646                                                         dest_mac_qual, dest, type, src, src_type);
647   
648   if (index == -1) {
649       return -1;
650   }
651
652   delete_route_entry(index);
653
654   return 0;
655 }
656
657 int delete_sock(struct sock_list * socks, int *first_sock, int *last_sock, SOCK fd) {
658   int i;
659   int prev_i;
660   int next_i;
661
662   
663   FOREACH_SOCK(i, socks, (*first_sock)) {
664     if (socks[i].sock == fd) {
665       V3_Close_Socket(socks[i].sock);
666       socks[i].sock = -1;
667
668       prev_i = socks[i].prev;
669       next_i = socks[i].next;
670
671       if (prev_i != -1)
672         socks[prev_i].next = socks[i].next;
673       
674       if (next_i != -1) 
675         socks[next_i].prev = socks[i].prev;
676       
677       if (*first_sock == i)
678         *first_sock = socks[i].next;
679       
680       if (*last_sock == i) 
681         *last_sock = socks[i].prev;
682
683       socks[i].next = -1;
684       socks[i].prev = -1;
685
686       return 0;
687     }
688   }
689   return -1;
690 }
691
692 //setup the topology of the testing network
693 static void store_topologies(SOCK fd)
694 {
695         int i;
696         int src_mac_qual = ANY_TYPE;
697         int dest_mac_qual = ANY_TYPE;
698         uint_t dest;
699 #ifndef VNET_SERVER
700         dest = (0 | 172 << 24 | 23 << 16 | 1 ); //this is in_addr.s_addr
701         PrintDebug("VNET: store_topologies. NO VNET_SERVER, dest = %x\n", dest);
702 #elif
703         dest = (0 | 172 << 24 | 23 << 16 | 2 ); //this is in_addr.s_addr
704         PrintDebug("VNET: store_topologies. VNET_SERVER, dest = %x\n", dest);
705 #endif
706
707         int type = UDP_TYPE;
708         int src = 0;
709         int src_type= ANY_SRC_TYPE;
710         int data_port = 22;
711         
712         //store link table
713       for(i = 0; i < MAX_LINKS; i++) {
714           if (g_links[i].use == 0) {
715                g_links[i].dest = (int)dest;
716                g_links[i].type = type;
717                g_links[i].link_sock = fd;
718                g_links[i].remote_port = data_port;
719                g_links[i].use = 1;
720
721                if (g_first_link == -1) 
722                      g_first_link = i;
723
724                g_links[i].prev = g_last_link;
725                g_links[i].next = -1;
726       
727                if (g_last_link != -1) {
728                      g_links[g_last_link].next = i;
729                }
730
731                g_last_link = i;
732
733                g_num_links++;
734                PrintDebug("VNET: store_topologies. new link: socket: %d, remote %x:[%d]\n", g_links[i].link_sock, (uint_t)g_links[i].dest, g_links[i].remote_port);
735          }
736       }
737
738   
739         //store route table
740
741         type = EDGE_TYPE;
742         dest =0;
743
744         for(i = 0; i < MAX_ROUTES; i++) {
745                 if (g_routes[i].use == 0) {
746                  if ((src_mac_qual != ANY_TYPE) && (src_mac_qual != NONE_TYPE)) {
747         //                  memcpy(g_routes[i].src_mac, src_mac, 6);
748                     } else {
749                         memset(g_routes[i].src_mac, 0, 6);
750                     }
751       
752                     if ((dest_mac_qual != ANY_TYPE) && (dest_mac_qual != NONE_TYPE)) {
753         //                  memcpy(g_routes[i].dest_mac, dest_mac, 6);
754                     } else {
755                            memset(g_routes[i].dest_mac, 0, 6);
756                     }
757
758               g_routes[i].src_mac_qual = src_mac_qual;
759               g_routes[i].dest_mac_qual = dest_mac_qual;
760               g_routes[i].dest = (int)dest;
761               g_routes[i].type = type;
762               g_routes[i].src = src;
763               g_routes[i].src_type = src_type;
764               
765               g_routes[i].use = 1;
766
767               if (g_first_route == -1) 
768                         g_first_route = i;
769
770               g_routes[i].prev = g_last_route;
771               g_routes[i].next = -1;
772
773               if (g_last_route != -1) {
774                 g_routes[g_last_route].next = i;
775               }
776
777               g_last_route = i;
778
779               g_num_routes++;
780
781                 PrintDebug("VNET: store_topologies. new route: src_mac: %s, dest_mac: %s, dest: %d\n", g_routes[i].src_mac, g_routes[i].dest_mac, dest);
782
783         }
784   }
785 }
786
787 static int match_route(char *src_mac, char *dst_mac, int src_type, int src_index, int *matches) 
788
789     int values[MAX_ROUTES];
790     int matched_routes[MAX_ROUTES];
791
792     int num_matches = 0;
793     int i;
794     int max = 0;
795     int no = 0;
796     int exact_match = 0;
797
798     FOREACH_ROUTE(i, g_routes, g_first_route) {
799             if ((g_routes[i].src_type != ANY_SRC_TYPE) &&
800                  ((g_routes[i].src_type != src_type) ||
801                  ((g_routes[i].src != src_index) &&
802                  (g_routes[i].src != -1))))
803             {
804               PrintDebug("Vnet: MatchRoute: Source route is on and does not match\n");
805               continue;
806             }
807
808             if ( (g_routes[i].dest_mac_qual == ANY_TYPE) &&
809              (g_routes[i].src_mac_qual == ANY_TYPE) ) 
810             {      
811                matched_routes[num_matches] = i;
812                values[num_matches] = 3;
813                num_matches++;
814             }
815             
816             if (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) 
817             {
818                if (g_routes[i].src_mac_qual !=  NOT_TYPE) {
819                  if (g_routes[i].dest_mac_qual == ANY_TYPE) {
820                 matched_routes[num_matches] = i;
821                 values[num_matches] = 6;
822               
823                 num_matches++;
824                    }else if (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) == 0) {
825                         if (g_routes[i].dest_mac_qual != NOT_TYPE) {   
826                                 matched_routes[num_matches] = i;
827                                 values[num_matches] = 8;    
828                                 exact_match = 1;
829                                 num_matches++;
830                         }
831                    }
832                }
833             }
834             
835             if (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) == 0) 
836             {
837                 if (g_routes[i].dest_mac_qual != NOT_TYPE) {
838                         if (g_routes[i].src_mac_qual == ANY_TYPE) {
839                               matched_routes[num_matches] = i;
840                               values[num_matches] = 6;
841
842                               num_matches++;
843                         } else if (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) {
844                                 if (g_routes[i].src_mac_qual != NOT_TYPE) {
845                                         if (exact_match == 0) {
846                                           matched_routes[num_matches] = i;
847                                           values[num_matches] = 8;
848                                           num_matches++;
849                                         }
850                                 }
851                         }
852               }
853             }
854             
855             if ((g_routes[i].dest_mac_qual == NOT_TYPE) &&
856                   (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) != 0)) 
857             {
858                 if (g_routes[i].src_mac_qual == ANY_TYPE) {
859                     matched_routes[num_matches] = i;
860                     values[num_matches] = 5;                
861                     num_matches++;    
862                } else if (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) {
863                         if (g_routes[i].src_mac_qual != NOT_TYPE) {      
864                               matched_routes[num_matches] = i;
865                               values[num_matches] = 7;                
866                               num_matches++;
867                         }
868                 }
869             }
870             
871             if ((g_routes[i].src_mac_qual == NOT_TYPE) &&
872                  (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) != 0)) 
873             {
874                 if (g_routes[i].dest_mac_qual == ANY_TYPE) {
875                     matched_routes[num_matches] = i;
876                     values[num_matches] = 5;        
877                     num_matches++;
878                 } else if (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) == 0) {
879                          if (g_routes[i].dest_mac_qual != NOT_TYPE) { 
880                               matched_routes[num_matches] = i;
881                               values[num_matches] = 7;
882                               num_matches++;
883                          }
884               }
885             }
886   }//end FOREACH_ROUTE
887
888   FOREACH_ROUTE(i, g_routes, g_first_route) {
889         if ((memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) &&
890                 (g_routes[i].dest_mac_qual == NONE_TYPE) &&
891                 ((g_routes[i].src_type == ANY_SRC_TYPE) ||
892         ((g_routes[i].src_type == src_type) &&
893                 ((g_routes[i].src == src_index) ||
894                 (g_routes[i].src == -1))))) {
895                       matched_routes[num_matches] = i;
896                       values[num_matches] = 4;
897                       PrintDebug("Vnet: MatchRoute: We matched a default route (%d)\n", i);
898                       num_matches++;
899         }
900   }
901  
902   //If many rules have been matched, we choose one which has the highest value rating
903   if (num_matches == 0) {
904         return 0;
905   }
906
907   for (i = 0; i < num_matches; i++) {
908         if (values[i] > max) {
909                 no = 0;
910                 max = values[i];
911                 matches[no] = matched_routes[i];
912                 no++;
913         } else if (values[i] == max) {
914               matches[no] = matched_routes[i];
915               no++;
916         }
917   }
918
919   return no;
920 }
921
922 static inline int if_write_pkt(struct vnet_if_device *iface, struct raw_ethernet_pkt *pkt)
923 {
924    return iface->input((uchar_t *)pkt->data, pkt->size);
925 }
926
927 static int handle_one_pkt(struct raw_ethernet_pkt *pkt)
928 {
929     int src_link_index = 0;     //the value of src_link_index of udp always is 0
930     int i;
931     char src_mac[6];
932     char dst_mac[6];
933
934     int matches[g_num_routes];
935     int num_matched_routes = 0;
936
937     struct HEADERS headers;
938   
939     // get the ethernet and ip headers from the packet
940     memcpy((void *)&headers, (void *)pkt->data, sizeof(headers));
941
942     int j;
943     for(j = 0;j < 6; j++) {
944        src_mac[j] = headers.ethernetsrc[j];
945        dst_mac[j] = headers.ethernetdest[j];
946     }
947
948
949 #ifdef DEBUG
950     char dest_str[18];
951     char src_str[18];
952
953     mac_to_string(src_mac, src_str);  
954     mac_to_string(dst_mac, dest_str);
955
956     PrintDebug("Vnet: HandleDataOverLink. SRC(%s), DEST(%s)\n", src_str, dest_str);
957 #endif
958
959     char hash_key[HASH_KEY_SIZE];
960     make_hash_key(hash_key, src_mac, dst_mac, EDGE_TYPE, src_link_index);
961
962     num_matched_routes = look_into_cache((route_hashkey_t)hash_key, matches);
963
964     if (num_matched_routes == -1) {//no match
965         num_matched_routes = match_route(src_mac, dst_mac, pkt->type, src_link_index, matches);
966
967          if (num_matched_routes > 0)
968              add_route_to_cache(hash_key, num_matched_routes,matches);      
969     }
970
971     PrintDebug("Vnet: HandleDataOverLink: Matches=%d\n", num_matched_routes);
972
973     for (i = 0; i < num_matched_routes; i++) {
974         int route_index = -1;
975         int link_index = -1;
976         int dev_index = -1;
977
978         route_index = matches[i];
979
980         PrintDebug("Vnet: HandleDataOverLink: Forward packet from link according to Route entry %d\n", route_index);
981
982         if (g_routes[route_index].type == EDGE_TYPE) {
983             link_index = g_routes[route_index].dest;
984
985             if(g_links[link_index].type == UDP_TYPE) {
986                 int size;
987
988                 if ((size = V3_SendTo_IP(g_links[link_index].link_sock,  g_links[link_index].dest,  g_links[link_index].remote_port, pkt->data, pkt->size)) != pkt->size)  {
989                     PrintError("Vnet: sending by UDP Exception, %x\n", size);
990                     return -1;
991                 }
992
993                 PrintDebug("Vnet: HandleDataOverLink: Serializing UDP Packet to link_sock [%d], dest [%x], remote_port [%d], size [%d]\n", g_links[link_index].link_sock, (uint_t)g_links[link_index].dest,  g_links[link_index].remote_port, (int)pkt->size);
994
995             }else if (g_links[link_index].type == TCP_TYPE) {
996  
997             }
998         } else if (g_routes[route_index].type == INTERFACE_TYPE) {
999             dev_index = g_routes[route_index].dest;
1000       
1001             PrintDebug("Writing Packet to device=%s\n", g_devices[dev_index].device->name);
1002
1003             if (if_write_pkt(g_devices[dev_index].device, pkt) == -1) {
1004                   PrintDebug("Can't write output packet to link\n");
1005                 return -1;
1006             }
1007         } else {
1008             PrintDebug("Vnet: Wrong Edge type\n");
1009         }
1010     }
1011
1012      return 0;
1013 }
1014
1015 static int send_ethernet_pkt(char *buf, int length)
1016 {
1017         struct raw_ethernet_pkt *pt;
1018
1019         pt = (struct raw_ethernet_pkt *)V3_Malloc(sizeof(struct raw_ethernet_pkt));
1020         raw_ethernet_packet_init(pt, buf, length);  //====here we copy sending data once 
1021
1022         PrintDebug("VNET: vm_send_pkt: transmitting packet: (size:%d)\n", (int)pt->size);
1023         print_packet((char *)buf, length);
1024         
1025         v3_enqueue(g_inpkt_q, (addr_t)pt);
1026         return 0;
1027         
1028 }
1029
1030 int V3_Send_pkt(uchar_t *buf, int length)
1031 {
1032         PrintDebug("VNET: In V3_Send_pkt: pkt length %d\n", length);
1033
1034         return send_ethernet_pkt((char *)buf, length);
1035 }
1036
1037 static int add_device_to_table(struct vnet_if_device*device, int type) {
1038   int i;
1039
1040   for (i = 0; i < MAX_DEVICES; i++) {
1041       if (g_devices[i].use == 0) {
1042           g_devices[i].type = type;
1043           g_devices[i].use = 1;
1044
1045           if (g_first_device == -1) 
1046                 g_first_device = i;
1047
1048           g_devices[i].prev = g_last_device;
1049           g_devices[i].next = -1;
1050
1051           if (g_last_device != -1) 
1052                 g_devices[g_last_device].next = i;
1053
1054           g_last_device = i;
1055           g_num_devices++;
1056
1057             return i;
1058       }
1059   }
1060   
1061   return -1;
1062 }
1063
1064 static int search_device(char *device_name)
1065 {
1066     int i;
1067
1068     for (i=0; i<MAX_DEVICES; i++)
1069         if (g_devices[i].use == 1){
1070                 if (!strcmp(device_name, g_devices[i].device->name))
1071                         return i;
1072         }
1073
1074     return -1;
1075 }
1076
1077 static struct vnet_if_device* delete_device_from_table(int index) 
1078 {
1079     int next_i;
1080     int prev_i;
1081     struct vnet_if_device *device = NULL;
1082
1083     if (g_devices[index].use == 0) 
1084           return NULL;
1085
1086     g_devices[index].use = 0;
1087
1088     prev_i = g_devices[index].prev;
1089     next_i = g_devices[index].next;
1090
1091     if (prev_i != -1)
1092         g_devices[prev_i].next = g_devices[index].next;
1093
1094     if (next_i != -1) 
1095         g_devices[next_i].prev = g_devices[index].prev;
1096
1097     if (g_first_device == index)
1098         g_first_device = g_devices[index].next;
1099
1100     if (g_last_device == index) 
1101         g_last_device = g_devices[index].prev;
1102
1103     g_devices[index].next = -1;
1104     g_devices[index].prev = -1;
1105
1106     device = g_devices[index].device;
1107     g_devices[index].device = NULL;
1108
1109     g_num_devices--;
1110
1111     return device;
1112 }
1113
1114
1115 int vnet_register_device(char *dev_name, int (*netif_input)(uchar_t * pkt, uint_t size), void *data)
1116 {
1117         struct vnet_if_device *dev;
1118
1119         dev = (struct vnet_if_device *)V3_Malloc(sizeof(struct vnet_if_device));
1120
1121         if(dev == NULL){
1122                 PrintError("VNET: Malloc fails\n");
1123                 return -1;
1124         }
1125
1126         strncpy(dev->name, dev_name, (strlen(dev_name) < 50)?strlen(dev_name):50);
1127         dev->input = netif_input;
1128         dev->data = data;
1129
1130         if (add_device_to_table(dev, GENERAL_NIC) == -1)
1131                 return -1;
1132
1133         return 0;
1134 }
1135
1136 int vnet_unregister_device(char *dev_name)
1137 {
1138     int i;
1139
1140     i=search_device(dev_name);
1141     if (i == -1)
1142         return -1;
1143
1144     struct vnet_if_device *device = delete_device_from_table(i);
1145     if (device == NULL)
1146           return -1;
1147
1148     V3_Free(device);
1149
1150     return 0;
1151 }
1152
1153 int V3_Register_pkt_event(int (*netif_input)(uchar_t * pkt, uint_t size))
1154 {
1155         return vnet_register_device("NE2000", netif_input, NULL);
1156
1157 }
1158 int vnet_pkt_process()
1159 {
1160         struct raw_ethernet_pkt *pt;
1161         int i;
1162
1163         PrintDebug("VNET: In vnet_check\n");
1164         
1165         while ((pt = (struct raw_ethernet_pkt *)v3_dequeue(g_inpkt_q)) != NULL){
1166
1167                 PrintDebug("VNET: In vnet_check: pt length %d, pt type %d\n", (int)pt->size, (int)pt->type);
1168
1169                 for (i = 0; i <  (int)pt->size; i++)
1170                         PrintDebug("%x ", pt->data[i]);
1171                 PrintDebug("\n");
1172         
1173               if(handle_one_pkt(pt)) {
1174                         PrintDebug("VNET: vnet_check: handle one packet!\n");  
1175                 }
1176
1177                 V3_Free(pt); //be careful here
1178         }
1179
1180         return 0;
1181 }
1182
1183 static int process_tcpdata()
1184 {
1185         return 0;
1186 }
1187
1188 static int process_udpdata()
1189 {
1190
1191   struct raw_ethernet_pkt *pt;
1192
1193   unsigned long dest = 0;
1194   unsigned short remote_port = 0;
1195   SOCK link_sock = g_udp_sockfd;
1196   int length = sizeof(struct raw_ethernet_pkt) - 2*sizeof(int);   //minus the "size" and "type" 
1197
1198   //run in a loop to get packets from outside network, adding them to the incoming packet queue
1199   while (1) {
1200         pt = (struct raw_ethernet_pkt *)V3_Malloc(sizeof(struct raw_ethernet_pkt));
1201         if (pt == NULL){
1202                 PrintError("Vnet: process_udp: Malloc fails\n");
1203                 continue;
1204         }
1205
1206         PrintDebug("Vnet: route_thread: socket: %d. ready to receive from ip %x, port [%d] or from VMs\n", link_sock, (uint_t)dest, remote_port);
1207         pt->size = V3_RecvFrom_IP( link_sock, dest, remote_port, pt->data, length);
1208         PrintDebug("Vnet: route_thread: socket: %d receive from ip %x, port [%d]\n", link_sock, (uint_t)dest, remote_port);
1209
1210         if (pt->size <= 0){
1211                 PrintDebug("Vnet: process_udp: receiving packet from UDP fails\n");
1212                 V3_Free(pt);
1213                 return -1;
1214         }
1215
1216        PrintDebug("Vnet: process_udp: get packet\n");
1217         print_packet(pt->data, pt->size);
1218         
1219         v3_enqueue(g_inpkt_q, (addr_t)pt);
1220
1221         //V3_Yield();
1222   }
1223 }
1224
1225 static int indata_handler( )
1226 {
1227       if (use_tcp)
1228            process_tcpdata();
1229       else
1230            process_udpdata( );    
1231
1232       return 0;   
1233 }
1234
1235 static int start_recv_data()
1236 {
1237         if (use_tcp){
1238                 
1239         } else {
1240                 SOCK udp_data_socket;
1241   
1242                 if ((udp_data_socket = V3_Create_UDP_Socket()) < 0){
1243                         PrintError("VNET: Can't setup udp socket\n");
1244                         return -1; 
1245                 }
1246                 PrintDebug("Vnet: vnet_setup_udp: get socket: %d\n", udp_data_socket);
1247                 g_udp_sockfd = udp_data_socket;
1248
1249                 store_topologies(udp_data_socket);
1250
1251                 if (V3_Bind_Socket(udp_data_socket, vnet_udp_port) < 0){ 
1252                         PrintError("VNET: Can't bind socket\n");
1253                         return -1;
1254                 }
1255                 PrintDebug("VNET: vnet_setup_udp: bind socket successful\n");
1256         }
1257
1258         V3_CREATE_THREAD(&indata_handler, NULL, "VNET_DATA_HANDLER");
1259         return 0;
1260 }
1261
1262 static void init_link_table()
1263 {
1264     int i;
1265     for (i = 0; i < MAX_LINKS; i++) {
1266         g_links[i].use = 0;
1267         g_links[i].next = -1;
1268         g_links[i].prev = -1;
1269     }
1270         
1271     g_first_link = -1;
1272     g_last_link = -1;
1273     g_num_links = 0;
1274 }
1275
1276 static void init_device_table()
1277 {
1278     int i;
1279     for (i = 0; i < MAX_DEVICES; i++) {
1280         g_devices[i].use = 0;
1281         g_devices[i].next = -1;
1282         g_devices[i].prev = -1;
1283     }
1284         
1285     g_first_device = -1;
1286     g_last_device = -1;
1287     g_num_devices = 0;
1288 }
1289
1290 static void init_route_table()
1291 {       
1292     int i;
1293     for (i = 0; i < MAX_ROUTES; i++) {
1294         g_routes[i].use = 0;
1295         g_routes[i].next = -1;
1296         g_routes[i].prev = -1;
1297     }
1298         
1299      g_first_route = -1;
1300      g_last_route = -1;
1301      g_num_routes = 0;
1302 }
1303
1304 static void init_tables()
1305 {
1306     init_link_table();
1307     init_device_table();
1308     init_route_table();
1309     init_route_cache();
1310 }
1311
1312 static void init_pkt_queue()
1313 {
1314     PrintDebug("VNET Init package receiving queue\n");
1315
1316     g_inpkt_q = v3_create_queue();
1317     v3_init_queue(g_inpkt_q);
1318 }
1319
1320 void vnet_init()
1321 {       
1322         vnet_server = 0;
1323         #ifdef VNET_SERVER
1324                 vnet_server =1;
1325         #endif
1326
1327         PrintDebug("VNET Init: Vnet input queue successful.\n");
1328
1329         init_tables();
1330         init_pkt_queue();
1331  
1332         start_recv_data();
1333 }
1334
1335