/* * An rarp packet is constructed and broadcasted to notify switches about * the new location of the migrated VM, so that packets from outside will * not be lost after migration. * * However, we don't actually "send" a rarp packet here, instead, we set * a flag 'broadcast_rarp' to let rte_vhost_dequeue_burst() inject it. */ int user_send_rarp(int vid, struct VhostUserMsg *msg) { struct virtio_net *dev; uint8_t *mac = (uint8_t *)&msg->payload.u64; dev = get_device(vid); if (!dev) return -1; RTE_LOG(DEBUG, VHOST_CONFIG, ":: mac: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); memcpy(dev->mac.addr_bytes, mac, 6); /* * Set the flag to inject a RARP broadcast packet at * rte_vhost_dequeue_burst(). * * rte_smp_wmb() is for making sure the mac is copied * before the flag is set. */ rte_smp_wmb(); rte_atomic16_set(&dev->broadcast_rarp, 1); return 0; }
inline int ipaugenblick_sendto_bulk(int sock,struct data_and_descriptor *bufs_and_desc,int *offsets,int *lengths,unsigned int *ipaddrs,unsigned short *ports,int buffer_count) { int rc,idx,total_length = 0; struct rte_mbuf *mbufs[buffer_count]; for(idx = 0;idx < buffer_count;idx++) { char *p_addr; struct sockaddr_in *p_addr_in; /* TODO: set offsets */ mbufs[idx] = (struct rte_mbuf *)bufs_and_desc[idx].pdesc; rte_pktmbuf_data_len(mbufs[idx]) = lengths[idx]; total_length += lengths[idx]; p_addr = rte_pktmbuf_mtod(mbufs[idx],char *); rte_pktmbuf_data_len(mbufs[idx]) = lengths[idx]; p_addr -= sizeof(struct sockaddr_in); p_addr_in = (struct sockaddr_in *)p_addr; p_addr_in->sin_family = AF_INET; p_addr_in->sin_port = htons(ports[idx]); p_addr_in->sin_addr.s_addr = ipaddrs[idx]; } ipaugenblick_stats_send_called++; ipaugenblick_stats_buffers_sent += buffer_count; rte_atomic16_set(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->write_ready_to_app),0); rc = ipaugenblick_enqueue_tx_bufs_bulk(sock,mbufs,buffer_count); if(rc == 0) rte_atomic32_sub(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->tx_space),total_length); ipaugenblick_stats_send_failure += (rc != 0); return rc; }
int ipaugenblick_get_socket_tx_space_own_buffer(int sock) { int ring_space = ipaugenblick_socket_tx_space(sock); int tx_space = rte_atomic32_read(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->tx_space))/1448; int rc = (ring_space > tx_space) ? tx_space : ring_space; // printf("sock %d ring space %d free bufs %d tx space %d\n",sock,ring_space,free_bufs_count,tx_space); if(!rc) { rte_atomic16_set(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->write_ready_to_app),0); ipaugenblick_notify_empty_tx_buffers(sock); } return rc; }
/* TCP or connected UDP */ inline int ipaugenblick_send(int sock,void *pdesc,int offset,int length) { int rc; struct rte_mbuf *mbuf = (struct rte_mbuf *)pdesc; ipaugenblick_stats_send_called++; rte_pktmbuf_data_len(mbuf) = length; mbuf->next = NULL; rte_atomic16_set(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->write_ready_to_app),0); rc = ipaugenblick_enqueue_tx_buf(sock,mbuf); if(rc == 0) rte_atomic32_sub(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->tx_space),length); ipaugenblick_stats_send_failure += (rc != 0); return rc; }
/* UDP or RAW */ inline int ipaugenblick_sendto(int sock,void *pdesc,int offset,int length,unsigned int ipaddr,unsigned short port) { int rc; struct rte_mbuf *mbuf = (struct rte_mbuf *)pdesc; char *p_addr = rte_pktmbuf_mtod(mbuf,char *); struct sockaddr_in *p_addr_in; ipaugenblick_stats_send_called++; rte_pktmbuf_data_len(mbuf) = length; p_addr -= sizeof(struct sockaddr_in); p_addr_in = (struct sockaddr_in *)p_addr; p_addr_in->sin_family = AF_INET; p_addr_in->sin_port = htons(port); p_addr_in->sin_addr.s_addr = ipaddr; rte_atomic16_set(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->write_ready_to_app),0); rc = ipaugenblick_enqueue_tx_buf(sock,mbuf); if(rc == 0) rte_atomic32_sub(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->tx_space),length); ipaugenblick_stats_send_failure += (rc != 0); return rc; }
inline int ipaugenblick_send_bulk(int sock,struct data_and_descriptor *bufs_and_desc,int *offsets,int *lengths,int buffer_count) { int rc,idx,total_length = 0; struct rte_mbuf *mbufs[buffer_count]; for(idx = 0;idx < buffer_count;idx++) { /* TODO: set offsets */ mbufs[idx] = (struct rte_mbuf *)bufs_and_desc[idx].pdesc; rte_pktmbuf_data_len(mbufs[idx]) = lengths[idx]; total_length += lengths[idx]; } ipaugenblick_stats_send_called++; ipaugenblick_stats_buffers_sent += buffer_count; rte_atomic16_set(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->write_ready_to_app),0); rc = ipaugenblick_enqueue_tx_bufs_bulk(sock,mbufs,buffer_count); if(rc == 0) rte_atomic32_sub(&(local_socket_descriptors[sock & SOCKET_READY_MASK].socket->tx_space),total_length); ipaugenblick_stats_send_failure += (rc != 0); return rc; }
/* * Set the number of schedulers in the system */ int lthread_num_schedulers_set(int num) { rte_atomic16_set(&num_schedulers, num); return (int)rte_atomic16_read(&num_schedulers); }