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.


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