示例#1
0
/*
 * create vhost interface in linux
 */
static int
vhost_create(void)
{
    int ret;
    struct vn_if vhost;
    struct nl_response *resp;

    bzero(&vhost, sizeof(vhost));
    strncpy(vhost.if_name, if_name, sizeof(vhost.if_name));
    strncpy(vhost.if_kind, VHOST_KIND, sizeof(vhost.if_kind));
    memcpy(vhost.if_mac, vr_ifmac, sizeof(vhost.if_mac));

    ret = nl_build_if_create_msg(cl, &vhost, 0);
    if (ret)
        return ret;

    ret = nl_sendmsg(cl);
    if (ret <= 0)
        return ret;

    while ((ret = nl_recvmsg(cl)) > 0) {
        resp = nl_parse_reply(cl);
        if (resp && resp->nl_op)
            printf("%s\n", strerror(resp->nl_op));
    }

    return ret;
}
示例#2
0
/* send and receive */
int
vr_recvmsg(struct nl_client *cl, bool dump)
{
    int ret = 0;
    bool pending = true;
    struct nl_response *resp;
    struct nlmsghdr *nlh;

    while (pending) {
        if ((ret = nl_recvmsg(cl)) > 0) {
            if (dump) {
                pending = true;
            } else {
                pending = false;
            }

            resp = nl_parse_reply(cl);
            if (resp->nl_op == SANDESH_REQUEST) {
                sandesh_decode(resp->nl_data, resp->nl_len,
                        vr_find_sandesh_info, &ret);
            } else if (resp->nl_type == NL_MSG_TYPE_DONE) {
                pending = false;
            }
        } else {
            return ret;
        }

        nlh = (struct nlmsghdr *)cl->cl_buf;
        if (!nlh || !nlh->nlmsg_flags)
            break;
    }

    return ret;
}
示例#3
0
int
vrouter_get_family_id(struct nl_client *cl)
{
    int ret;
    struct nl_response *resp;
    struct genl_ctrl_message *msg;

#if defined(__linux__)
    if ((ret = nl_build_get_family_id(cl, VROUTER_GENETLINK_FAMILY_NAME)))
        return ret;

    if (nl_sendmsg(cl) <= 0)
        return -errno;

    if (nl_recvmsg(cl) <= 0)
        return -errno;

    resp = nl_parse_reply(cl);
    if (!resp || resp->nl_type != NL_MSG_TYPE_GEN_CTRL ||
            resp->nl_op != CTRL_CMD_NEWFAMILY)
        return -EINVAL;

    msg = (struct genl_ctrl_message *)resp->nl_data;
    nl_set_genl_family_id(cl, msg->family_id);
#elif defined(__FreeBSD__)
    /* BSD doesn't check the value of family id, so set it to one */
    nl_set_genl_family_id(cl, 1);
#endif

    return cl->cl_genl_family_id;
}
示例#4
0
static int
vr_send_one_message(void)
{
    int ret;
    struct nl_response *resp;

    ret = nl_sendmsg(cl);
    if (ret <= 0)
        return 0;

    while ((ret = nl_recvmsg(cl)) > 0) {
        resp = nl_parse_reply(cl);
        if (resp->nl_op == SANDESH_REQUEST)
            sandesh_decode(resp->nl_data, resp->nl_len, vr_find_sandesh_info, &ret);
    }

    return resp_code;
}
示例#5
0
static int
vr_intf_send_msg(void *request, char *request_string)
{
    int ret, error, attr_len; 
    struct nl_response *resp;

    /* nlmsg header */
    ret = nl_build_nlh(cl, cl->cl_genl_family_id, NLM_F_REQUEST);
    if (ret) {
        return ret;
    }

    /* Generic nlmsg header */
    ret = nl_build_genlh(cl, SANDESH_REQUEST, 0);
    if (ret) {
        return ret;
    }

    attr_len = nl_get_attr_hdr_size();

    error = 0;
    ret = sandesh_encode(request, request_string, vr_find_sandesh_info,
                             (nl_get_buf_ptr(cl) + attr_len),
                             (nl_get_buf_len(cl) - attr_len), &error);
    if (ret <= 0) {
        return ret;
    }

    /* Add sandesh attribute */
    nl_build_attr(cl, ret, NL_ATTR_VR_MESSAGE_PROTOCOL);
    nl_update_nlh(cl);

    /* Send the request to kernel */
    ret = nl_sendmsg(cl);

    while ((ret = nl_recvmsg(cl)) > 0) {
        resp = nl_parse_reply(cl);
        if (resp->nl_op == SANDESH_REQUEST) {
            sandesh_decode(resp->nl_data, resp->nl_len, vr_find_sandesh_info, &ret);
        }
    }

    return 0;
}
示例#6
0
static int
make_flow_req(vr_flow_req *req)
{
    int ret, attr_len, error;
    struct nl_response *resp;

    ret = nl_build_nlh(cl, cl->cl_genl_family_id, NLM_F_REQUEST);
    if (ret)
        return ret;

    ret = nl_build_genlh(cl, SANDESH_REQUEST, 0);
    if (ret)
        return ret;

    attr_len = nl_get_attr_hdr_size();

    error = 0;
    ret = sandesh_encode(req, "vr_flow_req", vr_find_sandesh_info,
                             (nl_get_buf_ptr(cl) + attr_len),
                             (nl_get_buf_len(cl) - attr_len), &error);

    if ((ret <= 0) || error) {
        return ret;
    }

    nl_build_attr(cl, ret, NL_ATTR_VR_MESSAGE_PROTOCOL);
    nl_update_nlh(cl);
    ret = nl_sendmsg(cl);
    if (ret <= 0)
        return ret;

    while ((ret = nl_recvmsg(cl)) > 0) {
        resp = nl_parse_reply(cl);
        if (resp->nl_op == SANDESH_REQUEST) {
            sandesh_decode(resp->nl_data, resp->nl_len, vr_find_sandesh_info, &ret);
        }
    }

    if (errno == EAGAIN || errno == EWOULDBLOCK)
        ret = 0;

    return ret;
}
示例#7
0
int 
vr_nh_op(int opt, int mode, uint32_t nh_id, uint32_t if_id, uint32_t vrf_id, 
        int8_t *dst, int8_t  *src, struct in_addr sip, struct in_addr dip, uint32_t flags)
{
    vr_nexthop_req nh_req;
    char *buf;
    int ret, error, attr_len;
    struct nl_response *resp;
    int i;

op_retry:

    bzero(&nh_req, sizeof(nh_req));

    if (opt == 1) {
        nh_req.h_op = SANDESH_OP_ADD;
        nh_req.nhr_flags = flags;
        nh_req.nhr_encap_oif_id = if_id;
        nh_req.nhr_encap_size = 0;
#if defined(__linux__)
        nh_req.nhr_encap_family = ETH_P_ARP;
#elif defined(__FreeBSD__)
    nh_req.nhr_encap_family = ETHERTYPE_ARP;
#endif
        nh_req.nhr_vrf = vrf_id;
        nh_req.nhr_tun_sip = sip.s_addr;
        nh_req.nhr_tun_dip = dip.s_addr;
        nh_req.nhr_tun_sport = htons(sport);
        nh_req.nhr_tun_dport = htons(dport);
        nh_req.nhr_nh_list_size = 0;
        if ((mode == NH_TUNNEL) || 
                ((mode == NH_ENCAP) && !(flags & NH_FLAG_ENCAP_L2))) {
            nh_req.nhr_encap_size = 14;
            buf = calloc(1, nh_req.nhr_encap_size);
            memcpy(buf, dst, 6);
            memcpy(buf+6, src, 6);
            buf[12] = 0x08;
            nh_req.nhr_encap = (int8_t *)buf;
        }

        if (mode == NH_COMPOSITE) {
            nh_req.nhr_nh_list_size = comp_nh_ind;
            nh_req.nhr_label_list_size = comp_nh_ind;
            nh_req.nhr_nh_list = calloc(comp_nh_ind, sizeof(uint32_t));
            nh_req.nhr_label_list = calloc(comp_nh_ind, sizeof(uint32_t));
            for (i = 0; i < comp_nh_ind; i++) {
                nh_req.nhr_nh_list[i] = comp_nh[i];
                if (i < lbl_ind)
                    nh_req.nhr_label_list[i] = lbl[i];
                else
                    nh_req.nhr_label_list[i] = 0;
            }
        }

    } else if (opt == 2) {
        nh_req.h_op = SANDESH_OP_DELETE;
    } else if (opt == 3) {
        nh_req.h_op = SANDESH_OP_DUMP;
        nh_req.nhr_marker = dump_marker;
    } else if (opt == 4) {
        nh_req.h_op = SANDESH_OP_GET;
    }

    nh_req.nhr_id = nh_id;
    nh_req.nhr_rid = 0;

    if ((mode == NH_ENCAP) && (flags & NH_FLAG_ENCAP_L2)) 
        nh_req.nhr_family = AF_BRIDGE;
    else if ((mode == NH_COMPOSITE) && (flags &
                NH_FLAG_COMPOSITE_MULTI_PROTO))
        nh_req.nhr_family = AF_UNSPEC;
    else
        nh_req.nhr_family = AF_INET;

    nh_req.nhr_type = mode;
    /* nlmsg header */
    ret = nl_build_nlh(cl, cl->cl_genl_family_id, NLM_F_REQUEST);
    if (ret) {
        return ret;
    }

    /* Generic nlmsg header */
    ret = nl_build_genlh(cl, SANDESH_REQUEST, 0);
    if (ret) {
        return ret;
    }

    attr_len = nl_get_attr_hdr_size();
     
    error = 0;
    ret = sandesh_encode(&nh_req, "vr_nexthop_req", vr_find_sandesh_info, 
                             (nl_get_buf_ptr(cl) + attr_len),
                             (nl_get_buf_len(cl) - attr_len), &error);

    if ((ret <= 0) || error) {
        return ret;
    }

    /* Add sandesh attribute */
    nl_build_attr(cl, ret, NL_ATTR_VR_MESSAGE_PROTOCOL);
    nl_update_nlh(cl);

    /* Send the request to kernel */
    ret = nl_sendmsg(cl);
    while ((ret = nl_recvmsg(cl)) > 0) {
        resp = nl_parse_reply(cl);
        if (resp->nl_op == SANDESH_REQUEST) {
            sandesh_decode(resp->nl_data, resp->nl_len, vr_find_sandesh_info, &ret);
        }
    }

    if (dump_pending)
        goto op_retry;

    return 0;

}