5 #include <asm/uaccess.h>
6 #include <linux/inet.h>
7 #include <linux/kthread.h>
8 #include <linux/netdevice.h>
11 #include <linux/string.h>
12 #include <linux/preempt.h>
13 #include <linux/sched.h>
14 #include <linux/if_packet.h>
15 #include <linux/errno.h>
18 #include <palacios/vmm_packet.h>
19 #include <palacios/vmm_host_events.h>
20 #include <palacios/vmm_vnet.h>
23 #include "palacios-packet.h"
25 //#define DEBUG_PALACIOS_PACKET
27 static struct socket * raw_sock;
29 static int packet_inited = 0;
31 static int init_raw_socket (const char * eth_dev){
33 struct sockaddr_ll sock_addr;
37 err = sock_create(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL), &raw_sock);
39 printk(KERN_WARNING "Could not create a PF_PACKET Socket, err %d\n", err);
47 memset(&if_req, 0, sizeof(if_req));
48 strncpy(if_req.ifr_name, eth_dev, sizeof(if_req.ifr_name));
50 err = raw_sock->ops->ioctl(raw_sock, SIOCGIFINDEX, (long)&if_req);
52 printk(KERN_WARNING "Palacios Packet: Unable to get index for device %s, error %d\n", if_req.ifr_name, err);
53 dev_idx = 2; /* default "eth0" */
56 dev_idx = if_req.ifr_ifindex;
59 printk(KERN_INFO "Palacios Packet: bind to device index: %d\n", dev_idx);
61 memset(&sock_addr, 0, sizeof(sock_addr));
62 sock_addr.sll_family = PF_PACKET;
63 sock_addr.sll_protocol = htons(ETH_P_ALL);
64 sock_addr.sll_ifindex = dev_idx;
66 err = raw_sock->ops->bind(raw_sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
68 printk(KERN_WARNING "Error binding raw packet to device %s, %d\n", eth_dev, err);
72 printk(KERN_INFO "Bind palacios raw packet interface to device %s\n", eth_dev);
79 palacios_packet_send(const char * pkt, unsigned int len, void * private_data) {
85 #ifdef DEBUG_PALACIOS_PACKET
87 printk("Palacios Packet: send pkt to NIC (size: %d)\n",
89 //print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt, len, 0);
94 iov.iov_base = (void *)pkt;
95 iov.iov_len = (__kernel_size_t)len;
99 msg.msg_control = NULL;
100 msg.msg_controllen = 0;
107 size = sock_sendmsg(raw_sock, &msg, len);
114 static struct v3_packet_hooks palacios_packet_hooks = {
115 .send = palacios_packet_send,
120 recv_pkt(char * pkt, int len) {
126 if (raw_sock == NULL) {
136 msg.msg_control = NULL;
137 msg.msg_controllen = 0;
140 msg.msg_control = NULL;
144 size = sock_recvmsg(raw_sock, &msg, len, msg.msg_flags);
152 send_raw_packet_to_palacios(char * pkt,
154 struct v3_vm_info * vm) {
155 struct v3_packet_event event;
157 event.pkt = kmalloc(len, GFP_KERNEL);
158 memcpy(event.pkt, pkt, len);
161 v3_deliver_packet_event(vm, &event);
164 static int packet_server(void * arg) {
165 char pkt[ETHERNET_PACKET_LEN];
168 printk("Palacios Raw Packet Bridge: Staring receiving server\n");
170 while (!kthread_should_stop()) {
171 size = recv_pkt(pkt, ETHERNET_PACKET_LEN);
173 printk(KERN_WARNING "Palacios Packet Socket receive error\n");
177 #ifdef DEBUG_PALACIOS_PACKET
179 printk("Palacios Packet: receive pkt from NIC (size: %d)\n",
181 //print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt, size, 0);
185 send_raw_packet_to_palacios(pkt, size, NULL);
192 int palacios_init_packet(const char * eth_dev) {
194 if(packet_inited == 0){
196 init_raw_socket(eth_dev);
197 V3_Init_Packet(&palacios_packet_hooks);
199 kthread_run(packet_server, NULL, "raw-packet-server");