Beispiel #1
0
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;
}
Beispiel #8
0
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;
}
Beispiel #10
0
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;
}