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.


ae1238f3bf95fbeeb471c37de707f04b1a71891c
[palacios.git] / palacios / src / devices / vnet_nic.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) 2008, Lei Xia <lxia@northwestern.edu>
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Lei Xia <lxia@northwestern.edu>
15  *               
16  *
17  * This is free software.  You are permitted to use,
18  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
19  */
20 //backend device for Virtio NIC
21
22 #include <palacios/vmm_vnet.h>
23 #include <palacios/vmm.h>
24 #include <palacios/vmm_dev_mgr.h>
25 #include <devices/lnx_virtio_pci.h>
26 #include <palacios/vm_guest_mem.h>
27 #include <devices/pci.h>
28
29 struct vnet_nic_state {
30         char mac[6];
31
32
33 };
34
35 //used when virtio_nic get a packet from guest and send it to the backend
36 // send packet to all of the virtio nic devices other than the sender
37 static int send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
38     PrintDebug("Virito NIC: In vnet_send: guest net state %p\n", private_data);
39
40     v3_vnet_send_rawpkt(buf, len, private_data);
41     return 0;
42 }
43
44 static int receive(uint8_t * buf, uint32_t count, void * private_data, struct vm_device *src_dev){
45
46     return 0;
47 }
48
49
50 static struct v3_dev_net_ops net_ops = {
51     .send = send, 
52     .receive = receive,
53 };
54
55
56 #if 0
57 static int input(struct v3_vm_info *info, uchar_t * buf, uint_t len, void * private_data){
58     PrintDebug("Virito NIC: In virtio_input: guest net state %p\n", private_data);
59
60     return __virtio_dev_send(buf, len, private_data);
61 }
62
63
64 //register a virtio device to the vnet as backend
65 void register_to_vnet(struct vm_device  *dev, 
66                                                 char *dev_name,
67                                                 uchar_t mac[6]){
68     struct virtio_net_state * net_state;
69     struct virtio_dev_state *virtio_state =  (struct virtio_dev_state *)dev->private_data;
70     uchar_t tapmac[6] = {0x00,0x02,0x55,0x67,0x42,0x39}; //for Intel-VT test HW
71     //uchar_t tapmac[6] = {0x6e,0xa8,0x75,0xf4,0x82,0x95};
72     uchar_t dstmac[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
73     uchar_t zeromac[6] = {0,0,0,0,0,0};
74
75
76     net_state  = (struct virtio_net_state *)V3_Malloc(sizeof(struct virtio_net_state));
77     memset(net_state, 0, sizeof(struct virtio_net_state));
78     net_state->net_ops = (struct v3_dev_net_ops *)V3_Malloc(sizeof(struct v3_dev_net_ops));
79     net_state->net_ops->send = &vnet_send;
80     net_state->net_ops->receive = &vnet_receive;
81     net_state->dev = dev;
82
83     register_dev(virtio_state, net_state);
84
85     PrintDebug("Virtio NIC register Device %s: queue size: %d, %d\n", dev->name,
86                net_state->rx_vq.queue_size, net_state->tx_vq.queue_size);
87     PrintDebug("Virtio NIC: connect virtio device %s, state %p, to vnet\n", dev->name, net_state);
88         
89     int idx = vnet_register_device(dev, dev_name, mac, &virtio_input, net_state);
90     //vnet_add_route_entry(zeromac, dstmac, MAC_ANY, MAC_NONE, idx, LINK_INTERFACE, -1, LINK_INTERFACE);
91     if (!strcmp(dev_name, "net_virtiodom0")){
92         vnet_add_route_entry(zeromac, tapmac, MAC_ANY, MAC_NONE, idx, LINK_INTERFACE, -1, LINK_INTERFACE);
93         vnet_add_route_entry(zeromac, dstmac, MAC_ANY, MAC_NONE, idx, LINK_INTERFACE, -1, LINK_INTERFACE);
94     }
95     if (!strcmp(dev_name, "net_virtio"))
96         vnet_add_route_entry(tapmac, zeromac, MAC_NONE, MAC_ANY, idx, LINK_INTERFACE, -1, LINK_INTERFACE);
97
98
99     v3_vnet_add_node(dev_name, mac, input, priv_data);
100     struct v3_vnet_route route;
101  //add default route
102     memset(&route, 0, sizeof(struct v3_vnet_route));
103     memcpy(&route.dest_mac, mac, 6);
104     route.src_mac_qual = MAC_ANY;
105     route.dest_mac_qual = MAC_NONE;
106     route.link_idx = idx;
107     route.link_type = LINK_EDGE;
108     route.src_link_idx = -1;
109     route.src_type = LINK_ANY;
110     v3_vnet_add_route(&route);
111
112     char mac
113     memset(&route, 0, sizeof(struct v3_vnet_route));
114     memcpy(&route.dest_mac, mac, 6);
115     route.src_mac_qual = MAC_ANY;
116     route.dest_mac_qual = MAC_NONE;
117     route.link_idx = idx;
118     route.link_type = LINK_EDGE;
119     route.src_link_idx = -1;
120     route.src_type = LINK_ANY;
121     v3_vnet_add_route(&route);
122     
123 }
124
125
126 /*
127   *called in svm/vmx handler
128   *iteative handled the unsent packet in incoming packet queues for
129   *all virtio nic devices in this guest
130   */
131 int v3_vnetnic_pktprocess(struct guest_info * info)
132 {
133  
134     return 0;
135 }
136
137 #endif
138
139 static int vnet_nic_free(struct vm_device * dev) {
140     return 0;
141 }
142
143 static struct v3_device_ops dev_ops = {
144     .free = vnet_nic_free,
145     .reset = NULL,
146     .start = NULL,
147     .stop = NULL,
148 };
149
150 static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
151     struct vnet_nic_state * vnetnic = NULL;
152     char * name = v3_cfg_val(cfg, "name");
153
154     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
155
156     vnetnic = (struct vnet_nic_state *)V3_Malloc(sizeof(struct vnet_nic_state));
157     memset(vnetnic, 0, sizeof(struct vnet_nic_state));
158
159
160     PrintDebug("Registering vnet_nic device at\n");
161
162     struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnetnic);
163
164     if (v3_attach_device(vm, dev) == -1) {
165         PrintError("Could not attach device %s\n", name);
166         return -1;
167     }
168
169     if (v3_dev_connect_net(vm, v3_cfg_val(frontend_cfg, "tag"), 
170                            &net_ops, frontend_cfg, vnetnic) == -1) {
171         PrintError("Could not connect %s to frontend %s\n", 
172                    name, v3_cfg_val(frontend_cfg, "tag"));
173         return -1;
174     }
175     
176
177     return 0;
178 }
179
180 device_register("VNET_NIC", vnet_nic_init)