/* Init NetLink and UVHost sockets */ int vr_dpdk_netlink_init(void) { void *event_sock = NULL; int ret; RTE_LOG(INFO, VROUTER, "Starting NetLink...\n"); ret = vr_message_transport_register(&dpdk_nl_transport); if (ret) return ret; #ifdef AGENT_VROUTER_TCP vr_dpdk.netlink_sock = vr_usocket(NETLINK, TCP); #else vr_dpdk.netlink_sock = vr_usocket(NETLINK, UNIX); #endif if (!vr_dpdk.netlink_sock) { RTE_LOG(ERR, VROUTER, " error creating NetLink server socket:" " %s (%d)\n", rte_strerror(errno), errno); goto error; } RTE_LOG(INFO, VROUTER, " NetLink TCP socket FD is %d\n", ((struct vr_usocket *)vr_dpdk.netlink_sock)->usock_fd); ret = vr_nl_uvhost_connect(); if (ret != 0) { RTE_LOG(ERR, VROUTER, " error creating uvhost connection\n"); goto error; } /* create and bind event usock to wake up the NetLink lcore */ event_sock = (void *)vr_usocket(EVENT, RAW); if (!event_sock) { RTE_LOG(ERR, VROUTER, " error creating NetLink event\n"); goto error; } if (vr_usocket_bind_usockets(vr_dpdk.netlink_sock, event_sock)) { RTE_LOG(ERR, VROUTER, " error binding NetLink event\n"); goto error; } vr_dpdk.netlink_event_sock = event_sock; return 0; error: vr_message_transport_unregister(&dpdk_nl_transport); vr_usocket_close(vr_dpdk.netlink_sock); return -1; }
int dpdk_packet_socket_init(void) { unsigned lcore_id; struct vr_dpdk_lcore *lcorep; void *event_sock = NULL; int err; vr_dpdk.packet_transport = (void *)vr_usocket(PACKET, RAW); if (!vr_dpdk.packet_transport) return -1; if (!vr_dpdk.packet_ring) { vr_dpdk.packet_ring = rte_ring_lookup("pkt0_tx"); if (!vr_dpdk.packet_ring) { /* multi-producers single-consumer ring */ vr_dpdk.packet_ring = rte_ring_create("pkt0_tx", VR_DPDK_TX_RING_SZ, SOCKET_ID_ANY, RING_F_SC_DEQ); if (!vr_dpdk.packet_ring) { RTE_LOG(ERR, VROUTER, " error creating pkt0 ring\n"); goto error; } } } /* socket events to wake up the pkt0 lcore */ RTE_LCORE_FOREACH(lcore_id) { lcorep = vr_dpdk.lcores[lcore_id]; event_sock = (void *)vr_usocket(EVENT, RAW); if (!event_sock) { goto error; } if (vr_usocket_bind_usockets(vr_dpdk.packet_transport, event_sock)) goto error; lcorep->lcore_event_sock = event_sock; } return 0; error: err = errno; if (event_sock) vr_usocket_close(event_sock); vr_usocket_close(vr_dpdk.packet_transport); vr_dpdk.packet_transport = NULL; errno = err; return -ENOMEM; }
int dpdk_packet_socket_init(void) { void *event_sock = NULL; int err; vr_dpdk.packet_transport = (void *)vr_usocket(PACKET, RAW); if (!vr_dpdk.packet_transport) return -1; if (!vr_dpdk.packet_ring) { vr_dpdk.packet_ring = rte_ring_lookup("packet_tx"); if (!vr_dpdk.packet_ring) { /* multi-producers single-consumer ring */ vr_dpdk.packet_ring = rte_ring_create("packet_tx", VR_DPDK_TX_RING_SZ, SOCKET_ID_ANY, RING_F_SC_DEQ); if (!vr_dpdk.packet_ring) { RTE_LOG(ERR, VROUTER, " error creating packet ring\n"); goto error; } } } /* create and bind event usock to wake up the packet lcore */ event_sock = (void *)vr_usocket(EVENT, RAW); if (!event_sock) { RTE_LOG(ERR, VROUTER, " error creating packet event\n"); goto error; } if (vr_usocket_bind_usockets(vr_dpdk.packet_transport, event_sock)) { RTE_LOG(ERR, VROUTER, " error binding packet event\n"); goto error; } vr_dpdk.packet_event_sock = event_sock; return 0; error: err = errno; if (event_sock) vr_usocket_close(event_sock); vr_usocket_close(vr_dpdk.packet_transport); vr_dpdk.packet_transport = NULL; errno = err; return -ENOMEM; }
/* * bind a child socket to the parent. binding in this context means adding * a child usocket to parent poll list. an example where this will be required * is when one has created an event usocket. An event usocket by itself cannot * do anything useful in the context of dpdk vrouter application. Hence it needs * to be bound to the parent socket that does something useful, in this case * the packet socket. Another example is that of netlink socket. when thexi * netlink socket accepts new connection and the new connected socket has to be * polled, in which case we will need to bind it to the parent socket poll list */ static int usock_bind_usockets(struct vr_usocket *parent, struct vr_usocket *child) { unsigned int i; int ret; struct vr_usocket *child_pair; if (parent->usock_state == LIMITED) return -ENOSPC; RTE_LOG(DEBUG, USOCK, "%s[%lx]: parent FD %d child FD %d\n", __func__, pthread_self(), parent->usock_fd, child->usock_fd); if (child->usock_proto == EVENT) { child_pair = vr_usocket(EVENT, RAW); if (!child_pair) return -ENOMEM; RTE_LOG(DEBUG, USOCK, "%s[%lx]: parent FD %d closing child FD %d\n", __func__, pthread_self(), parent->usock_fd, child->usock_fd); close(child->usock_fd); child->usock_fd = child_pair->usock_fd; child = child_pair; } ret = usock_init_poll(parent); if (ret) return ret; if (!parent->usock_children) { parent->usock_children = vr_zalloc(sizeof(struct vr_usocket *) * USOCK_MAX_CHILD_FDS + 1, VR_USOCK_OBJECT); if (!parent->usock_children) { usock_set_error(parent, -ENOMEM); return -ENOMEM; } } child->usock_parent = parent; parent->usock_cfds++; if (parent->usock_cfds == USOCK_MAX_CHILD_FDS) parent->usock_state = LIMITED; for (i = 1; i <= parent->usock_max_cfds; i++) { if (!parent->usock_children[i]) { parent->usock_children[i] = child; parent->usock_pfds[i].fd = child->usock_fd; parent->usock_pfds[i].events = POLLIN; child->usock_child_index = i; break; } } if (child->usock_proto == EVENT) child->usock_state = READING_DATA; usock_read_init(child); return 0; }