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; }
void vr_dpdk_packet_wakeup(struct vr_interface *vif) { struct vr_interface_stats *stats; struct vrouter *router; if (unlikely(vif == NULL)) { /* get global agent vif */ router = vrouter_get(0); vif = router->vr_agent_if; } if (likely(vr_dpdk.packet_event_sock != NULL)) { if (likely(vif != NULL)) { stats = vif_get_stats(vif, rte_lcore_id()); stats->vis_port_osyscalls++; } else { /* no agent interface - no counter */ } if (vr_usocket_eventfd_write(vr_dpdk.packet_event_sock) < 0) { vr_usocket_close(vr_dpdk.packet_event_sock); vr_dpdk.packet_event_sock = NULL; } } }
void vr_dpdk_netlink_wakeup(void) { if (likely(vr_dpdk.netlink_event_sock != NULL)) { if (vr_usocket_eventfd_write(vr_dpdk.netlink_event_sock) < 0) { vr_usocket_close(vr_dpdk.netlink_event_sock); vr_dpdk.netlink_event_sock = NULL; } } }
void dpdk_netlink_exit(void) { vr_message_transport_unregister(&dpdk_nl_transport); vr_usocket_close(vr_dpdk.netlink_sock); vr_dpdk.netlink_sock = NULL; vr_dpdk.netlink_event_sock = NULL; return; }
static void dpdk_nl_process_response(void *usockp, struct nlmsghdr *nlh) { __u32 seq; unsigned int multi_flag = 0; bool write = true; struct vr_message *resp; struct nlmsghdr *resp_nlh; struct genlmsghdr *genlh, *resp_genlh; struct nlattr *resp_nla; seq = nlh->nlmsg_seq; genlh = (struct genlmsghdr *)((unsigned char *)nlh + NLMSG_HDRLEN); /* Process responses */ while ((resp = (struct vr_message *)vr_message_dequeue_response())) { if (!write) { vr_message_free(resp); continue; } if (!vr_response_queue_empty()) { multi_flag = NLM_F_MULTI; } else { multi_flag = 0; } /* Update Netlink headers */ resp_nlh = dpdk_nl_message_hdr(resp); resp_nlh->nlmsg_len = dpdk_nl_message_len(resp); resp_nlh->nlmsg_type = nlh->nlmsg_type; resp_nlh->nlmsg_flags = multi_flag; resp_nlh->nlmsg_seq = seq; resp_nlh->nlmsg_pid = 0; resp_genlh = (struct genlmsghdr *)((unsigned char *)resp_nlh + NLMSG_HDRLEN); memcpy(resp_genlh, genlh, sizeof(*genlh)); resp_nla = (struct nlattr *)((unsigned char *)resp_genlh + GENL_HDRLEN); resp_nla->nla_len = resp->vr_message_len; resp_nla->nla_type = NL_ATTR_VR_MESSAGE_PROTOCOL; if (vr_usocket_message_write(usockp, resp) < 0) { write = false; vr_usocket_close(usockp); } } return; }
/* 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; }
void vr_dpdk_packet_wakeup(void) { /* to wake up pkt0 thread we always use current lcore event sock */ struct vr_dpdk_lcore *lcorep = vr_dpdk.lcores[rte_lcore_id()]; if (likely(lcorep->lcore_event_sock != NULL)) { if (vr_usocket_eventfd_write(lcorep->lcore_event_sock) < 0) { vr_usocket_close(lcorep->lcore_event_sock); lcorep->lcore_event_sock = NULL; } } }
void dpdk_packet_socket_close(void) { if (!vr_dpdk.packet_transport) return; /* close and free up the memory both for packet usock and binded event usock */ vr_usocket_close(vr_dpdk.packet_transport); vr_dpdk_packet_wakeup(NULL); vr_dpdk.packet_transport = NULL; vr_dpdk.packet_event_sock = NULL; return; }
void dpdk_packet_socket_close(void) { void *usockp; if (!vr_dpdk.packet_transport) return; usockp = vr_dpdk.packet_transport; vr_dpdk.packet_transport = NULL; vr_usocket_close(usockp); return; }