Beispiel #1
0
/*---------------------------------------------------------------------*/
static int
loadline(lua_State *L)
{
	TRACE_LUA_FUNC_START();

        int status;
        lua_settop(L, 0);
        if (!pushline(L, 1)) {
		TRACE_LUA_FUNC_END();
                return -1;  /* no input */
	}
        for (;;) {  /* repeat until gets a complete line */
                status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
                if (!incomplete(L, status)) break;  /* cannot try to add lines? */
                if (!pushline(L, 0))  {/* no more input? */
			TRACE_LUA_FUNC_END();
                        return -1;
		}
                lua_pushliteral(L, "\n");  /* add a new line... */
                lua_insert(L, -2);  /* ...between the two lines */
                lua_concat(L, 3);  /* join them */
        }
	TRACE_DEBUG_LOG("%s\n", lua_tostring(L, 1));
	TRACE_LUA_FUNC_END();
        return status;
}
Beispiel #2
0
/**
 * XXX - This function needs to be improved...
 */
static int
linker_new(lua_State *L)
{
	TRACE_LUA_FUNC_START();
	int arg = -1;
	int nargs = lua_gettop(L);
	const char *brick_name = luaL_optstring(L, 1, 0);
	int i;

	if (nargs == 2) {
		arg = luaL_optint(L, 2, 0);
	}

	Linker_Intf *linker = push_linker(L);
	for (i = 3; elibs[i].init != NULL; i++) {
		if (!strcmp(elibs[i].getId(), brick_name))
			linker->type = i;
	}
	
	linker->hash_split = arg;
	TRACE_DEBUG_LOG("Hash splitting logic: %d\n", linker->hash_split);
	linker->output_count = 0;
	linker->input_count = 0;
	linker->next_linker = NULL;
	TRACE_LUA_FUNC_END();
	return 1;
}
Beispiel #3
0
/*---------------------------------------------------------------------*/
int
connect_to_bricks_server(char *rshell_args)
{
	TRACE_BACKEND_FUNC_START();
	int sock;
	struct sockaddr_in server;
	char *ip_addr, *port_str;
	uint16_t port;

	if (rshell_args == NULL)
		ip_addr = port_str = NULL;
	else {
		/* first parse the ipaddr and port string */
		ip_addr = strtok(rshell_args, ":");
		port_str = strtok(NULL, ":");
	}
	port = (port_str == NULL) ? BRICKS_LISTEN_PORT : atoi(port_str);

	/* Create socket */
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1) {
		TRACE_ERR("Could not create socket: %s\n", 
			  strerror(errno));
		TRACE_BACKEND_FUNC_END();
		return -1;
	}
	TRACE_DEBUG_LOG("Socket created");
     
	server.sin_addr.s_addr = (ip_addr == NULL) ? 
		inet_addr("127.0.0.1") : inet_addr(ip_addr);
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
 
	/* Connect to remote server */
	if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) {
		TRACE_ERR("Connect failed!: %s\n", strerror(errno));
		TRACE_BACKEND_FUNC_END();
		return -1;
	}
     
	TRACE_DEBUG_LOG("Connected\n");
	TRACE_BACKEND_FUNC_END();

	return sock;
}
Beispiel #4
0
/**
 * Overloaded garbage collector
 */
static int
linker_gc(lua_State *L)
{
	TRACE_LUA_FUNC_START();
	TRACE_DEBUG_LOG("Wiping off Linker: %p\n", to_linker(L, 1));
	TRACE_LUA_FUNC_END();
	UNUSED(L);
	return 0;
}
Beispiel #5
0
/**
 * Overloaded garbage collector
 */
static int
pkteng_gc(lua_State *L)
{
	TRACE_LUA_FUNC_START();
	TRACE_DEBUG_LOG("Wiping off PktEngine: %p\n", to_pkteng(L, 1));
	TRACE_LUA_FUNC_END();
	UNUSED(L);
	return 0;
}
Beispiel #6
0
/**
 * Initializes all the modules of the system
 */
static inline void
init_modules()
{
	TRACE_FUNC_START();

	TRACE_DEBUG_LOG("Initializing the engines module \n");
	pktengine_init();
	interface_init();
	initBricks();

	TRACE_FUNC_END();
}
Beispiel #7
0
/*---------------------------------------------------------------------*/
static int
luaopen_platform(lua_State *L)
{
	/* load systems' lua interface */
	TRACE_LUA_FUNC_START();

	platform_dir_create_meta(L);
        TRACE_DEBUG_LOG("%s", "Loading "PLATFORM_NAME" command metatable\n");
        luaL_openlib(L, PLATFORM_NAME, platformlib, 0);
        platform_set_info(L);

	TRACE_LUA_FUNC_END();
	return 1;
}
Beispiel #8
0
/**
 * XXX - This function needs to be revised..
 * Services incoming request from userland applications and takes
 * necessary actions. The actions can be: (i) passing packets to userland
 * apps etc.
 */
