Example #1
0
File: snctl.c Project: apanda/bess
static struct snobj *handle_list_ports(struct snobj *q)
{
	struct snobj *r;

	int cnt = 1;
	int offset;

	r = snobj_list();

	for (offset = 0; cnt != 0; offset += cnt) {
		const int arr_size = 16;
		const struct port *ports[arr_size];

		int i;

		cnt = list_ports(ports, arr_size, offset);

		for (i = 0; i < cnt; i++) {
			struct snobj *port = snobj_map();

			snobj_map_set(port, "name",
					snobj_str(ports[i]->name));
			snobj_map_set(port, "driver",
					snobj_str(ports[i]->driver->name));

			snobj_list_add(r, port);
		}
	};

	return r;
}
Example #2
0
File: snctl.c Project: apanda/bess
static struct snobj *handle_get_module_info(struct snobj *arg)
{
	const char *m_name;
	struct module *m;

	struct snobj *r;
	struct snobj *gates;

	m_name = snobj_str_get(arg);

	if (!m_name)
		return snobj_err(EINVAL, "Argument must be a name in str");

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

	r = snobj_map();
	gates = snobj_list();

	snobj_map_set(r, "name", snobj_str(m->name));
	snobj_map_set(r, "mclass", snobj_str(m->mclass->name));

	if (m->mclass->get_desc)
		snobj_map_set(r, "desc", m->mclass->get_desc(m));

	if (m->mclass->get_dump)
		snobj_map_set(r, "dump", m->mclass->get_dump(m));

	for (int i = 0; i < m->allocated_gates; i++) {
		if (m->gates[i].m) {
			struct snobj *gate = snobj_map();
			snobj_map_set(gate, "gate", snobj_uint(i));
#if TRACK_GATES
			snobj_map_set(gate, "cnt", 
					snobj_uint(m->gates[i].cnt));
			snobj_map_set(gate, "pkts", 
					snobj_uint(m->gates[i].pkts));
			snobj_map_set(gate, "timestamp", 
					snobj_double(get_epoch_time()));
#endif
			snobj_map_set(gate, "name", snobj_str(m->gates[i].m->name));
			snobj_list_add(gates, gate);
		}
	}

	snobj_map_set(r, "gates", gates);

	return r;
}
Example #3
0
File: snctl.c Project: apanda/bess
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;
}
Example #4
0
File: snctl.c Project: apanda/bess
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;
}
Example #5
0
File: snctl.c Project: apanda/bess
static struct snobj *handle_list_modules(struct snobj *q)
{
	struct snobj *r;

	int cnt = 1;
	int offset;

	r = snobj_list();

	for (offset = 0; cnt != 0; offset += cnt) {
		const int arr_size = 16;
		const struct module *modules[arr_size];

		int i;
		
		cnt = list_modules(modules, arr_size, offset);

		for (i = 0; i < cnt; i++) {
			const struct module *m = modules[i];
			const struct mclass *mclass = m->mclass;

			struct snobj *module = snobj_map();

			snobj_map_set(module, "name", 
					snobj_str(m->name));
			snobj_map_set(module, "mclass", 
					snobj_str(mclass->name));
			if (mclass->get_desc) {
				snobj_map_set(module, "desc", 
						mclass->get_desc(m));
			}

			snobj_list_add(r, module);
		}
	};

	return r;
}
Example #6
0
File: vport.c Project: apanda/bess
static struct snobj *docker_container_pid(char *cid, int *container_pid)
{
	char buf[1024];

	FILE *fp;
		
	int ret;
	int exit_code;

	if (!cid)
		return snobj_err(EINVAL, "field 'docker' should be " \
				"a containder ID or name in string");

	ret = snprintf(buf, sizeof(buf), 
			"docker inspect --format '{{.State.Pid}}' " \
			"%s 2>&1", cid);
	if (ret >= sizeof(buf))
		return snobj_err(EINVAL, "The specified Docker " \
				"container ID or name is too long");

	fp = popen(buf, "r");
	if (!fp) 
		return snobj_err_details(ESRCH, 
				snobj_str_fmt("popen() errno=%d (%s)",
					errno, strerror(errno)),
				"Command 'docker' is not available. " \
				"(not installed?)");

	ret = fread(buf, 1, sizeof(buf) - 1, fp);
	if (ret == 0)
		return snobj_err(ENOENT, "Cannot find the PID of " \
				"container %s", cid);

	buf[ret] = '\0';
	
	ret = pclose(fp);
	exit_code = WEXITSTATUS(ret);

	if (exit_code != 0 || sscanf(buf, "%d", container_pid) == 0) {
		struct snobj *details = snobj_map();

		snobj_map_set(details, "exit_code", snobj_int(exit_code));
		snobj_map_set(details, "docker_err", snobj_str(buf));
	
		return snobj_err_details(ESRCH, details,
				"Cannot find the PID of container %s", cid);
	}

	return NULL;
}
Example #7
0
File: snctl.c Project: apanda/bess
struct snobj *handle_request(struct client *c, struct snobj *q)
{
	struct snobj *r = NULL;
	const char *s;

#if 0
	printf("Request:\n");
	snobj_dump(q);
#endif

	if (q->type != TYPE_MAP) {
		r = snobj_err(EINVAL, "The message must be a map");
		goto reply;
	}

	s = snobj_eval_str(q, "to");
	if (!s) {
		r = snobj_str("There is no 'to' field");
		goto reply;
	}

	if (strcmp(s, "softnic") == 0) {
		r = handle_snobj_softnic(q);
	} else if (strcmp(s, "module") == 0) {
		r = handle_snobj_module(q);
	} else
		r = snobj_err(EINVAL, "Unknown destination in 'to': %s", s);

reply:
	/* No response was made? (normally means "success") */
	if (!r)
		r = snobj_nil();

#if 0
	printf("Response:\n");
	snobj_dump(r);
#endif

	return r;
}
Example #8
0
File: snctl.c Project: apanda/bess
static struct snobj *handle_list_drivers(struct snobj *q)
{
	struct snobj *r;

	int cnt = 1;
	int offset;

	r = snobj_list();

	for (offset = 0; cnt != 0; offset += cnt) {
		const int arr_size = 16;
		const struct driver *drivers[arr_size];

		int i;

		cnt = list_drivers(drivers, arr_size, offset);

		for (i = 0; i < cnt; i++)
			snobj_list_add(r, snobj_str(drivers[i]->name));
	};

	return r;
}
Example #9
0
File: vport.c Project: apanda/bess
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;
}
Example #10
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;
}