예제 #1
0
int
vr_sendmsg(struct nl_client *cl, void *request,
        char *request_string)
{
    int ret, error, attr_len;

    /* 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();
    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);

    return nl_sendmsg(cl);
}
예제 #2
0
int
nl_build_header(struct nl_client *cl, unsigned char **buf, uint32_t *buf_len)
{
    int ret;

    if (!cl->cl_buf)
        return -EINVAL;

    if (!cl->cl_genl_family_id)
        return -EINVAL;

    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;

    ret = nl_build_sandesh_attr_without_attr_len(cl);
    if (ret)
        return ret;

    *buf = (unsigned char *)(cl->cl_buf) + cl->cl_buf_offset;
    *buf_len = cl->cl_buf_len - cl->cl_buf_offset;

    return 0;
}
예제 #3
0
static int
vr_build_netlink_request(vr_drop_stats_req *req)
{
    int ret, error = 0, attr_len;

    /* 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();
    ret = sandesh_encode(req, "vr_drop_stats_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 -1;

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

    return 0;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
0
int
nl_build_if_create_msg(struct nl_client *cl, struct vn_if *ifp, uint8_t ack)
{
    int ret;
    uint32_t flags;

    if (!cl->cl_buf || cl->cl_buf_offset || !ifp)
        return -EINVAL;

    flags = NLM_F_REQUEST | NLM_F_CREATE;
    if (ack) {
        flags |= NLM_F_ACK;
    }
    ret = nl_build_nlh(cl, RTM_NEWLINK, flags);
    if (ret)
        return ret;

    ret = nl_build_ifinfo(cl, ifp);
    if (ret)
        return ret;

    ret = nl_build_mac_address(cl, ifp);
    if (ret)
        return ret;

    ret = nl_build_attr_ifname(cl, ifp);
    if (ret)
        return ret;

    ret = nl_build_attr_linkinfo(cl, ifp);
    if (ret)
        return ret;

    cl->cl_msg_len = cl->cl_buf_offset;
    nl_update_nlh(cl);

    return 0;
}
예제 #7
0
int
nl_build_get_family_id(struct nl_client *cl, char *family)
{
    int ret;

    if (!cl->cl_buf)
        return -ENOMEM;

    ret = nl_build_nlh(cl, GENL_ID_CTRL, NLM_F_REQUEST);
    if (ret)
        return ret;

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

    ret = nl_build_family_name_attr(cl, family);
    if (ret)
        return ret;

    nl_update_nlh(cl);

    return 0;
}
예제 #8
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;

}