static void
process_request_backend(engine *eng, struct kevent chlist[])
{
	TRACE_BACKEND_FUNC_START();
	int client_sock, c, total_read, fd;
	struct sockaddr_in client;
	int read_size;
	char client_message[2000];
	req_block *rb;
	char channelname[20];
	total_read = read_size = 0;

	/* accept connection from an incoming client */
	client_sock = accept(eng->listen_fd, (struct sockaddr *)&client, (socklen_t *)&c);
	if (client_sock < 0) {
		TRACE_LOG("accept failed: %s\n", strerror(errno));
		TRACE_BACKEND_FUNC_END();
		return;
	}
     
	/* Receive a message from client */
	while ((read_size = recv(client_sock, 
				 &client_message[total_read], 
				 sizeof(req_block) - total_read, 0)) > 0) {
		total_read += read_size;
		if ((unsigned)total_read >= sizeof(req_block)) break;
	}

	TRACE_DEBUG_LOG("Total bytes read from listening socket: %d\n", 
			total_read);
	
	/* parse new rule */
	rb = (req_block *)client_message;
	TRACE_DEBUG_LOG("Got a new rule\n");
	TRACE_DEBUG_LOG("Target: %d\n", rb->t);
	TRACE_DEBUG_LOG("TargetArgs.pid: %d\n", rb->targs.pid);
	TRACE_DEBUG_LOG("TargetArgs.proc_name: %s\n", rb->targs.proc_name);
	TRACE_FLUSH();

	//snprintf(channelname, 20, "vale%s%d:s", 
	//	 rb->targs.proc_name, rb->targs.pid);
	snprintf(channelname, 20, "%s%d", 
		 rb->targs.proc_name, rb->targs.pid);

	Rule *r = add_new_rule(eng, NULL, rb->t);

	/* create communication back channel */
	fd = eng->iom.create_channel(eng, r, channelname/*, client_sock*/);
	EV_SET(&chlist[fd], fd, EVFILT_READ | EVFILT_WRITE, EV_ADD, 0, 0, NULL);

	/* add client sock to the polling layer */
	fd = client_sock;
	EV_SET(&chlist[fd], fd, EVFILT_READ | EVFILT_WRITE, EV_ADD, 0, 0, NULL);
	
	/* continue listening */
	fd = eng->listen_fd;
	EV_SET(&chlist[fd], fd, EVFILT_READ | EVFILT_WRITE, EV_ADD, 0, 0, NULL);
	
	TRACE_BACKEND_FUNC_END();
	return;
}
Beispiel #9
0
/**
 * Main entry point
 */
int
main(int argc, char **argv)
{
	TRACE_FUNC_START();
	int rc;

	/* accept command-line arguments */
	while ( (rc = getopt(argc, argv, "a:b:hsdf:")) != -1) {
		switch(rc) {
		case 'a':
			pc_info.rshell_args = (int8_t *)strdup(optarg);
			if (NULL == pc_info.rshell_args) {
				TRACE_ERR("Can't strdup remote shell args!!\n");
			}
			break;
		case 'b':
			pc_info.batch_size = atoi(optarg);
			TRACE_DEBUG_LOG("Taking batch_size as %d\n", 
					pc_info.batch_size);
			break;
		case 'd':
			pc_info.daemonize = 1;
			break;
		case 'h':
			print_help(*argv);
			break;
		case 'f':
			pc_info.lua_startup_file = (uint8_t *)strdup(optarg);
			if (NULL == pc_info.lua_startup_file) {
				TRACE_ERR("Can't strdup string for lua_startup_file: %s\n",
					  strerror(errno));
			}
			TRACE_DEBUG_LOG("Taking file %s as startup\n",
					pc_info.lua_startup_file);
			load_lua_file(optarg);
			break;
		case 's':
			pc_info.rshell = 1;
			break;
		default:
			print_help(*argv);
			break;
		}
	}

	/* init_modules */
	init_modules();

	/* check if rshell and daemonize are both enabled */
	if (pc_info.daemonize && pc_info.rshell) {
		fprintf(stdout, "You cannot create a daemon process and "
			"a remote shell at the same time!\n");
		fflush(stdout);
		print_help(*argv);
		return EXIT_FAILURE;
	}
	
	/* warp to remote shell, if asked */
	if (pc_info.rshell) {
		if (pc_info.rshell_args == NULL)
			fprintf(stdout, "Using localhost and port %d by default\n",
				BRICKS_LISTEN_PORT);
		lua_kickoff(LUA_EXE_REMOTE_SHELL, pc_info.rshell_args);
		return EXIT_SUCCESS;
	}

	/* daemonize, if asked */
	if ((pc_info.daemonize && (rc=do_daemonize()) == 0) ||
	    !pc_info.daemonize) {
		if (mark_pid_file(pv.pid_file) != 0) {
			TRACE_FUNC_END();
			TRACE_ERR("Can't lock the pid file.\n"
				  "Is a previous bricks daemon already running??\n");
		}
		export_global_socket();
		lua_kickoff((pc_info.daemonize) ? 
			    LUA_EXE_SCRIPT : LUA_EXE_HOME_SHELL, NULL);
	}

	/* initialize file printing mini-module */
	print_status_file();

	/* 
	 * if the user wants to daemonize and the process 
	 * is the child, then jump to accepting requests...
	 */
	if (pc_info.daemonize && rc == 0) {
		start_listening_reqs();
	}
	
	TRACE_FUNC_END();
	clean_exit(EXIT_SUCCESS);

	/* control will never come here */
	return EXIT_SUCCESS;
}
Beispiel #10
0
/**
 * XXX - This function is being revised
 * Services incoming request from userland applications and takes
 * necessary actions. The actions can be: (i) passing packets to userland
 * apps etc.
 */
