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); }
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; }
void nl_update_header(struct nl_client *cl, int data_len) { /* First update attribute header len for NLA_SANDESH_ATTR */ struct nlattr *nla = (struct nlattr *) ((char *)cl->cl_buf + cl->cl_buf_offset - NLA_HDRLEN); assert(nla->nla_type == NL_ATTR_VR_MESSAGE_PROTOCOL); nla->nla_len += data_len; cl->cl_buf_offset += data_len; nl_update_nlh(cl); }
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; }
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; }
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; }
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; }
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; }