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.


d8c64f35b853c6dc79cc6a1f97359d215c9be88d
[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 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 struct topology g_links[MAX_LINKS];
46 int g_num_links; //The current number of links
47 int g_first_link;
48 int g_last_link;
49
50 struct routing g_routes[MAX_ROUTES];
51 int g_num_routes; //The current number of routes
52 int g_first_route;
53 int g_last_route;
54
55 struct device_list g_devices[MAX_DEVICES];
56 int g_num_devices;
57 int g_first_device;
58 int g_last_device;
59
60 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 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 // TODO: What is this used for?
415 int add_sock(struct sock_list *socks, int  len, int *first_sock, int *last_sock, SOCK fd) {
416   int i;
417
418   for (i = 0; i < len; i++) {
419       if (socks[i].sock == -1) {
420           socks[i].sock = fd;
421
422       if (*first_sock == -1) 
423             *first_sock = i;
424
425       socks[i].prev = *last_sock;
426       socks[i].next = -1;
427
428       if (*last_sock != -1) 
429             socks[*last_sock].next = i;
430
431       *last_sock = i;
432
433       return i;
434     }
435   }
436   return -1;
437 }
438
439
440 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) {
441   int i;
442
443   for(i = 0; i < MAX_ROUTES; i++) {
444       if (g_routes[i].use == 0) {
445      
446           if ((src_mac_qual != ANY_TYPE) && (src_mac_qual != NONE_TYPE)) {
447                 memcpy(g_routes[i].src_mac, src_mac, 6);
448           } else {
449                 memset(g_routes[i].src_mac, 0, 6);
450           }
451       
452           if ((dest_mac_qual != ANY_TYPE) && (dest_mac_qual != NONE_TYPE)) {
453                 memcpy(g_routes[i].dest_mac, dest_mac, 6);
454           } else {
455                 memset(g_routes[i].dest_mac, 0, 6);
456           }
457
458            g_routes[i].src_mac_qual = src_mac_qual;
459            g_routes[i].dest_mac_qual = dest_mac_qual;
460            g_routes[i].dest = dest;
461            g_routes[i].type = type;
462            g_routes[i].src = src;
463            g_routes[i].src_type = src_type;
464            g_routes[i].use = 1;
465
466            if (g_first_route == -1) 
467                  g_first_route = i;
468
469            g_routes[i].prev = g_last_route;
470            g_routes[i].next = -1;
471
472            if (g_last_route != -1) {
473                 g_routes[g_last_route].next = i;
474            }
475
476            g_last_route = i;
477
478            g_num_routes++;
479
480              return i;
481     }
482   }
483
484   clear_hash_cache();
485   
486   return -1;
487 }
488
489
490 static int find_link_entry(unsigned long dest, int type) 
491 {
492   int i;
493
494   FOREACH_LINK(i, g_links, g_first_link) {
495       if ((g_links[i].dest == dest) && 
496             ((type == -1) || (g_links[i].type == type)) ) {
497           return i;
498       }
499   } 
500
501   return -1;
502 }
503
504 static int delete_link_entry(int index) 
505 {
506   int next_i;
507   int prev_i;
508
509   if (g_links[index].use == 0) {
510     return -1;
511   }
512
513   g_links[index].dest = 0;
514   g_links[index].type = 0;
515   g_links[index].link_sock = -1;
516   g_links[index].use = 0;
517
518   prev_i = g_links[index].prev;
519   next_i = g_links[index].next;
520
521   if (prev_i != -1)
522     g_links[prev_i].next = g_links[index].next;
523
524   if (next_i != -1) 
525     g_links[next_i].prev = g_links[index].prev;
526
527   if (g_first_link == index)
528     g_first_link = g_links[index].next;
529
530   if (g_last_link == index) 
531     g_last_link = g_links[index].prev;
532
533   g_links[index].next = -1;
534   g_links[index].prev = -1;
535
536   g_num_links--;
537
538   return 0;
539 }
540
541 int vnet_delete_link_entry_by_addr(unsigned long dest, int type) 
542 {
543   int index = find_link_entry(dest, type);
544   
545   if (index == -1) {
546        return -1;
547   }
548
549   return delete_link_entry(index);
550 }
551
552
553 static int find_route_entry(char src_mac[6], 
554                                                         char dest_mac[6], 
555                                                         int src_mac_qual, 
556                                                         int dest_mac_qual, 
557                                                         int dest, 
558                                                         int type, 
559                                                         int src, 
560                                                         int src_type) 
561 {
562   int i;
563   char temp_src_mac[6];
564   char temp_dest_mac[6];
565   
566   if ((src_mac_qual != ANY_TYPE) && (src_mac_qual != NONE_TYPE)) {
567       memcpy(temp_src_mac, src_mac, 6);
568   } else {
569       memset(temp_src_mac, 0, 6);
570   }
571   
572   if ((dest_mac_qual != ANY_TYPE) && (dest_mac_qual != NONE_TYPE)) {
573       memcpy(temp_dest_mac, dest_mac, 6);
574   } else {
575       memset(temp_dest_mac, 0, 6);
576   }
577
578   FOREACH_LINK(i, g_routes, g_first_route) {
579       if ((memcmp(temp_src_mac, g_routes[i].src_mac, 6) == 0) && 
580             (memcmp(temp_dest_mac, g_routes[i].dest_mac, 6) == 0) &&
581             (g_routes[i].src_mac_qual == src_mac_qual) &&
582             (g_routes[i].dest_mac_qual == dest_mac_qual)  &&
583             ((type == -1) || 
584             ((type == g_routes[i].type) && (g_routes[i].dest == dest))) &&
585             ((src_type == -1) || 
586             ((src_type == g_routes[i].src_type) && (g_routes[i].src == src))) ) 
587       {
588           return i;
589       }
590   } 
591
592   return -1;
593 }
594
595 static int delete_route_entry(int index) 
596 {
597   
598   int next_i;
599   int prev_i;
600
601   memset(g_routes[index].src_mac, 0, 6);
602   memset(g_routes[index].dest_mac, 0, 6);
603
604   g_routes[index].dest = 0;
605   g_routes[index].src = 0;
606   g_routes[index].src_mac_qual = 0;
607   g_routes[index].dest_mac_qual = 0;
608   g_routes[index].type = -1;
609   g_routes[index].src_type = -1;
610   g_routes[index].use = 0;
611
612   prev_i = g_routes[index].prev;
613   next_i = g_routes[index].next;
614
615   if (prev_i != -1)
616     g_routes[prev_i].next = g_routes[index].next;
617
618   if (next_i != -1) 
619     g_routes[next_i].prev = g_routes[index].prev;
620
621   if (g_first_route == index)
622     g_first_route = g_routes[index].next;
623
624   if (g_last_route == index) 
625     g_last_route = g_routes[index].prev;
626
627   g_routes[index].next = -1;
628   g_routes[index].prev = -1;
629
630   g_num_routes--;
631
632   clear_hash_cache();
633
634   return 0;
635 }
636
637 int vnet_delete_route_entry_by_addr(char src_mac[6], 
638                                                                                 char dest_mac[6], 
639                                                                                 int src_mac_qual, 
640                                                                                 int dest_mac_qual, 
641                                                                                 int dest, 
642                                                                                 int type, 
643                                                                                 int src, 
644                                                                                 int src_type) 
645 {
646   int index = find_route_entry(src_mac, dest_mac, src_mac_qual, 
647                                                         dest_mac_qual, dest, type, src, src_type);
648   
649   if (index == -1) {
650       return -1;
651   }
652
653   delete_route_entry(index);
654
655   return 0;
656 }
657
658 int delete_sock(struct sock_list * socks, int *first_sock, int *last_sock, SOCK fd) {
659   int i;
660   int prev_i;
661   int next_i;
662
663   
664   FOREACH_SOCK(i, socks, (*first_sock)) {
665     if (socks[i].sock == fd) {
666       V3_Close_Socket(socks[i].sock);
667       socks[i].sock = -1;
668
669       prev_i = socks[i].prev;
670       next_i = socks[i].next;
671
672       if (prev_i != -1)
673         socks[prev_i].next = socks[i].next;
674       
675       if (next_i != -1) 
676         socks[next_i].prev = socks[i].prev;
677       
678       if (*first_sock == i)
679         *first_sock = socks[i].next;
680       
681       if (*last_sock == i) 
682         *last_sock = socks[i].prev;
683
684       socks[i].next = -1;
685       socks[i].prev = -1;
686
687       return 0;
688     }
689   }
690   return -1;
691 }
692
693 //setup the topology of the testing network
694 static void store_topologies(SOCK fd)
695 {
696         int i;
697         int src_mac_qual = ANY_TYPE;
698         int dest_mac_qual = ANY_TYPE;
699         uint_t dest;
700 #ifndef VNET_SERVER
701         dest = (0 | 172 << 24 | 23 << 16 | 1 ); //this is in_addr.s_addr
702         PrintDebug("VNET: store_topologies. NO VNET_SERVER, dest = %x\n", dest);
703 #elif
704         dest = (0 | 172 << 24 | 23 << 16 | 2 ); //this is in_addr.s_addr
705         PrintDebug("VNET: store_topologies. VNET_SERVER, dest = %x\n", dest);
706 #endif
707
708         int type = UDP_TYPE;
709         int src = 0;
710         int src_type= ANY_SRC_TYPE;
711         int data_port = 22;
712         
713         //store link table
714       for(i = 0; i < MAX_LINKS; i++) {
715           if (g_links[i].use == 0) {
716                g_links[i].dest = (int)dest;
717                g_links[i].type = type;
718                g_links[i].link_sock = fd;
719                g_links[i].remote_port = data_port;
720                g_links[i].use = 1;
721
722                if (g_first_link == -1) 
723                      g_first_link = i;
724
725                g_links[i].prev = g_last_link;
726                g_links[i].next = -1;
727       
728                if (g_last_link != -1) {
729                      g_links[g_last_link].next = i;
730                }
731
732                g_last_link = i;
733
734                g_num_links++;
735                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);
736          }
737       }
738
739   
740         //store route table
741
742         type = EDGE_TYPE;
743         dest =0;
744
745         for(i = 0; i < MAX_ROUTES; i++) {
746                 if (g_routes[i].use == 0) {
747                  if ((src_mac_qual != ANY_TYPE) && (src_mac_qual != NONE_TYPE)) {
748         //                  memcpy(g_routes[i].src_mac, src_mac, 6);
749                     } else {
750                         memset(g_routes[i].src_mac, 0, 6);
751                     }
752       
753                     if ((dest_mac_qual != ANY_TYPE) && (dest_mac_qual != NONE_TYPE)) {
754         //                  memcpy(g_routes[i].dest_mac, dest_mac, 6);
755                     } else {
756                            memset(g_routes[i].dest_mac, 0, 6);
757                     }
758
759               g_routes[i].src_mac_qual = src_mac_qual;
760               g_routes[i].dest_mac_qual = dest_mac_qual;
761               g_routes[i].dest = (int)dest;
762               g_routes[i].type = type;
763               g_routes[i].src = src;
764               g_routes[i].src_type = src_type;
765               
766               g_routes[i].use = 1;
767
768               if (g_first_route == -1) 
769                         g_first_route = i;
770
771               g_routes[i].prev = g_last_route;
772               g_routes[i].next = -1;
773
774               if (g_last_route != -1) {
775                 g_routes[g_last_route].next = i;
776               }
777
778               g_last_route = i;
779
780               g_num_routes++;
781
782                 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);
783
784         }
785   }
786 }
787
788 static int match_route(char *src_mac, char *dst_mac, int src_type, int src_index, int *matches) 
789
790     int values[MAX_ROUTES];
791     int matched_routes[MAX_ROUTES];
792
793     int num_matches = 0;
794     int i;
795     int max = 0;
796     int no = 0;
797     int exact_match = 0;
798
799     FOREACH_ROUTE(i, g_routes, g_first_route) {
800             if ((g_routes[i].src_type != ANY_SRC_TYPE) &&
801                  ((g_routes[i].src_type != src_type) ||
802                  ((g_routes[i].src != src_index) &&
803                  (g_routes[i].src != -1))))
804             {
805               PrintDebug("Vnet: MatchRoute: Source route is on and does not match\n");
806               continue;
807             }
808
809             if ( (g_routes[i].dest_mac_qual == ANY_TYPE) &&
810              (g_routes[i].src_mac_qual == ANY_TYPE) ) 
811             {      
812                matched_routes[num_matches] = i;
813                values[num_matches] = 3;
814                num_matches++;
815             }
816             
817             if (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) 
818             {
819                if (g_routes[i].src_mac_qual !=  NOT_TYPE) {
820                  if (g_routes[i].dest_mac_qual == ANY_TYPE) {
821                 matched_routes[num_matches] = i;
822                 values[num_matches] = 6;
823               
824                 num_matches++;
825                    }else if (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) == 0) {
826                         if (g_routes[i].dest_mac_qual != NOT_TYPE) {   
827                                 matched_routes[num_matches] = i;
828                                 values[num_matches] = 8;    
829                                 exact_match = 1;
830                                 num_matches++;
831                         }
832                    }
833                }
834             }
835             
836             if (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) == 0) 
837             {
838                 if (g_routes[i].dest_mac_qual != NOT_TYPE) {
839                         if (g_routes[i].src_mac_qual == ANY_TYPE) {
840                               matched_routes[num_matches] = i;
841                               values[num_matches] = 6;
842
843                               num_matches++;
844                         } else if (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) {
845                                 if (g_routes[i].src_mac_qual != NOT_TYPE) {
846                                         if (exact_match == 0) {
847                                           matched_routes[num_matches] = i;
848                                           values[num_matches] = 8;
849                                           num_matches++;
850                                         }
851                                 }
852                         }
853               }
854             }
855             
856             if ((g_routes[i].dest_mac_qual == NOT_TYPE) &&
857                   (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) != 0)) 
858             {
859                 if (g_routes[i].src_mac_qual == ANY_TYPE) {
860                     matched_routes[num_matches] = i;
861                     values[num_matches] = 5;                
862                     num_matches++;    
863                } else if (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) {
864                         if (g_routes[i].src_mac_qual != NOT_TYPE) {      
865                               matched_routes[num_matches] = i;
866                               values[num_matches] = 7;                
867                               num_matches++;
868                         }
869                 }
870             }
871             
872             if ((g_routes[i].src_mac_qual == NOT_TYPE) &&
873                  (memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) != 0)) 
874             {
875                 if (g_routes[i].dest_mac_qual == ANY_TYPE) {
876                     matched_routes[num_matches] = i;
877                     values[num_matches] = 5;        
878                     num_matches++;
879                 } else if (memcmp((void *)&g_routes[i].dest_mac, (void *)dst_mac, 6) == 0) {
880                          if (g_routes[i].dest_mac_qual != NOT_TYPE) { 
881                               matched_routes[num_matches] = i;
882                               values[num_matches] = 7;
883                               num_matches++;
884                          }
885               }
886             }
887   }//end FOREACH_ROUTE
888
889   FOREACH_ROUTE(i, g_routes, g_first_route) {
890         if ((memcmp((void *)&g_routes[i].src_mac, (void *)src_mac, 6) == 0) &&
891                 (g_routes[i].dest_mac_qual == NONE_TYPE) &&
892                 ((g_routes[i].src_type == ANY_SRC_TYPE) ||
893         ((g_routes[i].src_type == src_type) &&
894                 ((g_routes[i].src == src_index) ||
895                 (g_routes[i].src == -1))))) {
896                       matched_routes[num_matches] = i;
897                       values[num_matches] = 4;
898                       PrintDebug("Vnet: MatchRoute: We matched a default route (%d)\n", i);
899                       num_matches++;
900         }
901   }
902  
903   //If many rules have been matched, we choose one which has the highest value rating
904   if (num_matches == 0) {
905         return 0;
906   }
907
908   for (i = 0; i < num_matches; i++) {
909         if (values[i] > max) {
910                 no = 0;
911                 max = values[i];
912                 matches[no] = matched_routes[i];
913                 no++;
914         } else if (values[i] == max) {
915               matches[no] = matched_routes[i];
916               no++;
917         }
918   }
919
920   return no;
921 }
922
923 static inline int if_write_pkt(struct vnet_if_device *iface, struct raw_ethernet_pkt *pkt)
924 {
925    return iface->input((uchar_t *)pkt->data, pkt->size);
926 }
927
928 static int handle_one_pkt(struct raw_ethernet_pkt *pkt)
929 {
930     int src_link_index = 0;     //the value of src_link_index of udp always is 0
931     int i;
932     char src_mac[6];
933     char dst_mac[6];
934
935     int matches[g_num_routes];
936     int num_matched_routes = 0;
937
938     struct HEADERS headers;
939   
940     // get the ethernet and ip headers from the packet
941     memcpy((void *)&headers, (void *)pkt->data, sizeof(headers));
942
943     int j;
944     for(j = 0;j < 6; j++) {
945        src_mac[j] = headers.ethernetsrc[j];
946        dst_mac[j] = headers.ethernetdest[j];
947     }
948
949
950 #ifdef DEBUG
951     char dest_str[18];
952     char src_str[18];
953
954     mac_to_string(src_mac, src_str);  
955     mac_to_string(dst_mac, dest_str);
956
957     PrintDebug("Vnet: HandleDataOverLink. SRC(%s), DEST(%s)\n", src_str, dest_str);
958 #endif
959
960     char hash_key[HASH_KEY_SIZE];
961     make_hash_key(hash_key, src_mac, dst_mac, EDGE_TYPE, src_link_index);
962
963     num_matched_routes = look_into_cache((route_hashkey_t)hash_key, matches);
964
965     if (num_matched_routes == -1) {//no match
966         num_matched_routes = match_route(src_mac, dst_mac, pkt->type, src_link_index, matches);
967
968          if (num_matched_routes > 0)
969              add_route_to_cache(hash_key, num_matched_routes,matches);      
970     }
971
972     PrintDebug("Vnet: HandleDataOverLink: Matches=%d\n", num_matched_routes);
973
974     for (i = 0; i < num_matched_routes; i++) {
975         int route_index = -1;
976         int link_index = -1;
977         int dev_index = -1;
978
979         route_index = matches[i];
980
981         PrintDebug("Vnet: HandleDataOverLink: Forward packet from link according to Route entry %d\n", route_index);
982
983         if (g_routes[route_index].type == EDGE_TYPE) {
984             link_index = g_routes[route_index].dest;
985
986             if(g_links[link_index].type == UDP_TYPE) {
987                 int size;
988
989                 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)  {
990                     PrintError("Vnet: sending by UDP Exception, %x\n", size);
991                     return -1;
992                 }
993
994                 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);
995
996             }else if (g_links[link_index].type == TCP_TYPE) {
997  
998             }
999         } else if (g_routes[route_index].type == INTERFACE_TYPE) {
1000             dev_index = g_routes[route_index].dest;
1001       
1002             PrintDebug("Writing Packet to device=%s\n", g_devices[dev_index].device->name);
1003
1004             if (if_write_pkt(g_devices[dev_index].device, pkt) == -1) {
1005                   PrintDebug("Can't write output packet to link\n");
1006                 return -1;
1007             }
1008         } else {
1009             PrintDebug("Vnet: Wrong Edge type\n");
1010         }
1011     }
1012
1013      return 0;
1014 }
1015
1016 static int send_ethernet_pkt(char *buf, int length)
1017 {
1018         struct raw_ethernet_pkt *pt;
1019
1020         pt = (struct raw_ethernet_pkt *)V3_Malloc(sizeof(struct raw_ethernet_pkt));
1021         raw_ethernet_packet_init(pt, buf, length);  //====here we copy sending data once 
1022
1023         PrintDebug("VNET: vm_send_pkt: transmitting packet: (size:%d)\n", (int)pt->size);
1024         print_packet((char *)buf, length);
1025         
1026         v3_enqueue(g_inpkt_q, (addr_t)pt);
1027         return 0;
1028         
1029 }
1030
1031 int V3_Send_pkt(uchar_t *buf, int length)
1032 {
1033         PrintDebug("VNET: In V3_Send_pkt: pkt length %d\n", length);
1034
1035         return send_ethernet_pkt((char *)buf, length);
1036 }
1037
1038 static int add_device_to_table(struct vnet_if_device*device, int type) {
1039   int i;
1040
1041   for (i = 0; i < MAX_DEVICES; i++) {
1042       if (g_devices[i].use == 0) {
1043           g_devices[i].type = type;
1044           g_devices[i].use = 1;
1045
1046           if (g_first_device == -1) 
1047                 g_first_device = i;
1048
1049           g_devices[i].prev = g_last_device;
1050           g_devices[i].next = -1;
1051
1052           if (g_last_device != -1) 
1053                 g_devices[g_last_device].next = i;
1054
1055           g_last_device = i;
1056           g_num_devices++;
1057
1058             return i;
1059       }
1060   }
1061   
1062   return -1;
1063 }
1064
1065 static int search_device(char *device_name)
1066 {
1067     int i;
1068
1069     for (i=0; i<MAX_DEVICES; i++)
1070         if (g_devices[i].use == 1){
1071                 if (!strcmp(device_name, g_devices[i].device->name))
1072                         return i;
1073         }
1074
1075     return -1;
1076 }
1077
1078 static struct vnet_if_device* delete_device_from_table(int index) 
1079 {
1080     int next_i;
1081     int prev_i;
1082     struct vnet_if_device *device = NULL;
1083
1084     if (g_devices[index].use == 0) 
1085           return NULL;
1086
1087     g_devices[index].use = 0;
1088
1089     prev_i = g_devices[index].prev;
1090     next_i = g_devices[index].next;
1091
1092     if (prev_i != -1)
1093         g_devices[prev_i].next = g_devices[index].next;
1094
1095     if (next_i != -1) 
1096         g_devices[next_i].prev = g_devices[index].prev;
1097
1098     if (g_first_device == index)
1099         g_first_device = g_devices[index].next;
1100
1101     if (g_last_device == index) 
1102         g_last_device = g_devices[index].prev;
1103
1104     g_devices[index].next = -1;
1105     g_devices[index].prev = -1;
1106
1107     device = g_devices[index].device;
1108     g_devices[index].device = NULL;
1109
1110     g_num_devices--;
1111
1112     return device;
1113 }
1114
1115
1116 int vnet_register_device(char *dev_name, int (*netif_input)(uchar_t * pkt, uint_t size), void *data)
1117 {
1118         struct vnet_if_device *dev;
1119
1120         dev = (struct vnet_if_device *)V3_Malloc(sizeof(struct vnet_if_device));
1121
1122         if(dev == NULL){
1123                 PrintError("VNET: Malloc fails\n");
1124                 return -1;
1125         }
1126
1127         strncpy(dev->name, dev_name, (strlen(dev_name) < 50)?strlen(dev_name):50);
1128         dev->input = netif_input;
1129         dev->data = data;
1130
1131         if (add_device_to_table(dev, GENERAL_NIC) == -1)
1132                 return -1;
1133
1134         return 0;
1135 }
1136
1137 int vnet_unregister_device(char *dev_name)
1138 {
1139     int i;
1140
1141     i=search_device(dev_name);
1142     if (i == -1)
1143         return -1;
1144
1145     struct vnet_if_device *device = delete_device_from_table(i);
1146     if (device == NULL)
1147           return -1;
1148
1149     V3_Free(device);
1150
1151     return 0;
1152 }
1153
1154 int V3_Register_pkt_event(int (*netif_input)(uchar_t * pkt, uint_t size))
1155 {
1156         return vnet_register_device("NE2000", netif_input, NULL);
1157
1158 }
1159 int vnet_pkt_process()
1160 {
1161         struct raw_ethernet_pkt *pt;
1162         int i;
1163
1164         PrintDebug("VNET: In vnet_check\n");
1165         
1166         while ((pt = (struct raw_ethernet_pkt *)v3_dequeue(g_inpkt_q)) != NULL){
1167
1168                 PrintDebug("VNET: In vnet_check: pt length %d, pt type %d\n", (int)pt->size, (int)pt->type);
1169
1170                 for (i = 0; i <  (int)pt->size; i++)
1171                         PrintDebug("%x ", pt->data[i]);
1172                 PrintDebug("\n");
1173         
1174               if(handle_one_pkt(pt)) {
1175                         PrintDebug("VNET: vnet_check: handle one packet!\n");  
1176                 }
1177
1178                 V3_Free(pt); //be careful here
1179         }
1180
1181         return 0;
1182 }
1183
1184 static int process_tcpdata()
1185 {
1186         return 0;
1187 }
1188
1189 static int process_udpdata()
1190 {
1191
1192   struct raw_ethernet_pkt *pt;
1193
1194   unsigned long dest = 0;
1195   unsigned short remote_port = 0;
1196   SOCK link_sock = g_udp_sockfd;
1197   int length = sizeof(struct raw_ethernet_pkt) - 2*sizeof(int);   //minus the "size" and "type" 
1198
1199   //run in a loop to get packets from outside network, adding them to the incoming packet queue
1200   while (1) {
1201         pt = (struct raw_ethernet_pkt *)V3_Malloc(sizeof(struct raw_ethernet_pkt));
1202         if (pt == NULL){
1203                 PrintError("Vnet: process_udp: Malloc fails\n");
1204                 continue;
1205         }
1206
1207         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);
1208         pt->size = V3_RecvFrom_IP( link_sock, dest, remote_port, pt->data, length);
1209         PrintDebug("Vnet: route_thread: socket: %d receive from ip %x, port [%d]\n", link_sock, (uint_t)dest, remote_port);
1210
1211         if (pt->size <= 0){
1212                 PrintDebug("Vnet: process_udp: receiving packet from UDP fails\n");
1213                 V3_Free(pt);
1214                 return -1;
1215         }
1216
1217        PrintDebug("Vnet: process_udp: get packet\n");
1218         print_packet(pt->data, pt->size);
1219         
1220         v3_enqueue(g_inpkt_q, (addr_t)pt);
1221
1222         //V3_Yield();
1223   }
1224 }
1225
1226 static int indata_handler( )
1227 {
1228       if (use_tcp)
1229            process_tcpdata();
1230       else
1231            process_udpdata( );    
1232
1233       return 0;   
1234 }
1235
1236 static int start_recv_data()
1237 {
1238         if (use_tcp){
1239                 
1240         } else {
1241                 SOCK udp_data_socket;
1242   
1243                 if ((udp_data_socket = V3_Create_UDP_Socket()) < 0){
1244                         PrintError("VNET: Can't setup udp socket\n");
1245                         return -1; 
1246                 }
1247                 PrintDebug("Vnet: vnet_setup_udp: get socket: %d\n", udp_data_socket);
1248                 g_udp_sockfd = udp_data_socket;
1249
1250                 store_topologies(udp_data_socket);
1251
1252                 if (V3_Bind_Socket(udp_data_socket, vnet_udp_port) < 0){ 
1253                         PrintError("VNET: Can't bind socket\n");
1254                         return -1;
1255                 }
1256                 PrintDebug("VNET: vnet_setup_udp: bind socket successful\n");
1257         }
1258
1259         V3_CREATE_THREAD(&indata_handler, NULL, "VNET_DATA_HANDLER");
1260         return 0;
1261 }
1262
1263 static void init_link_table()
1264 {
1265     int i;
1266     for (i = 0; i < MAX_LINKS; i++) {
1267         g_links[i].use = 0;
1268         g_links[i].next = -1;
1269         g_links[i].prev = -1;
1270     }
1271         
1272     g_first_link = -1;
1273     g_last_link = -1;
1274     g_num_links = 0;
1275 }
1276
1277 static void init_device_table()
1278 {
1279     int i;
1280     for (i = 0; i < MAX_DEVICES; i++) {
1281         g_devices[i].use = 0;
1282         g_devices[i].next = -1;
1283         g_devices[i].prev = -1;
1284     }
1285         
1286     g_first_device = -1;
1287     g_last_device = -1;
1288     g_num_devices = 0;
1289 }
1290
1291 static void init_route_table()
1292 {       
1293     int i;
1294     for (i = 0; i < MAX_ROUTES; i++) {
1295         g_routes[i].use = 0;
1296         g_routes[i].next = -1;
1297         g_routes[i].prev = -1;
1298     }
1299         
1300      g_first_route = -1;
1301      g_last_route = -1;
1302      g_num_routes = 0;
1303 }
1304
1305 static void init_tables()
1306 {
1307     init_link_table();
1308     init_device_table();
1309     init_route_table();
1310     init_route_cache();
1311 }
1312
1313 static void init_pkt_queue()
1314 {
1315     PrintDebug("VNET Init package receiving queue\n");
1316
1317     g_inpkt_q = v3_create_queue();
1318     v3_init_queue(g_inpkt_q);
1319 }
1320
1321 void vnet_init()
1322 {       
1323         vnet_server = 0;
1324         #ifdef VNET_SERVER
1325                 vnet_server =1;
1326         #endif
1327
1328         PrintDebug("VNET Init: Vnet input queue successful.\n");
1329
1330         init_tables();
1331         init_pkt_queue();
1332  
1333         start_recv_data();
1334 }
1335
1336