static void
process_request_backend(engine *eng, int epoll_fd)
{
	TRACE_BACKEND_FUNC_START();
	int client_sock, c, total_read;
	struct sockaddr_in client;
	int read_size;
	char client_message[2000];
	struct epoll_event ev;
	req_block *rb;
	resp_block respb;

	total_read = read_size = 0;
	respb.len = sizeof(resp_block);

	/* accept connection from an incoming client */
	client_sock = accept(eng->listen_fd, (struct sockaddr *)&client, (socklen_t *)&c);
	if (client_sock < 0) {
		TRACE_LOG("accept failed: %s\n", strerror(errno));
		TRACE_BACKEND_FUNC_END();
		return;
	}
     
	/* Receive a message from client */
	while ((read_size = recv(client_sock, 
				 &client_message[total_read], 
				 sizeof(req_block) - total_read, 0)) > 0) {
		total_read += read_size;
		if ((unsigned)total_read >= sizeof(req_block)) break;
	}

	TRACE_DEBUG_LOG("Total bytes read from listening socket: %d\n", 
			total_read);
	
	/* parse new rule */
	rb = (req_block *)client_message;
	TRACE_DEBUG_LOG("Got a new request\n");
	TRACE_DEBUG_LOG("\tLen: %u\n", rb->len);
	TRACE_DEBUG_LOG("\tInterface name: %s\n", rb->ifname);
	TRACE_FLUSH();

#if 0
	respb.flag = (process_filter_request(eng, rb->ifname, &rb->f) == -1) ?
		0 : 1;
#else
	(void)rb;
	respb.flag = 1;
#endif
	
	/* write the response back to the app */
	if (write(client_sock, &respb, sizeof(respb)) == -1) {
		TRACE_LOG("Write failed due to %s\n", 
			  strerror(errno));
	}

	/* add client sock to the polling layer */
	ev.data.fd = client_sock;
	ev.events = EPOLLIN | EPOLLOUT;
	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
		TRACE_LOG("Engine %s failed to exe epoll_ctl for fd: %d\n",
			  eng->name, epoll_fd);
		TRACE_BACKEND_FUNC_END();
		return;
	}
	
	/* for the moment, close the client socket immediately */
	close(client_sock);

	/* continue listening */
	ev.data.fd = eng->listen_fd;
	ev.events = EPOLLIN | EPOLLOUT;
	if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, ev.data.fd, &ev) == -1) {
		TRACE_LOG("Engine %s failed to exe epoll_ctl for fd: %d\n",
			  eng->name, epoll_fd);
		TRACE_BACKEND_FUNC_END();
		return;
	}
	
	TRACE_BACKEND_FUNC_END();
	return;
}
Beispiel #11
0
/*---------------------------------------------------------------------*/
static int
pkteng_link(lua_State *L)
{
	TRACE_LUA_FUNC_START();
	PktEngine_Intf *pe = check_pkteng(L, 1);
	Linker_Intf *linker;
	Brick *first_brick;
	int nargs = lua_gettop(L);
	int i;

	/* check if args2 is user-data */
	luaL_checktype(L, 2, LUA_TUSERDATA);
	
	/* Retrieve linker data */
	linker = (Linker_Intf *)luaL_optudata(L, 2);

	/* set values as default */
	pe->batch = DEFAULT_BATCH_SIZE;
	pe->qid = -1;

	/* if 3rd arg is passed, fill it with batch size */
	if (nargs >= 3)
		pe->batch = luaL_checkint(L, 3);
	/* if 4th arg is passed, fill it with qid */
	if (nargs >= 4)
		pe->qid = luaL_checkint(L, 4);
	lua_settop(L, 1);

	TRACE_DEBUG_LOG("Engine info so far...:\n"
			"\tName: %s\n"
			"\tCpu: %d\n"
			"\tBatch: %d\n"
			"\tQid: %d\n",
			pe->eng_name,
			pe->cpu,
			pe->batch,
			pe->qid);
	
	for (i = 0; i < linker->input_count; i++) {
		/* link the source(s) with the packet engine */
		pktengine_link_iface((uint8_t *)pe->eng_name, 
				     (uint8_t *)linker->input_link[i], 
				     pe->batch, pe->qid);
		TRACE_LOG("Linking %s with link %s with batch size: %d and qid: %d\n",
			  pe->eng_name, linker->input_link[i], pe->batch, pe->qid);
	}
	first_brick = createBrick(linker->type);
	if (first_brick == NULL) {
		TRACE_LUA_FUNC_END();
		return 1;
	}

	first_brick->eng = engine_find((unsigned char *)pe->eng_name);
	first_brick->elib->init(first_brick, linker);
	if (first_brick->eng == NULL) {
		TRACE_LOG("Could not find engine with name: %s\n",
			  pe->eng_name);
		TRACE_LUA_FUNC_END();
		free(first_brick);
		return 1;
	}
	first_brick->elib->link(first_brick, linker);
	
	/* if there are pipelines, link them as well */
	while (linker->next_linker != NULL) {
		linker = linker->next_linker;
		first_brick->elib->link(first_brick, linker); 
	}

	TRACE_LUA_FUNC_END();
	return 1;
}
/*---------------------------------------------------------------------*/
int32_t
netmap_link_iface(void *ctxt, const unsigned char *iface,
		  const uint16_t batchsize, int8_t qid)
{
	TRACE_NETMAP_FUNC_START();

	char nifname[MAX_IFNAMELEN];
	netmap_module_context *nmc = (netmap_module_context *)ctxt;
	netmap_iface_context *nic = NULL;

	/* setting nm-ifname*/
	sprintf(nifname, "netmap:%s", iface);

	/* check if the interface has been registered with some other engine */
	netiface *nif = interface_find((char *)iface);
	if (nif == NULL) {
		nic = calloc(1, sizeof(netmap_iface_context));
		if (nic == NULL) {
			TRACE_ERR("Can't allocate memory for "
				  "netmap_iface_context (for %s)\n", iface);
			TRACE_NETMAP_FUNC_END();
			return -1;
		}
		/* resetting base_nmd */
		memset(&nic->base_nmd, 0, sizeof(struct nm_desc));

		/* resetting fd to -1 */
		nic->global_fd = nmc->local_fd = -1;

		/* use some extra rings */
		nic->base_nmd.req.nr_arg3 = NM_EXTRA_BUFS;
		nic->nmd_flags |= NM_OPEN_ARG3;

		nic->global_nmd = nm_open((char *)nifname, NULL, 
					  nic->nmd_flags, 
					  &nic->base_nmd);

		if (nic->global_nmd == NULL) {
			TRACE_LOG("Unable to open %s: %s\n", 
				  iface, strerror(errno));
			free(nic);
			TRACE_NETMAP_FUNC_END();
			return -1;
		}
		nic->global_fd = nic->global_nmd->fd;
		TRACE_DEBUG_LOG("mapped %dKB at %p\n", 
				nic->global_nmd->req.nr_memsize>>10, 
				nic->global_nmd->mem);
		TRACE_DEBUG_LOG("zerocopy %s", 
				(nic->global_nmd->mem == nic->base_nmd.mem) ? 
				"enabled\n" : "disabled\n");
		
		if (qid != -1) {
			nic->global_nmd->req.nr_flags = NR_REG_ONE_NIC;
			nic->global_nmd->req.nr_ringid = qid;
		}
	
		/* create interface entry */
		create_interface_entry(iface, (qid == -1) ? NO_QUEUES : HW_QUEUES, 
				       IO_NETMAP, nic, nmc->eng);
	} else { /* otherwise check if that interface can be registered */