Exemple #1
0
static struct snobj *handle_add_worker(struct snobj *q)
{
	unsigned int wid;
	unsigned int core;

	struct snobj *t;

	t = snobj_eval(q, "wid");
	if (!t)
		return snobj_err(EINVAL, "Missing 'wid' field");

	wid = snobj_uint_get(t);
	if (wid >= MAX_WORKERS)
		return snobj_err(EINVAL, "'wid' must be between 0 and %d",
				MAX_WORKERS - 1);

	t = snobj_eval(q, "core");
	if (!t)
		return snobj_err(EINVAL, "Missing 'core' field");

	core = snobj_uint_get(t);
	if (!is_cpu_present(core))
		return snobj_err(EINVAL, "Invalid core %d", core);

	if (is_worker_active(wid))
		return snobj_err(EEXIST, "worker:%d is already active", wid);

	launch_worker(wid, core);

	return NULL;
}
Exemple #2
0
static struct snobj *queue_out_init(struct module *m, struct snobj *arg)
{
    struct queue_out_priv *priv = get_priv(m);

    struct snobj *t;

    const char *port_name;

    int ret;

    if (!arg || snobj_type(arg) != TYPE_MAP)
        return snobj_err(EINVAL, "Argument must be a map");

    t = snobj_eval(arg, "port");
    if (!t || !(port_name = snobj_str_get(t)))
        return snobj_err(EINVAL, "Field 'port' must be specified");

    t = snobj_eval(arg, "qid");
    if (!t || snobj_type(t) != TYPE_INT)
        return snobj_err(EINVAL, "Field 'qid' must be specified");
    priv->qid = snobj_uint_get(t);

    priv->port = find_port(port_name);
    if (!priv->port)
        return snobj_err(ENODEV, "Port %s not found", port_name);

    ret = acquire_queues(priv->port, m, PACKET_DIR_OUT, &priv->qid, 1);
    if (ret < 0)
        return snobj_errno(-ret);

    priv->send_pkts = priv->port->driver->send_pkts;

    return NULL;
}
Exemple #3
0
static struct snobj *handle_create_module(struct snobj *arg)
{
	const char *mclass_name;
	const struct mclass *mclass;
	struct module *module;

	struct snobj *r;

	mclass_name = snobj_eval_str(arg, "mclass");
	if (!mclass_name)
		return snobj_err(EINVAL, "Missing 'mclass' field in arg");

	mclass = find_mclass(mclass_name);
	if (!mclass)
		return snobj_err(ENOENT, "No mclass '%s' found", mclass_name);

	module = create_module(snobj_eval_str(arg, "name"), mclass, 
			snobj_eval(arg, "arg"), &r);
	if (!module)
		return r;

	printf("Module %s created at %p\n", module->name, module);

	r = snobj_map();
	snobj_map_set(r, "name", snobj_str(module->name));

	return r;
}
Exemple #4
0
static struct snobj *handle_create_port(struct snobj *arg)
{
	const char *driver_name;
	const struct driver *driver;
	struct port *port;

	struct snobj *r;
	struct snobj *err;

	driver_name = snobj_eval_str(arg, "driver");
	if (!driver_name)
		return snobj_err(EINVAL, "Missing 'driver' field in arg");

	driver = find_driver(driver_name);
	if (!driver)
		return snobj_err(ENOENT, "No port driver '%s' found",
				driver_name);

	port = create_port(snobj_eval_str(arg, "name"), driver, 
			snobj_eval(arg, "arg"), &err);
	if (!port)
		return err;

	printf("Port %s created at %p\n", port->name, port);

	r = snobj_map();
	snobj_map_set(r, "name", snobj_str(port->name));

	return r;
}
Exemple #5
0
static struct snobj *handle_snobj_module(struct snobj *q)
{
	const char *m_name;
	const char *cmd;

	struct module *m;

	m_name = snobj_eval_str(q, "name");

	if (!m_name)
		return snobj_err(EINVAL, "Missing module name field 'name'");

	if ((m = find_module(m_name)) == NULL)
		return snobj_err(ENOENT, "No module '%s' found", m_name);

	cmd = snobj_eval_str(q, "cmd");

