X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fpalacios-vnet.c;h=454cd8db8e5f649addcb759b6d157096ee7f3003;hb=f904d129c5f7f44493bba3c9a82c150bbb613217;hp=ad51ee513b225c609e02883e25fa6b06dfd6ba00;hpb=260bb3e805ebc92ae294c3c2b36d027ba8bca488;p=palacios.git diff --git a/linux_module/palacios-vnet.c b/linux_module/palacios-vnet.c index ad51ee5..454cd8d 100644 --- a/linux_module/palacios-vnet.c +++ b/linux_module/palacios-vnet.c @@ -17,14 +17,13 @@ #include #include -#include #include "palacios-vnet.h" //#define DEBUG_VNET_BRIGE #define VNET_UDP_PORT 9000 -struct vnet_route { +struct palacios_vnet_route { struct v3_vnet_route route; int route_idx; @@ -66,7 +65,7 @@ struct palacios_vnet_state { static struct palacios_vnet_state vnet_state; -struct vnet_link * find_link_by_ip(uint32_t ip) { +struct vnet_link * link_by_ip(uint32_t ip) { struct vnet_link * link = NULL; list_for_each_entry(link, &(vnet_state.link_list), node) { @@ -79,7 +78,7 @@ struct vnet_link * find_link_by_ip(uint32_t ip) { return NULL; } -struct vnet_link * find_link_by_idx(int idx) { +struct vnet_link * link_by_idx(int idx) { struct vnet_link * link = NULL; list_for_each_entry(link, &(vnet_state.link_list), node) { @@ -91,8 +90,8 @@ struct vnet_link * find_link_by_idx(int idx) { return NULL; } -struct vnet_route * find_route_by_idx(int idx) { - struct vnet_route * route = NULL; +struct palacios_vnet_route * route_by_idx(int idx) { + struct palacios_vnet_route * route = NULL; list_for_each_entry(route, &(vnet_state.route_list), node) { @@ -109,119 +108,162 @@ static int parse_mac_str(char * str, uint8_t * qual, uint8_t * mac) { char * token; printk("Parsing MAC (%s)\n", str); + + *qual = MAC_NOSET; + if(strnicmp("any", str, strlen(str)) == 0){ + *qual = MAC_ANY; + return 0; + }else if(strnicmp("none", str, strlen(str)) == 0){ + *qual = MAC_NONE; + return 0; + }else{ + if (strstr(str, "-")) { + token = strsep(&str, "-"); + + if (strnicmp("not", token, strlen("not")) == 0) { + *qual = MAC_NOT; + } else { + printk("Invalid MAC String token (%s)\n", token); + return -1; + } + } - if (strstr(str, "-")) { - token = strsep(&str, "-"); + if (strstr(str, ":")) { + int i = 0; - if (strnicmp("not", token, strlen("not")) == 0) { - *qual = MAC_NOT; - } else { + if(*qual == MAC_NOSET){ + *qual = MAC_ADDR; + } + + for (i = 0; i < 6; i++) { + token = strsep(&str, ":"); + if (!token) { + printk("Invalid MAC String token (%s)\n", token); + return -1; + } + mac[i] = simple_strtol(token, &token, 16); + } + printk("MAC: %2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + }else { printk("Invalid MAC String token (%s)\n", token); return -1; } + } - if (!strstr(str, ":")) { - if (strnicmp("any", str, strlen("any")) == 0) { - printk("qual = any\n"); - *qual = MAC_ANY; - } else if (strnicmp("none", str, strlen("none")) == 0) { - printk("qual = None\n"); - *qual = MAC_NONE; - } else { - printk("Invalid MAC Qual token (%s)\n", str); - return -1; - } - - } else { - int i = 0; + return 0; +} - *qual = MAC_ADDR; - for (i = 0; i < 6; i++) { - token = strsep(&str, ":"); - mac[i] = simple_strtol(token, &token, 16); +static int str2mac(char * str, uint8_t * mac){ + int i = 0; + char *hex = NULL; + + for (i = 0; i < ETH_ALEN; i++) { + hex = strsep(&str, ":"); + if (!hex) { + printk("Invalid MAC String token (%s)\n", str); + return -1; } + mac[i] = simple_strtol(hex, &hex, 16); } - + return 0; } + +/* Format: + * add src-MAC dst-MAC dst-TYPE [dst-ID] src-TYPE [src-ID] + * + * src-MAC = dst-MAC = not-MAC|any|none|MAC + * dst-TYPE = edge|interface + * src-TYPE = edge|interface|any + * dst-ID = src-ID = IP|MAC + * MAC=xx:xx:xx:xx:xx:xx + * IP = xxx.xxx.xxx.xxx + */ static int parse_route_str(char * str, struct v3_vnet_route * route) { char * token = NULL; struct vnet_link *link = NULL; // src MAC token = strsep(&str, " "); - if (!token) { return -1; } - parse_mac_str(token, &(route->src_mac_qual), route->src_mac); // dst MAC token = strsep(&str, " "); - if (!token) { return -1; } - parse_mac_str(token, &(route->dst_mac_qual), route->dst_mac); // dst LINK type token = strsep(&str, " "); - if (!token) { return -1; } + printk("dst type =(%s)\n", token); if (strnicmp("interface", token, strlen("interface")) == 0) { route->dst_type = LINK_INTERFACE; - printk("DST type = INTERFACE\n"); } else if (strnicmp("edge", token, strlen("edge")) == 0) { route->dst_type = LINK_EDGE; - printk("DST type = EDGE\n"); } else { printk("Invalid Destination Link Type (%s)\n", token); return -1; } - - // dst link ID + // dst link token = strsep(&str, " "); - if (!token) { return -1; } + printk("dst link ID=(%s)\n", token); - printk("dst link ID=%s\n", token); - - // Figure out link ID here + // Figure out link here if (route->dst_type == LINK_EDGE) { uint32_t link_ip; - // Figure out Link Here if (in4_pton(token, strlen(token), (uint8_t *)&(link_ip), '\0', NULL) != 1) { printk("Invalid Dst IP address (%s)\n", token); return -EFAULT; } - - printk("link_ip = %d\n", link_ip); - link = find_link_by_ip(link_ip); + link = link_by_ip(link_ip); if (link != NULL){ route->dst_id = link->link_idx; }else{ printk("can not find dst link %s\n", token); return -1; } + + printk("link_ip = %d, link_id = %d\n", link_ip, link->link_idx); + } else if (route->dst_type == LINK_INTERFACE) { + uint8_t mac[ETH_ALEN]; + + if(str2mac(token, mac) == -1){ + printk("wrong MAC format (%s)\n", token); + return -1; + } + + route->dst_id = v3_vnet_find_dev(mac); + if (route->dst_id == -1){ + printk("can not find dst device %s\n", token); + return -1; + } } else { printk("Unsupported dst link type\n"); return -1; } + route->src_id = -1; + route->src_type = -1; + // src LINK token = strsep(&str, " "); @@ -233,13 +275,10 @@ static int parse_route_str(char * str, struct v3_vnet_route * route) { if (strnicmp("interface", token, strlen("interface")) == 0) { route->src_type = LINK_INTERFACE; - printk("SRC type = INTERFACE\n"); } else if (strnicmp("edge", token, strlen("edge")) == 0) { route->src_type = LINK_EDGE; - printk("SRC type = EDGE\n"); } else if (strnicmp("any", token, strlen("any")) == 0) { route->src_type = LINK_ANY; - printk("SRC type = ANY\n"); } else { printk("Invalid Src link type (%s)\n", token); return -1; @@ -247,7 +286,7 @@ static int parse_route_str(char * str, struct v3_vnet_route * route) { if (route->src_type == LINK_ANY) { - route->src_id = (uint32_t)-1; + route->src_id = -1; } else if (route->src_type == LINK_EDGE) { uint32_t src_ip; token = strsep(&str, " "); @@ -262,19 +301,31 @@ static int parse_route_str(char * str, struct v3_vnet_route * route) { return -EFAULT; } - link = find_link_by_ip(src_ip); + link = link_by_ip(src_ip); if (link != NULL){ route->src_id = link->link_idx; }else{ printk("can not find src link %s\n", token); return -1; } + } else if(route->src_type == LINK_INTERFACE){ + uint8_t mac[ETH_ALEN]; + + if(str2mac(token, mac) == -1){ + printk("wrong MAC format (%s)\n", token); + return -1; + } + + route->src_id = v3_vnet_find_dev(mac); + if (route->src_id == -1){ + printk("can not find dst device %s\n", token); + return -1; + } } else { printk("Invalid link type\n"); return -1; } - return 0; } @@ -282,7 +333,7 @@ static int parse_route_str(char * str, struct v3_vnet_route * route) { static void * route_seq_start(struct seq_file * s, loff_t * pos) { - struct vnet_route * route_iter = NULL; + struct palacios_vnet_route * route_iter = NULL; loff_t i = 0; @@ -307,7 +358,6 @@ static void * link_seq_start(struct seq_file * s, loff_t * pos) { struct vnet_link * link_iter = NULL; loff_t i = 0; - if (*pos >= vnet_state.num_links) { return NULL; } @@ -327,9 +377,9 @@ static void * link_seq_start(struct seq_file * s, loff_t * pos) { static void * route_seq_next(struct seq_file * s, void * v, loff_t * pos) { - struct vnet_route * route_iter = NULL; + struct palacios_vnet_route * route_iter = NULL; - route_iter = list_entry(((struct vnet_route *)v)->node.next, struct vnet_route, node); + route_iter = list_entry(((struct palacios_vnet_route *)v)->node.next, struct palacios_vnet_route, node); // Check if the list has looped if (&(route_iter->node) == &(vnet_state.route_list)) { @@ -373,12 +423,12 @@ static void link_seq_stop(struct seq_file * s, void * v) { } static int route_seq_show(struct seq_file * s, void * v) { - struct vnet_route * route_iter = v; + struct palacios_vnet_route * route_iter = v; struct v3_vnet_route * route = &(route_iter->route); - seq_printf(s, "%d:\t", route_iter->route_idx); + seq_printf(s, "\nSrc:\t"); switch (route->src_mac_qual) { case MAC_ANY: seq_printf(s, "any "); @@ -387,7 +437,7 @@ static int route_seq_show(struct seq_file * s, void * v) { seq_printf(s, "none "); break; case MAC_NOT: - seq_printf(s, "not-%x:%x:%x:%x:%x:%x ", + seq_printf(s, "not-%2x:%2x:%2x:%2x:%2x:%2x ", route->src_mac[0], route->src_mac[1], route->src_mac[2], route->src_mac[3], route->src_mac[4], route->src_mac[5]); break; @@ -398,6 +448,7 @@ static int route_seq_show(struct seq_file * s, void * v) { break; } + seq_printf(s, "\nDst:\t"); switch (route->dst_mac_qual) { case MAC_ANY: seq_printf(s, "any "); @@ -417,10 +468,10 @@ static int route_seq_show(struct seq_file * s, void * v) { break; } - + seq_printf(s, "\nDst-Type:\t"); switch (route->dst_type) { case LINK_EDGE: { - struct vnet_link * link = (struct vnet_link *)find_link_by_idx(route->dst_id); + struct vnet_link * link = (struct vnet_link *)link_by_idx(route->dst_id); seq_printf(s, "EDGE %pI4", &link->dst_ip); break; } @@ -434,13 +485,10 @@ static int route_seq_show(struct seq_file * s, void * v) { break; } - - - - + seq_printf(s, "\nSrc-Type:\t"); switch (route->src_type) { case LINK_EDGE: { - struct vnet_link * link = (struct vnet_link *)find_link_by_idx(route->src_id); + struct vnet_link * link = (struct vnet_link *)link_by_idx(route->src_id); seq_printf(s, "EDGE %pI4", &link->dst_ip); break; } @@ -500,9 +548,16 @@ static int link_open(struct inode * inode, struct file * file) { return seq_open(file, &link_seq_ops); } -static int inject_route(struct vnet_route * route) { +static int inject_route(struct palacios_vnet_route * route) { + unsigned long flags; + v3_vnet_add_route(route->route); + spin_lock_irqsave(&(vnet_state.lock), flags); + list_add(&(route->node), &(vnet_state.route_list)); + route->route_idx = vnet_state.num_routes++; + spin_unlock_irqrestore(&(vnet_state.lock), flags); + printk("Palacios-vnet: One route added to VNET core\n"); return 0; @@ -536,14 +591,14 @@ route_write(struct file * file, } if (strnicmp("ADD", token, strlen("ADD")) == 0) { - struct vnet_route * new_route = NULL; - new_route = kmalloc(sizeof(struct vnet_route), GFP_KERNEL); + struct palacios_vnet_route * new_route = NULL; + new_route = kmalloc(sizeof(struct palacios_vnet_route), GFP_KERNEL); if (!new_route) { return -ENOMEM; } - memset(new_route, 0, sizeof(struct vnet_route)); + memset(new_route, 0, sizeof(struct palacios_vnet_route)); if (parse_route_str(buf_iter, &(new_route->route)) == -1) { kfree(new_route); @@ -602,6 +657,8 @@ static int create_link(struct vnet_link * link) { return 0; } + +/* ADD dst-ip 9000 */ static ssize_t link_write(struct file * file, const char * buf, size_t size, loff_t * ppos) { char link_buf[256]; @@ -810,7 +867,7 @@ send_to_palacios(unsigned char * buf, memcpy(pkt.header, buf, ETHERNET_HEADER_LEN); pkt.data = buf; -#ifdef DEBUG_VNET_BRIGE +#ifdef CONFIG_PALACIOS_VNET_DEBUG { printk("VNET Lnx Bridge: send pkt to VNET core (size: %d, src_id: %d, src_type: %d)\n", pkt.size, pkt.src_id, pkt.src_type); @@ -819,7 +876,7 @@ send_to_palacios(unsigned char * buf, } #endif - return v3_vnet_send_pkt(&pkt, NULL);; + return v3_vnet_send_pkt(&pkt, NULL, 1); } @@ -830,7 +887,7 @@ bridge_send_pkt(struct v3_vm_info * vm, void * private_data) { struct vnet_link * link; - #ifdef DEBUG_VNET_BRIGE + #ifdef CONFIG_PALACIOS_VNET_DEBUG { printk("VNET Lnx Host Bridge: packet received from VNET Core ... len: %d, pkt size: %d, link: %d\n", len, @@ -843,7 +900,7 @@ bridge_send_pkt(struct v3_vm_info * vm, vnet_state.pkt_recv ++; - link = find_link_by_idx(pkt->dst_id); + link = link_by_idx(pkt->dst_id); if (link != NULL) { udp_send(link->sock, &(link->sock_addr), pkt->data, pkt->size); vnet_state.pkt_udp_send ++; @@ -905,7 +962,7 @@ static int vnet_server(void * arg) { continue; } - link = find_link_by_ip(ntohl(pkt_addr.sin_addr.s_addr)); + link = link_by_ip(ntohl(pkt_addr.sin_addr.s_addr)); if (link != NULL){ link_id= link->link_idx; } @@ -921,29 +978,6 @@ static int vnet_server(void * arg) { return 0; } -#if 0 -static int profiling(void *args) { - static unsigned long long last_time=0; - unsigned long long cur_time=0; - set_user_nice(current, MAX_PRIO-1); - - while (!kthread_should_stop()) { - rdtscll(cur_time); - if((cur_time - last_time) > 50000000000) { - last_time = cur_time; - printk("Palacios Linux VNET Bridge - profiling: sent: %ld, rxed: %ld, dropped: %ld, upd send: %ld, udp recv: %ld\n", - vnet_state.pkt_sent, - vnet_state.pkt_recv, - vnet_state.pkt_drop, - vnet_state.pkt_udp_send, - vnet_state.pkt_udp_recv); - } - schedule(); - } - - return 0; -} -#endif int palacios_init_vnet(void) { struct v3_vnet_bridge_ops bridge_ops;