Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
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;
}
/*
 * 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;
}