TError TNlHtb::Create(const TNlLink &link, uint32_t defaultClass) { TError error = TError::Success(); int ret; struct rtnl_qdisc *qdisc; qdisc = rtnl_qdisc_alloc(); if (!qdisc) return TError(EError::Unknown, std::string("Unable to allocate qdisc object")); rtnl_tc_set_ifindex(TC_CAST(qdisc), link.GetIndex()); rtnl_tc_set_parent(TC_CAST(qdisc), Parent); rtnl_tc_set_handle(TC_CAST(qdisc), Handle); ret = rtnl_tc_set_kind(TC_CAST(qdisc), "htb"); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to set qdisc type: ") + nl_geterror(ret)); goto free_qdisc; } rtnl_htb_set_defcls(qdisc, TC_H_MIN(defaultClass)); rtnl_htb_set_rate2quantum(qdisc, 10); link.Dump("add", qdisc); ret = rtnl_qdisc_add(link.GetSock(), qdisc, NLM_F_CREATE); if (ret < 0) error = TError(EError::Unknown, std::string("Unable to add qdisc: ") + nl_geterror(ret)); free_qdisc: rtnl_qdisc_put(qdisc); return error; }
static int remus_netbuf_op(libxl__remus_device_nic *remus_nic, libxl__checkpoint_devices_state *cds, int buffer_op) { int rc, ret; libxl__remus_state *rs = cds->concrete_data; STATE_AO_GC(cds->ao); if (buffer_op == tc_buffer_start) ret = rtnl_qdisc_plug_buffer(remus_nic->qdisc); else ret = rtnl_qdisc_plug_release_one(remus_nic->qdisc); if (ret) { rc = ERROR_FAIL; goto out; } ret = rtnl_qdisc_add(rs->nlsock, remus_nic->qdisc, NLM_F_REQUEST); if (ret) { rc = ERROR_FAIL; goto out; } rc = 0; out: if (rc) LOGD(ERROR, cds-> domid, "Remus: cannot do netbuf op %s on %s:%s", ((buffer_op == tc_buffer_start) ? "start_new_epoch" : "release_prev_epoch"), remus_nic->ifb, nl_geterror(ret)); return rc; }
int netem_set_params(const char *iface, struct netem_params *params) { struct rtnl_link *link; struct rtnl_qdisc *qdisc; int err; pthread_mutex_lock(&nl_sock_mutex); /* filter link by name */ if ((link = rtnl_link_get_by_name(link_cache, iface)) == NULL) { fprintf(stderr, "unknown interface/link name.\n"); pthread_mutex_unlock(&nl_sock_mutex); return -1; } if (!(qdisc = rtnl_qdisc_alloc())) { /* OOM error */ fprintf(stderr, "couldn't alloc qdisc\n"); pthread_mutex_unlock(&nl_sock_mutex); return -1; } rtnl_tc_set_link(TC_CAST(qdisc), link); rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT); rtnl_tc_set_kind(TC_CAST(qdisc), "netem"); rtnl_netem_set_delay(qdisc, params->delay * 1000); /* expects microseconds */ rtnl_netem_set_jitter(qdisc, params->jitter * 1000); /* params->loss is given in 10ths of a percent */ rtnl_netem_set_loss(qdisc, (params->loss * (UINT_MAX / 1000))); /* Submit request to kernel and wait for response */ err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE | NLM_F_REPLACE); /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); if (err < 0) { fprintf(stderr, "Unable to add qdisc: %s\n", nl_geterror(err)); pthread_mutex_unlock(&nl_sock_mutex); return err; } if ((err = nl_cache_refill(sock, link_cache)) < 0) { fprintf(stderr, "Unable to resync link cache: %s\n", nl_geterror(err)); pthread_mutex_unlock(&nl_sock_mutex); return -1; } pthread_mutex_unlock(&nl_sock_mutex); return 0; }
/* * function that adds a new ingress qdisc and set the default class for unclassified traffic */ static int qdisc_add_ingress(struct nl_sock *sock, struct rtnl_link *rtnlLink) { struct rtnl_qdisc *qdisc; int err; /* Allocation of a qdisc object */ if (!(qdisc = rtnl_qdisc_alloc())) { printf("Can not allocate Qdisc\n"); return -1; } //rtnl_tc_set_ifindex(TC_CAST(qdisc), master_index); rtnl_tc_set_link(TC_CAST(qdisc), rtnlLink); rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT); //printf("Delete current qdisc\n"); rtnl_qdisc_delete(sock, qdisc); //rtnl_qdisc_put(qdisc); rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(0xffff, 0)); if ((err = rtnl_tc_set_kind(TC_CAST(qdisc), "ingress"))) { printf("Can not allocate ingress\n"); return -1; } /* Submit request to kernel and wait for response */ if ((err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE))) { printf("Can not allocate ingress Qdisc\n"); return -1; } /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); return 0; }
int main(int argc, char *argv[]) { struct nl_sock *nlh; struct rtnl_qdisc *qdisc; uint32_t handle, parent; int err = 1; if (nltool_init(argc, argv) < 0) return -1; if (argc < 5 || !strcmp(argv[1], "-h")) print_usage(); nlh = nltool_alloc_handle(); if (!nlh) goto errout; qdisc = rtnl_qdisc_alloc(); if (!qdisc) goto errout_free_handle; rtnl_qdisc_set_ifindex(qdisc, strtoul(argv[1], NULL, 0)); if (rtnl_tc_str2handle(argv[2], &handle) < 0) { fprintf(stderr, "%s\n", nl_geterror()); goto errout_free_qdisc; } if (rtnl_tc_str2handle(argv[3], &parent) < 0) { fprintf(stderr, "%s\n", nl_geterror()); goto errout_free_qdisc; } rtnl_qdisc_set_handle(qdisc, handle); rtnl_qdisc_set_parent(qdisc, parent); rtnl_qdisc_set_kind(qdisc, argv[4]); if (!strcasecmp(argv[4], "blackhole")) err = parse_blackhole_opts(qdisc, &argv[5], argc-5); else if (!strcasecmp(argv[4], "pfifo")) err = parse_pfifo_opts(qdisc, &argv[5], argc-5); else if (!strcasecmp(argv[4], "bfifo")) err = parse_bfifo_opts(qdisc, &argv[5], argc-5); else if (!strcasecmp(argv[4], "prio")) err = parse_prio_opts(qdisc, &argv[5], argc-5); else { fprintf(stderr, "Unknown qdisc \"%s\"\n", argv[4]); goto errout_free_qdisc; } if (err < 0) goto errout_free_qdisc; if (nltool_connect(nlh, NETLINK_ROUTE) < 0) goto errout_free_qdisc; if (rtnl_qdisc_add(nlh, qdisc, NLM_F_REPLACE) < 0) { fprintf(stderr, "Unable to add Qdisc: %s\n", nl_geterror()); goto errout_close; } err = 0; errout_close: nl_close(nlh); errout_free_qdisc: rtnl_qdisc_put(qdisc); errout_free_handle: nl_handle_destroy(nlh); errout: return err; }
TError TNlQdisc::Create(const TNl &nl) { TError error = TError::Success(); int ret; struct rtnl_qdisc *qdisc; if (Kind == "") return Delete(nl); qdisc = rtnl_qdisc_alloc(); if (!qdisc) return TError(EError::Unknown, std::string("Unable to allocate qdisc object")); rtnl_tc_set_ifindex(TC_CAST(qdisc), Index); rtnl_tc_set_parent(TC_CAST(qdisc), Parent); rtnl_tc_set_handle(TC_CAST(qdisc), Handle); ret = rtnl_tc_set_kind(TC_CAST(qdisc), Kind.c_str()); if (ret < 0) { error = nl.Error(ret, "Cannot to set qdisc type: " + Kind); goto free_qdisc; } if (Kind == "bfifo" || Kind == "pfifo") { if (Limit) rtnl_qdisc_fifo_set_limit(qdisc, Limit); } if (Kind == "htb") { if (Default) rtnl_htb_set_defcls(qdisc, Default); if (Quantum) rtnl_htb_set_rate2quantum(qdisc, Quantum); } if (Kind == "hfsc") { if (Default) rtnl_qdisc_hfsc_set_defcls(qdisc, Default); } if (Kind == "sfq") { if (Limit) rtnl_sfq_set_limit(qdisc, Limit); if (Quantum) rtnl_sfq_set_quantum(qdisc, Quantum); } if (Kind == "fq_codel") { if (Limit) rtnl_qdisc_fq_codel_set_limit(qdisc, Limit); if (Quantum) rtnl_qdisc_fq_codel_set_quantum(qdisc, Quantum); } nl.Dump("create", qdisc); ret = rtnl_qdisc_add(nl.GetSock(), qdisc, NLM_F_CREATE | NLM_F_REPLACE); if (ret < 0) error = nl.Error(ret, "Cannot create qdisc"); free_qdisc: rtnl_qdisc_put(qdisc); return error; }