	if (strcmp(cmd, "query") == 0) {
		struct snobj *arg;

		if (!m->mclass->query)
			return snobj_err(ENOTSUP,
					"Module '%s' does not support queries",
					m_name);

		arg = snobj_eval(q, "arg");
		if (!arg) {
			struct snobj *ret;

			arg = snobj_nil();
			ret = m->mclass->query(m, arg);
			snobj_free(arg);
			return ret;
		}

		return m->mclass->query(m, arg);
	} else
		return snobj_err(ENOTSUP, "Not supported command '%s'", cmd);
}
Exemple #6
0
static struct snobj *init_port(struct port *p, struct snobj *conf)
{
	struct vport_priv *priv = get_port_priv(p);

	int container_pid = 0;
	int cpu;
	int rxq;

	int ret;

	if (strlen(p->name) >= IFNAMSIZ)
		return snobj_err(EINVAL, "Linux interface name should be " \
				"shorter than %d characters", IFNAMSIZ);

	if (snobj_eval_exists(conf, "docker")) {
		struct snobj *err = docker_container_pid(
				snobj_eval_str(conf, "docker"), 
				&container_pid);

		if (err)
			return err;
	}

	priv->fd = open("/dev/softnic", O_RDONLY);
	if (priv->fd == -1)
		return snobj_err(ENODEV, "the kernel module is not loaded");

	priv->bar = alloc_bar(p, container_pid);
	ret = ioctl(priv->fd, SN_IOC_CREATE_HOSTNIC, 
			rte_malloc_virt2phy(priv->bar));
	if (ret < 0) {
		close(priv->fd);
		return snobj_errno_details(-ret, 
				snobj_str("SN_IOC_CREATE_HOSTNIC failure"));
	}

	if (snobj_eval_exists(conf, "ip_addr")) {
		struct snobj *err = set_ip_addr(p, container_pid,
				snobj_eval(conf, "ip_addr"));
		
		if (err) {
			deinit_port(p);
			return err;
		}
	}

	for (cpu = 0; cpu < SN_MAX_CPU; cpu++)
		priv->map.cpu_to_txq[cpu] = cpu % p->num_queues[PACKET_DIR_INC];

	cpu = 0;
	for (rxq = 0; rxq < p->num_queues[PACKET_DIR_OUT]; rxq++) {
		while (is_worker_core(cpu))
			cpu = (cpu + 1) % sysconf(_SC_NPROCESSORS_ONLN);

		priv->map.rxq_to_cpu[rxq] = cpu;
		cpu = (cpu + 1) % sysconf(_SC_NPROCESSORS_ONLN);
	}

	ret = ioctl(priv->fd, SN_IOC_SET_QUEUE_MAPPING, &priv->map);
	if (ret < 0)
		perror("SN_IOC_SET_QUEUE_MAPPING");	

	return NULL;
}
Exemple #7
0
static struct snobj *handle_list_tcs(struct snobj *q)
{
	struct snobj *r;
	struct snobj *t;

	unsigned int wid_filter = MAX_WORKERS;

	struct ns_iter iter;

	struct tc *c;

	t = snobj_eval(q, "wid");
	if (t) {
		wid_filter = snobj_uint_get(t);

		if (wid_filter >= MAX_WORKERS)
			return snobj_err(EINVAL, 
					"'wid' must be between 0 and %d",
					MAX_WORKERS - 1);

		if (!is_worker_active(wid_filter))
			return snobj_err(EINVAL, "worker:%d does not exist", 
					wid_filter);
	}

	r = snobj_list();

	ns_init_iterator(&iter, NS_TYPE_TC);

	while ((c = (struct tc *)ns_next(&iter)) != NULL) {
		int wid;

		if (wid_filter < MAX_WORKERS) {
			if (workers[wid_filter]->s != c->s)
				continue;
			wid = wid_filter;
		} else {
			for (wid = 0; wid < MAX_WORKERS; wid++)
				if (is_worker_active(wid) && 
						workers[wid]->s == c->s)
					break;
		}

		struct snobj *elem = snobj_map();

		snobj_map_set(elem, "name", snobj_str(c->name));
		snobj_map_set(elem, "tasks", snobj_int(c->num_tasks));
		snobj_map_set(elem, "parent", snobj_str(c->parent->name));
		snobj_map_set(elem, "priority", snobj_int(c->priority));

		if (wid < MAX_WORKERS)
			snobj_map_set(elem, "wid", snobj_uint(wid));
		else
			snobj_map_set(elem, "wid", snobj_int(-1));


		snobj_list_add(r, elem);
	}

	ns_release_iterator(&iter);

	return r;
}