Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 6
0
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;
}