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.


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