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.


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