Ejemplo n.º 1
0
Archivo: snctl.c Proyecto: apanda/bess
static struct snobj *handle_enable_tcpdump(struct snobj *arg)
{
	const char *m_name;
	const char *fifo;
	uint16_t gate;

	struct module *m;

	int ret;

	m_name = snobj_eval_str(arg, "name");
	gate = snobj_eval_uint(arg, "gate");
	fifo = snobj_eval_str(arg, "fifo");

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

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

	if (gate >= m->allocated_gates)
		return snobj_err(EINVAL, "Gate '%hu' does not exist", gate);

	ret = enable_tcpdump(fifo, m, gate);

	if (ret < 0) {
		return snobj_err(-ret, "Enabling tcpdump %s[%d] failed",
				m_name, gate);
	}
	return NULL;
}
Ejemplo n.º 2
0
Archivo: snctl.c Proyecto: 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;
}
Ejemplo n.º 3
0
Archivo: snctl.c Proyecto: apanda/bess
static struct snobj *handle_connect_modules(struct snobj *arg)
{
	const char *m1_name;
	const char *m2_name;
	uint16_t gate;

	struct module *m1;
	struct module *m2;

	int ret;

	m1_name = snobj_eval_str(arg, "m1");
	m2_name = snobj_eval_str(arg, "m2");
	gate = snobj_eval_uint(arg, "gate");

	if (!m1_name || !m2_name)
		return snobj_err(EINVAL, "Missing 'm1' or 'm2' field in arg");

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

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

	ret = connect_modules(m1, gate, m2);
	if (ret < 0)
		return snobj_err(-ret, "Connection '%s'[%d]->'%s' failed", 
			m1_name, gate, m2_name);

	printf("%s[%d] -> %s\n", m1_name, gate, m2_name);

	return NULL;
}
Ejemplo n.º 4
0
Archivo: snctl.c Proyecto: 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;
}
Ejemplo n.º 5
0
static struct snobj *handle_attach_task(struct snobj *q)
{
	const char *m_name;
	const char *tc_name;

	task_id_t tid;

	struct module *m;
	struct task *t;

	m_name = snobj_eval_str(q, "name");

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

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

	tid = snobj_eval_uint(q, "taskid");
	if (tid >= MAX_TASKS_PER_MODULE)
		return snobj_err(EINVAL, "'taskid' must be between 0 and %d",
				MAX_TASKS_PER_MODULE - 1);

	if ((t = m->tasks[tid]) == NULL)
		return snobj_err(ENOENT, "Task %s:%hu does not exist", 
				m_name, tid);

	tc_name = snobj_eval_str(q, "tc");

	if (tc_name) {
		struct tc *c;

		c = ns_lookup(NS_TYPE_TC, tc_name);
		if (!c)
			return snobj_err(ENOENT, "No TC '%s' found", tc_name);

		task_attach(t, c);
	} else {
		int wid;		/* TODO: worker_id_t */

		if (task_is_attached(t))
			return snobj_err(EBUSY, "Task %s:%hu is already "
					"attached to a TC", m_name, tid);

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

		if (!is_worker_active(wid))
			return snobj_err(EINVAL, "Worker %d does not exist", wid);

		assign_default_tc(wid, t);
	}

	return NULL;
}
Ejemplo n.º 6
0
Archivo: snctl.c Proyecto: apanda/bess
static struct snobj *handle_disconnect_modules(struct snobj *arg)
{
	const char *m_name;
	uint16_t gate;

	struct module *m;

	int ret;

	m_name = snobj_eval_str(arg, "name");
	gate = snobj_eval_uint(arg, "gate");

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

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

	ret = disconnect_modules(m, gate);
	if (ret < 0)
		return snobj_err(-ret, "Disconnection '%s'[%d] failed", 
			m_name, gate);

	printf("%s[%d] -> <dead end>\n", m_name, gate);

	return NULL;
}
Ejemplo n.º 7
0
static struct snobj *handle_disable_tcpdump(struct snobj *q)
{
	const char *m_name;
	gate_t gate;

	struct module *m;

	int ret;

	m_name = snobj_eval_str(q, "name");
	gate = snobj_eval_uint(q, "gate");

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

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

	if (gate >= m->allocated_gates)
		return snobj_err(EINVAL, "Gate '%hu' does not exist", gate);

	ret = disable_tcpdump(m, gate);

	if (ret < 0) {
		return snobj_err(-ret, "Disabling tcpdump %s[%d] failed",
				m_name, gate);
	}
	return NULL;
}
Ejemplo n.º 8
0
Archivo: snctl.c Proyecto: apanda/bess
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);
}
Ejemplo n.º 9
0
static struct snobj *handle_add_tc(struct snobj *q)
{
	const char *tc_name;
	int wid;

	struct tc_params params;
	struct tc *c;

	tc_name = snobj_eval_str(q, "name");
	if (!tc_name)
		return snobj_err(EINVAL, "Missing 'name' field");

	if (!ns_is_valid_name(tc_name))
		return snobj_err(EINVAL, "'%s' is an invalid name", tc_name);

	if (ns_name_exists(tc_name))
		return snobj_err(EINVAL, "Name '%s' already exists", tc_name);

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

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

	memset(&params, 0, sizeof(params));

	strcpy(params.name, tc_name);

	params.priority = snobj_eval_int(q, "priority");
	if (params.priority == DEFAULT_PRIORITY)
		return snobj_err(EINVAL, "Priority %d is reserved",
				DEFAULT_PRIORITY);

	/* TODO */
	params.share = 1;
	params.share_resource = RESOURCE_CNT;

	c = tc_init(workers[wid]->s, &params);
	if (is_err(c))
		return snobj_err(-ptr_to_err(c), "tc_init() failed");

	tc_join(c);

	return NULL;
}
Ejemplo n.º 10
0
Archivo: snctl.c Proyecto: 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;
}
Ejemplo n.º 11
0
Archivo: snctl.c Proyecto: apanda/bess
static struct snobj *handle_snobj_softnic(struct snobj *q)
{
	struct snobj *arg;
	const char *s;

	s = snobj_eval_str(q, "cmd");
	if (!s)
		return snobj_err(EINVAL, "Missing 'cmd' field");

	arg = snobj_map_get(q, "arg");

	for (int i = 0; sn_handlers[i].cmd != NULL; i++) {
		if (strcmp(s, sn_handlers[i].cmd) != 0)
			continue;

		if (sn_handlers[i].pause_needed && is_any_worker_running())
			return snobj_err(EBUSY, "There is a running worker");

		return sn_handlers[i].func(arg);
	}

	return snobj_err(ENOTSUP, "Unknown command in 'cmd': '%s'", s);
}
Ejemplo n.º 12
0
Archivo: vport.c Proyecto: 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;
}