int
vr_usocket_message_write(struct vr_usocket *usockp,
        struct vr_message *message)
{
    int ret;
    unsigned int len;
    unsigned char *buf;

    RTE_LOG(DEBUG, USOCK, "%s[%lx]: FD %d\n", __func__, pthread_self(),
                usockp->usock_fd);
    if ((usockp->usock_proto != NETLINK) && (usockp->usock_type != TCP))
        return -EINVAL;

    if (usockp->usock_tx_buf || !vr_queue_empty(&usockp->usock_nl_responses)) {
        vr_queue_enqueue(&usockp->usock_nl_responses,
                &message->vr_message_queue);
        return 0;
    }

    buf = (unsigned char *)dpdk_nl_message_hdr(message);
    len = dpdk_nl_message_len(message);
    ret = vr_usocket_write(usockp, buf, len);
    if (ret == len) {
        vr_message_free(message);
    }

    return ret;
}
Ejemplo n.º 2
0
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;
}
static void
usock_netlink_write_responses(struct vr_usocket *usockp)
{
    int ret;
    struct vr_message *resp;

    RTE_LOG(DEBUG, USOCK, "%s[%lx]: FD %d\n", __func__, pthread_self(), usockp->usock_fd);
    while ((resp =
                (struct vr_message *)vr_queue_dequeue(&usockp->usock_nl_responses))) {
        usockp->usock_tx_buf = (unsigned char *)dpdk_nl_message_hdr(resp);
        usockp->usock_write_len = dpdk_nl_message_len(resp);
        usockp->usock_write_offset = 0;
        ret = __usock_write(usockp);
        if ((ret < 0) || (ret == usockp->usock_write_len)) {
            vr_message_free(resp);
        } else {
            break;
        }
    }

    return;
}