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.


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