int main(void)
{
	static ofp_init_global_t oig;
	odp_instance_t instance;

	if (odp_init_global(&instance, NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	if (ofp_init_global(instance, &oig)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}

	OFP_INFO("Init successful.\n");
	return 0;
}
static int
init_suite(void)
{
	ofp_global_param_t params;
	odp_instance_t instance;

	/* Init ODP before calling anything else */
	if (odp_init_global(&instance, NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		return -1;
	}

	/* Init this thread */
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		return -1;
	}

	ofp_init_global_param(&params);
	params.enable_nl_thread = 0;
	memset(params.pkt_hook, 0, sizeof(params.pkt_hook));
	params.pkt_hook[OFP_HOOK_OUT_IPv4] = fastpath_hook_out_IPv4;
#ifdef INET6
	params.pkt_hook[OFP_HOOK_OUT_IPv6] = fastpath_hook_out_IPv6;
#endif /* INET6 */

	(void) ofp_init_global(instance, &params);

	ofp_init_local();

	init_ifnet();

	ofp_add_mac(dev, tun_rem_ip, tun_rem_mac);

	return 0;
}
Exemple #3
0
/** main() Application entry point
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	if (odp_init_global(NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	if (core_count > 1)
		num_workers--;

	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	memset(&app_init_params, 0, sizeof(app_init_params));
	app_init_params.linux_core_id = 0;
	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;

	if (ofp_init_global(&app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}

	memset(thread_tbl, 0, sizeof(thread_tbl));
	/* Start dataplane dispatcher worker threads */
	ofp_linux_pthread_create(thread_tbl,
				  &cpumask,
				  default_event_dispatcher,
				  ofp_eth_vlan_processing,
				  ODP_THREAD_CONTROL
				);

	/* other app code here.*/
	/* Start CLI */
	ofp_start_cli_thread(app_init_params.linux_core_id, params.conf_file);

	sleep(5);

	ofp_loglevel = OFP_LOG_INFO;

	config_suite_framework(app_init_params.linux_core_id);

	OFP_INFO("\n\nSuite: IPv4 UDP socket: create and close.\n\n");
	if (!init_suite(NULL))
		run_suite(create_close_udp, create_close_udp_noproto);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP socket: create and close.\n\n");
	if (!init_suite(NULL))
		run_suite(create_close_tcp, create_close_tcp_noproto);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP socket: create and close.\n\n");
	if (!init_suite(NULL))
		run_suite(create_close_udp6, create_close_udp6_noproto);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 TCP socket: create and close.\n\n");
	if (!init_suite(NULL))
		run_suite(create_close_tcp6, create_close_tcp6_noproto);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /* INET6 */

	OFP_INFO("\n\nSuite: IPv4 UDP socket: bind.\n\n");
	if (!init_suite(init_udp_create_socket))
		run_suite(bind_ip4_local_ip, bind_ip4_any);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP socket: bind.\n\n");
	if (!init_suite(init_tcp_create_socket))
		run_suite(bind_ip4_local_ip, bind_ip4_any);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP socket: bind.\n\n");
	if (!init_suite(init_udp6_create_socket))
		run_suite(bind_ip6_local_ip, bind_ip6_any);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 TCP socket: bind.\n\n");
	if (!init_suite(init_tcp6_create_socket))
		run_suite(bind_ip6_local_ip, bind_ip6_any);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /* INET6 */

	OFP_INFO("\n\nSuite: IPv4 UDP socket: shutdown.\n\n");
	if (!init_suite(init_udp_create_socket))
		run_suite(shutdown_socket, shutdown_socket);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP socket: shutdown (no connection).\n\n");
	if (!init_suite(init_tcp_create_socket))
		run_suite(shutdown_socket, shutdown_socket);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP socket: shutdown.\n\n");
	if (!init_suite(init_udp6_create_socket))
		run_suite(shutdown_socket, shutdown_socket);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 TCP socket: shutdown (no connection).\n\n");
	if (!init_suite(init_tcp6_create_socket))
		run_suite(shutdown_socket, shutdown_socket);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /* INET6 */

	OFP_INFO("\n\nSuite: IPv4 UDP socket: connect.\n\n");
	if (!init_suite(init_udp_create_socket))
		run_suite(connect_udp4, connect_bind_udp4);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 UDP socket: connect + shutdown.\n\n");
	if (!init_suite(init_udp_create_socket))
		run_suite(connect_shutdown_udp4, connect_shutdown_bind_udp4);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP socket: connect.\n\n");
	if (!init_suite(init_udp6_create_socket))
		run_suite(connect_udp6, connect_bind_udp6);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP socket: connect + shutdown.\n\n");
	if (!init_suite(init_udp6_create_socket))
		run_suite(connect_shutdown_udp6, connect_shutdown_bind_udp6);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP socket: connect + shutdown + any.\n\n");
	if (!init_suite(init_udp6_create_socket))
		run_suite(connect_shutdown_udp6_any,
				connect_shutdown_bind_udp6_any);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /* INET6 */

	OFP_INFO("\n\nSuite: IPv4 UDP socket BIND local address: send + sendto\n\n");
	if (!init_suite(init_udp_bind_local_ip))
		run_suite(send_ip4_udp_local_ip, sendto_ip4_udp_local_ip);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 UDP socket bind any address: send + sendto\n\n");
	if (!init_suite(init_udp_bind_any))
		run_suite(send_ip4_udp_any, sendto_ip4_udp_any);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP socket BIND local address: send + sendto\n\n");
	if (!init_suite(init_udp6_bind_local_ip))
		run_suite(send_ip6_udp_local_ip, sendto_ip6_udp_local_ip);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP socket bind any address: send + sendto\n\n");
	if (!init_suite(init_udp6_bind_any))
		run_suite(send_ip6_udp_any, sendto_ip6_udp_any);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /* INET6 */

	OFP_INFO("\n\nSuite: IPv4 UDP bind local IP: sendto + recv.\n\n");
	if (!init_suite(init_udp_local_ip))
		run_suite(send_udp_local_ip, recv_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 UDP bind local IP: sendto + recvfrom.\n\n");
	if (!init_suite(init_udp_bind_local_ip))
		run_suite(send_udp_local_ip, recvfrom_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 UDP bind any address: sendto + recv.\n\n");
	if (!init_suite(init_udp_any))
		run_suite(send_udp_any, recv_udp);
	end_suite();

	OFP_INFO("\n\nSuite: IPv4 UDP bind any address: sendto + recvfrom.\n\n");
	if (!init_suite(init_udp_bind_any))
		run_suite(send_udp_any, recvfrom_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 UDP bind any address: sendto + recvfrom(NULL addr).\n\n");
	if (!init_suite(init_udp_bind_any))
		run_suite(send_udp_any, recvfrom_udp_null_addr);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP bind local IP: sendto + recv.\n\n");
	if (!init_suite(init_udp6_bind_local_ip))
		run_suite(send_udp6_local_ip, recv_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP bind local IP: sendto + recvfrom.\n\n");
	if (!init_suite(init_udp6_bind_local_ip))
		run_suite(send_udp6_local_ip, recvfrom_udp6);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP bind any IP: sendto + recv.\n\n");
	if (!init_suite(init_udp6_bind_any))
		run_suite(send_udp6_any, recv_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP bind any IP: sendto + recvfrom.\n\n");
	if (!init_suite(init_udp6_bind_any))
		run_suite(send_udp6_any, recvfrom_udp6);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 UDP bind any IP: sendto + recvfrom(NULL addr).\n\n");
	if (!init_suite(init_udp6_bind_any))
		run_suite(send_udp6_any, recvfrom_udp_null_addr);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 TCP socket local IP: listen.\n\n");
	if (!init_suite(init_tcp_bind_local_ip))
		run_suite(listen_tcp, listen_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 TCP socket local IP: listen.\n\n");
	if (!init_suite(init_tcp6_bind_local_ip))
		run_suite(listen_tcp, listen_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 TCP socket local IP: connect + accept.\n\n");
	if (!init_suite(init_tcp_bind_listen_local_ip))
		run_suite(connect_tcp4_local_ip, accept_tcp4);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP socket any IP: connect + accept.\n\n");
	if (!init_suite(init_tcp_bind_listen_any))
		run_suite(connect_tcp4_any, accept_tcp4);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP socket local IP: connect + accept null address.\n\n");
	if (!init_suite(init_tcp_bind_listen_local_ip))
		run_suite(connect_tcp4_local_ip, accept_tcp4_null_addr);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 TCP socket local IP: connect + accept.\n\n");
	if (!init_suite(init_tcp6_bind_listen_local_ip))
		run_suite(connect_tcp6_local_ip, accept_tcp6);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 TCP socket any IP: connect + accept.\n\n");
	if (!init_suite(init_tcp6_bind_listen_any))
		run_suite(connect_tcp6_any, accept_tcp6);
	end_suite();
	OFP_INFO("Test ended.\n");


	OFP_INFO("\n\nSuite: IPv6 TCP socket local IP: connect + accept null address.\n\n");
	if (!init_suite(init_tcp6_bind_listen_local_ip))
		run_suite(connect_tcp6_local_ip, accept_tcp6_null_addr);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 TCP socket local IP: send + recv.\n\n");
	if (!init_suite(init_tcp_bind_listen_local_ip))
		run_suite(send_tcp4_local_ip, receive_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP socket any IP: send + recv.\n\n");
	if (!init_suite(init_tcp_bind_listen_any))
		run_suite(send_tcp4_any, receive_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 TCP socket local IP: send + recv.\n\n");
	if (!init_suite(init_tcp6_bind_listen_local_ip))
		run_suite(send_tcp6_local_ip, receive_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 TCP socket any IP: send + recv.\n\n");
	if (!init_suite(init_tcp6_bind_listen_any))
		run_suite(send_tcp6_any, receive_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 UDP bind local IP: select + recv.\n\n");
	if (!init_suite(init_udp_bind_local_ip))
		run_suite(send_udp_local_ip, select_recv_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 TCP bind local IP: select + accept + recv.\n\n");
	if (!init_suite(init_tcp_bind_listen_local_ip))
		run_suite(send_tcp4_local_ip, select_recv_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP bind local IP: select + recv.\n\n");
	if (!init_suite(init_udp6_bind_local_ip))
		run_suite(send_udp6_local_ip, select_recv_udp);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv6 TCP bind local IP: select + accept + recv.\n\n");
	if (!init_suite(init_tcp6_bind_listen_local_ip))
		run_suite(send_tcp6_local_ip, select_recv_tcp);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 UDP bindlocal IP: select + recv x2.\n\n");
	if (!init_suite(init_udp_bind_local_ip))
		run_suite(send_udp_local_ip, select_recv_udp_2);
	end_suite();
	OFP_INFO("Test ended.\n");

	OFP_INFO("\n\nSuite: IPv4 UDP bind local IP: socket_sigevent rcv.\n\n");
	if (!init_suite(init_udp_bind_local_ip))
		run_suite(recv_send_udp_local_ip, socket_sigevent_udp4);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 UDP bind local IP: socket_sigevent rcv.\n\n");
	if (!init_suite(init_udp6_bind_local_ip))
		run_suite(recv_send_udp6_local_ip, socket_sigevent_udp6);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 TCP bind local IP: socket_sigevent rcv.\n\n");
	if (!init_suite(init_tcp_bind_listen_local_ip))
		run_suite(connect_recv_send_tcp_local_ip, socket_sigevent_tcp_rcv);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 TCP bind local IP: socket_sigevent rcv.\n\n");
	if (!init_suite(init_tcp6_bind_listen_local_ip))
		run_suite(connect_recv_send_tcp6_local_ip, socket_sigevent_tcp_rcv);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	OFP_INFO("\n\nSuite: IPv4 TCP bind local IP: socket_sigevent accept.\n\n");
	if (!init_suite(init_tcp_bind_listen_local_ip))
		run_suite(connect_tcp_delayed_local_ip, socket_sigevent_tcp_accept);
	end_suite();
	OFP_INFO("Test ended.\n");

#ifdef INET6
	OFP_INFO("\n\nSuite: IPv6 TCP bind local IP: socket_sigevent accept.\n\n");
	if (!init_suite(init_tcp6_bind_listen_local_ip))
		run_suite(connect_tcp6_delayed_local_ip,
			socket_sigevent_tcp_accept);
	end_suite();
	OFP_INFO("Test ended.\n");
#endif /*INET6*/

	odph_linux_pthread_join(thread_tbl, num_workers);
	printf("End Main()\n");
	return 0;
}
Exemple #4
0
/**
 * main() Application entry point
 *
 * This is the main function of the FPM application, it's a minimalistic
 * example, see 'usage' function for available arguments and usage.
 *
 * Using the number of available cores as input, this example sets up
 * ODP dispatcher threads executing OFP VLAN processesing and starts
 * a CLI function on a managment core.
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
	appl_args_t params;
	int core_count, num_workers, ret_val;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];
	odph_linux_thr_params_t thr_params;
	odp_instance_t instance;

	/* Parse and store the application arguments */
	if (parse_args(argc, argv, &params) != EXIT_SUCCESS)
		return EXIT_FAILURE;

	if (ofp_sigactions_set(ofp_sig_func_stop)) {
		printf("Error: failed to set signal actions.\n");
		return EXIT_FAILURE;
	}

	/*
	 * Before any ODP API functions can be called, we must first init the ODP
	 * globals, e.g. availale accelerators or software implementations for
	 * shared memory, threads, pool, qeueus, sheduler, pktio, timer, crypto
	 * and classification.
	 */
	if (odp_init_global(&instance, NULL, NULL)) {
		printf("Error: ODP global init failed.\n");
		return EXIT_FAILURE;
	}

	/*
	 * When the gloabel ODP level init has been done, we can now issue a
	 * local init per thread. This must also be done before any other ODP API
	 * calls may be made. Local inits are made here for shared memory,
	 * threads, pktio and scheduler.
	 */
	if (odp_init_local(instance, ODP_THREAD_CONTROL) != 0) {
		printf("Error: ODP local init failed.\n");
		odp_term_global(instance);
		return EXIT_FAILURE;
	}

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	/*
	 * Get the number of cores available to ODP, one run-to-completion thread
	 * will be created per core.
	 */
	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	/*
	 * This example assumes that core #0 runs Linux kernel background tasks.
	 * By default, cores #1 and beyond will be populated with a OFP
	 * processing thread each.
	 */
	memset(&app_init_params, 0, sizeof(app_init_params));

	app_init_params.linux_core_id = 0;

	if (core_count > 1)
		num_workers--;

	/*
	 * Initializes cpumask with CPUs available for worker threads.
	 * Sets up to 'num' CPUs and returns the count actually set.
	 * Use zero for all available CPUs.
	 */
	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	if (odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)) < 0) {
		printf("Error: Too small buffer provided to "
			"odp_cpumask_to_str\n");
		odp_term_local();
		odp_term_global(instance);
		return EXIT_FAILURE;
	}

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;
	app_init_params.pkt_hook[OFP_HOOK_LOCAL] = fastpath_local_hook;

	/*
	 * Now that ODP has been initalized, we can initialize OFP. This will
	 * open a pktio instance for each interface supplied as argument by the
	 * user.
	 *
	 * General configuration will be to pktio and schedluer queues here in
	 * addition will fast path interface configuration.
	 */
	if (ofp_init_global(instance, &app_init_params) != 0) {
		printf("Error: OFP global init failed.\n");
		ofp_term_global();
		odp_term_local();
		odp_term_global(instance);
		return EXIT_FAILURE;
	}

	if (ofp_init_local() != 0) {
		printf("Error: OFP local init failed.\n");
		ofp_term_local();
		ofp_term_global();
		odp_term_local();
		odp_term_global(instance);
		return EXIT_FAILURE;
	}

	/*
	 * Create and launch dataplane dispatcher worker threads to be placed
	 * according to the cpumask, thread_tbl will be populated with the
	 * created pthread IDs.
	 *
	 * In this case, all threads will run the default_event_dispatcher
	 * function with ofp_eth_vlan_processing as argument.
	 *
	 * If different dispatchers should run, or the same be run with differnt
	 * input arguments, the cpumask is used to control this.
	 */
	memset(thread_tbl, 0, sizeof(thread_tbl));
	thr_params.start = default_event_dispatcher;
	thr_params.arg = ofp_eth_vlan_processing;
	thr_params.thr_type = ODP_THREAD_WORKER;
	thr_params.instance = instance;
	ret_val = odph_linux_pthread_create(thread_tbl,
					    &cpumask,
					    &thr_params);
	if (ret_val != num_workers) {
		OFP_ERR("Error: Failed to create worker threads, "
			"expected %d, got %d",
			num_workers, ret_val);
		ofp_stop_processing();
		odph_linux_pthread_join(thread_tbl, num_workers);
		ofp_term_local();
		ofp_term_global();
		odp_term_local();
		odp_term_global(instance);
		return EXIT_FAILURE;
	}

	/*
	 * Now when the ODP dispatcher threads are running, further applications
	 * can be launched, in this case, we will start the OFP CLI thread on
	 * the management core, i.e. not competing for cpu cycles with the
	 * worker threads
	 */
	if (ofp_start_cli_thread(instance, app_init_params.linux_core_id,
		params.conf_file) < 0) {
		OFP_ERR("Error: Failed to init CLI thread");
		ofp_stop_processing();
		odph_linux_pthread_join(thread_tbl, num_workers);
		ofp_term_local();
		ofp_term_global();
		odp_term_local();
		odp_term_global(instance);
		return EXIT_FAILURE;
	}

	/*
	 * If we choose to check performance, a performance monitoring client
	 * will be started on the management core. Once every second it will
	 * read the statistics from the workers from a shared memory region.
	 * Using this has negligible performance impact (<<0.01%).
	 */
	if (params.perf_stat) {
		if (start_performance(instance,
			app_init_params.linux_core_id) <= 0) {
			OFP_ERR("Error: Failed to init performance monitor");
			ofp_stop_processing();
			odph_linux_pthread_join(thread_tbl, num_workers);
			ofp_term_local();
			ofp_term_global();
			odp_term_local();
			odp_term_global(instance);
			return EXIT_FAILURE;
		}
	}

	/*
	 * Wait here until all worker threads have terminated, then free up all
	 * resources allocated by odp_init_global().
	 */
	odph_linux_pthread_join(thread_tbl, num_workers);

	if (ofp_term_local() < 0)
		printf("Error: ofp_term_local failed\n");

	if (ofp_term_global() < 0)
		printf("Error: ofp_term_global failed\n");

	if (odp_term_local() < 0)
		printf("Error: odp_term_local failed\n");

	if (odp_term_global(instance) < 0)
		printf("Error: odp_term_global failed\n");

	printf("FPM End Main()\n");

	return EXIT_SUCCESS;
}
Exemple #5
0
/** main() Application entry point
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_odpthread_t thread_tbl[MAX_WORKERS];
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];
	odph_odpthread_params_t thr_params;
	odp_instance_t instance;

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	if (params.if_count > OFP_FP_INTERFACE_MAX) {
		printf("Error: Invalid number of interfaces: maximum %d\n",
			OFP_FP_INTERFACE_MAX);
		exit(EXIT_FAILURE);
	}

	if (odp_init_global(&instance, NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count && params.core_count < core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	if (core_count > 1)
		num_workers--;

	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	ofp_init_global_param(&app_init_params);
	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;

	if (ofp_init_global(instance, &app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (ofp_init_local()) {
		OFP_ERR("Error: OFP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	build_classifier(app_init_params.if_count, app_init_params.if_names);

	/* Start CLI */
	ofp_start_cli_thread(instance, app_init_params.linux_core_id, params.cli_file);
	sleep(1);

	memset(thread_tbl, 0, sizeof(thread_tbl));
	/* Start dataplane dispatcher worker threads */
	thr_params.start = default_event_dispatcher;
	thr_params.arg = ofp_udp4_processing;
	thr_params.thr_type = ODP_THREAD_WORKER;
	thr_params.instance = instance;
	odph_odpthreads_create(thread_tbl,
			       &cpumask,
			       &thr_params);

	app_processing();

	odph_odpthreads_join(thread_tbl);

	printf("End Main()\n");
	return 0;
}
Exemple #6
0
/** main() Application entry point
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	if (odp_init_global(NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	/*
	 * By default core #0 runs Linux kernel background tasks.
	 * Start mapping thread from core #1
	 */
	memset(&app_init_params, 0, sizeof(app_init_params));

	app_init_params.linux_core_id = 0;

	if (core_count > 1)
		num_workers--;

	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;
	app_init_params.pkt_hook[OFP_HOOK_LOCAL] = fastpath_local_hook;
	if (ofp_init_global(&app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}

	memset(thread_tbl, 0, sizeof(thread_tbl));
	/* Start dataplane dispatcher worker threads */

	ofp_linux_pthread_create(thread_tbl,
				  &cpumask,
				  default_event_dispatcher,
				  ofp_eth_vlan_processing,
				  ODP_THREAD_CONTROL
				);

	/* other app code here.*/
	/* Start CLI */
	ofp_start_cli_thread(app_init_params.linux_core_id, params.conf_file);

	/* sysctl test thread */
	ofp_start_sysctl_thread(app_init_params.linux_core_id);

	odph_linux_pthread_join(thread_tbl, num_workers);
	printf("End Main()\n");

	return 0;
}
static int ofp_lib_start(void)
{
	ofp_init_global_t app_init_params;

	odph_linux_pthread_t thread_tbl[32];
	int ret_val, num_workers = 1;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];

	if (ofp_init_global_called)
		return EXIT_FAILURE;

	/*
	 * Before any ODP API functions can be called, we must first init the ODP
	 * globals, e.g. availale accelerators or software implementations for
	 * shared memory, threads, pool, qeueus, sheduler, pktio, timer, crypto
	 * and classification.
	 */
	if (odp_init_global(NULL, NULL)) {
		OFP_ERR("ODP global init failed.");
		return EXIT_FAILURE;
	}

	/*
	 * When the gloabel ODP level init has been done, we can now issue a
	 * local init per thread. This must also be done before any other ODP API
	 * calls may be made. Local inits are made here for shared memory,
	 * threads, pktio and scheduler.
	 */
	if (odp_init_local(ODP_THREAD_CONTROL) != 0) {
		OFP_ERR("ODP local init failed.");
		odp_term_global();
		return EXIT_FAILURE;
	}

	/*
	 * Initializes cpumask with CPUs available for worker threads.
	 * Sets up to 'num' CPUs and returns the count actually set.
	 * Use zero for all available CPUs.
	 */
	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	if (odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)) < 0) {
		OFP_ERR("Error: Too small buffer provided to "
			"odp_cpumask_to_str");
		odp_term_local();
		odp_term_global();
		return EXIT_FAILURE;
	}

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU: %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:  %s\n", cpumaskstr);

	/*
	 * Now that ODP has been initalized, we can initialize OFP. This will
	 * open a pktio instance for each interface supplied as argument by the
	 * user.
	 *
	 * General configuration will be to pktio and schedluer queues here in
	 * addition will fast path interface configuration.
	 */
	memset(&app_init_params, 0, sizeof(app_init_params));
	if (ofp_init_global(&app_init_params) != 0) {
		OFP_ERR("OFP global init failed.");
		ofp_term_global();
		odp_term_local();
		odp_term_global();
		return EXIT_FAILURE;
	}

	if (ofp_init_local() != 0) {
		OFP_ERR("Error: OFP local init failed.");
		ofp_term_local();
		ofp_term_global();
		odp_term_local();
		odp_term_global();
		return EXIT_FAILURE;
	}


	/*
	 * Create and launch dataplane dispatcher worker threads to be placed
	 * according to the cpumask, thread_tbl will be populated with the
	 * created pthread IDs.
	 *
	 * In this case, all threads will run the default_event_dispatcher
	 * function with ofp_eth_vlan_processing as argument.
	 *
	 * If different dispatchers should run, or the same be run with differnt
	 * input arguments, the cpumask is used to control this.
	 */
	memset(thread_tbl, 0, sizeof(thread_tbl));
	ret_val = ofp_linux_pthread_create(thread_tbl,
			&cpumask,
			default_event_dispatcher,
			ofp_eth_vlan_processing,
			ODP_THREAD_CONTROL);

	if (ret_val != num_workers) {
		OFP_ERR("Error: Failed to create worker threads, "
			"expected %d, got %d",
			num_workers, ret_val);
		ofp_stop_processing();
		odph_linux_pthread_join(thread_tbl, num_workers);
		ofp_term_local();
		ofp_term_global();
		odp_term_local();
		odp_term_global();
		return EXIT_FAILURE;
	}

	ofp_ifconfig();

	return EXIT_SUCCESS;
}
Exemple #8
0
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];
	odph_linux_thr_params_t thr_params;
	odp_instance_t instance;

	struct rlimit rlp;

	getrlimit(RLIMIT_CORE, &rlp);
	printf("RLIMIT_CORE: %ld/%ld\n", rlp.rlim_cur, rlp.rlim_max);
	rlp.rlim_cur = 200000000;
	printf("Setting to max: %d\n", setrlimit(RLIMIT_CORE, &rlp));

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	if (odp_init_global(&instance, NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	/*
	 * By default core #0 runs Linux kernel background tasks.
	 * Start mapping thread from core #1
	 */
	memset(&app_init_params, 0, sizeof(app_init_params));

	app_init_params.linux_core_id = 0;

	if (core_count > 1)
		num_workers--;

	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;
	app_init_params.pkt_hook[OFP_HOOK_LOCAL] = fastpath_local_hook;
	if (ofp_init_global(instance, &app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}

	memset(thread_tbl, 0, sizeof(thread_tbl));
	/* Start dataplane dispatcher worker threads */

	thr_params.start = default_event_dispatcher;
	thr_params.arg = ofp_eth_vlan_processing;
	thr_params.thr_type = ODP_THREAD_WORKER;
	thr_params.instance = instance;
	odph_linux_pthread_create(thread_tbl,
				  &cpumask,
				  &thr_params);

	/* other app code here.*/
	/* Start CLI */
	ofp_start_cli_thread(instance, app_init_params.linux_core_id,
		params.conf_file);

	sleep(2);
	/* webserver */
	if (setup_webserver(params.root_dir, params.laddr, params.lport)) {
		OFP_ERR("Error: Failed to setup webserver.\n");
		exit(EXIT_FAILURE);
	}

	odph_linux_pthread_join(thread_tbl, num_workers);
	printf("End Main()\n");

	return 0;
}
Exemple #9
0
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS], dispatcher_thread;
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpu_mask;
	char cpumaskstr[64];
	int cpu, first_cpu, i;
	struct pktio_thr_arg pktio_thr_args[MAX_WORKERS];

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	if (odp_init_global(NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	odp_init_local(ODP_THREAD_CONTROL);

	memset(&app_init_params, 0, sizeof(app_init_params));
	app_init_params.linux_core_id = 0;
	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;
	app_init_params.burst_recv_mode = 1;

	ofp_init_global(&app_init_params);
	ofp_init_local();

	memset(thread_tbl, 0, sizeof(thread_tbl));
	memset(pktio_thr_args, 0, sizeof(pktio_thr_args));

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count)
		num_workers = params.core_count < core_count?
			params.core_count: core_count;

	first_cpu = 1;
	num_workers -= first_cpu;

	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	if (num_workers < params.if_count) {
		OFP_ERR("At least %u fastpath cores required.\n",
			  params.if_count);
		exit(EXIT_FAILURE);
	}

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", first_cpu);

	for (i = 0; i < num_workers; ++i) {
		pktio_thr_args[i].pkt_func = ofp_eth_vlan_processing;
		pktio_thr_args[i].port = i % params.if_count;

		odp_cpumask_zero(&cpu_mask);
		cpu = first_cpu + i;
		odp_cpumask_set(&cpu_mask, cpu);
		odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));

		OFP_DBG("Starting pktio receive on core: %d port: %d\n",
			  cpu, pktio_thr_args[i].port);
		OFP_DBG("cpu mask: %s\n", cpumaskstr);

		ofp_linux_pthread_create(&thread_tbl[i],
					  &cpu_mask,
					  pkt_io_recv,
					  &pktio_thr_args[i],
					  ODP_THREAD_WORKER
					);
	}

	odp_cpumask_zero(&cpu_mask);
	odp_cpumask_set(&cpu_mask, app_init_params.linux_core_id + 1);
	ofp_linux_pthread_create(&dispatcher_thread,
				  &cpu_mask,
				  event_dispatcher,
				  NULL,
				  ODP_THREAD_CONTROL
				);

	/* Start CLI */
	ofp_start_cli_thread(app_init_params.linux_core_id, params.conf_file);

	sleep(1);

	udp_fwd_cfg(params.sock_count, params.laddr, params.raddr);

	odph_linux_pthread_join(thread_tbl, num_workers);

	printf("End Main()\n");
	return 0;
}
Exemple #10
0
/** main() Application entry point
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS], dispatcher_thread;
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpu_mask;
	int first_cpu, i;
	struct pktio_thr_arg pktio_thr_args[MAX_WORKERS];
	odp_pktio_param_t pktio_param;
	odp_pktin_queue_param_t pktin_param;
	odp_pktout_queue_param_t pktout_param;
	odp_pktio_t pktio;
	int port, queue_id;
	odph_linux_thr_params_t thr_params;
	odp_instance_t instance;

	struct pktin_table_s {
		int	num_in_queue;
		odp_pktin_queue_t in_queue[OFP_PKTIN_QUEUE_MAX];
	} pktin_table[OFP_FP_INTERFACE_MAX];

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	if (params.if_count > OFP_FP_INTERFACE_MAX) {
		printf("Error: Invalid number of interfaces: maximum %d\n",
			OFP_FP_INTERFACE_MAX);
		exit(EXIT_FAILURE);
	}

	if (odp_init_global(&instance, NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count && params.core_count < core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;
	/*
	 * By default core #0 runs Linux kernel background tasks.
	 * Start mapping thread from core #1
	 */
	if (num_workers > 1) {
		num_workers--;
		first_cpu = 1;
	} else {
		OFP_ERR("Burst mode requires multiple cores.\n");
		exit(EXIT_FAILURE);
	}

	if (num_workers < params.if_count) {
		OFP_ERR("At least %u fastpath cores required.\n",
			  params.if_count);
		exit(EXIT_FAILURE);
	}

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", first_cpu);

	memset(&app_init_params, 0, sizeof(app_init_params));
	app_init_params.linux_core_id = 0;

	if (ofp_init_global(instance, &app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (ofp_init_local()) {
		OFP_ERR("Error: OFP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	odp_pktio_param_init(&pktio_param);
	pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT;
	pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;

	odp_pktin_queue_param_init(&pktin_param);
	pktin_param.op_mode = ODP_PKTIO_OP_MT;
	pktin_param.hash_enable = 0;
	pktin_param.hash_proto.all_bits = 0;
	pktin_param.num_queues = 1;

	odp_pktout_queue_param_init(&pktout_param);
	pktout_param.num_queues = 1;
	pktout_param.op_mode = ODP_PKTIO_OP_MT;

	for (i = 0; i < params.if_count; i++) {
		if (ofp_ifnet_create(instance, params.if_names[i],
				&pktio_param,
				&pktin_param,
				&pktout_param) < 0) {
			OFP_ERR("Failed to init interface %s",
				params.if_names[i]);
			exit(EXIT_FAILURE);
		}

		pktio = odp_pktio_lookup(params.if_names[i]);
		if (pktio == ODP_PKTIO_INVALID) {
			OFP_ERR("Failed locate pktio %s",
				params.if_names[i]);
			exit(EXIT_FAILURE);
		}
		pktin_table[i].num_in_queue = odp_pktin_queue(pktio,
			pktin_table[i].in_queue, OFP_PKTIN_QUEUE_MAX);

		if (pktin_table[i].num_in_queue < 0) {
			OFP_ERR("Failed get input queues for %s",
				params.if_names[i]);
			exit(EXIT_FAILURE);
		}
	}

	memset(thread_tbl, 0, sizeof(thread_tbl));
	memset(pktio_thr_args, 0, sizeof(pktio_thr_args));

	for (i = 0; i < num_workers; ++i) {
		pktio_thr_args[i].pkt_func = ofp_eth_vlan_processing;

		port = i % params.if_count;
		queue_id = (i / params.if_count) %
			pktin_table[port].num_in_queue;
		pktio_thr_args[i].pktin = pktin_table[port].in_queue[queue_id];

		odp_cpumask_zero(&cpu_mask);
		odp_cpumask_set(&cpu_mask, first_cpu + i);

		thr_params.start = pkt_io_recv;
		thr_params.arg = &pktio_thr_args[i];
		thr_params.thr_type = ODP_THREAD_WORKER;
		thr_params.instance = instance;
		odph_linux_pthread_create(&thread_tbl[i],
					  &cpu_mask,
					  &thr_params);
	}

	odp_cpumask_zero(&cpu_mask);
	odp_cpumask_set(&cpu_mask, app_init_params.linux_core_id);
	thr_params.start = event_dispatcher;
	thr_params.arg = NULL;
	thr_params.thr_type = ODP_THREAD_WORKER;
	thr_params.instance = instance;
	odph_linux_pthread_create(&dispatcher_thread,
				  &cpu_mask,
				  &thr_params);

	/* Start CLI */
	ofp_start_cli_thread(instance, app_init_params.linux_core_id,
		params.conf_file);

	odph_linux_pthread_join(thread_tbl, num_workers);
	printf("End Main()\n");

	return 0;
}
Exemple #11
0
/** main() Application entry point
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpumask;
	char cpumaskstr[64];

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	if (odp_init_global(NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	core_count = odp_cpu_count();
	num_workers = core_count;

	if (params.core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	if (core_count > 1)
		num_workers--;

#if ODP_VERSION < 104
	num_workers = odp_cpumask_def_worker(&cpumask, num_workers);
#else
	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
#endif
	odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	memset(&app_init_params, 0, sizeof(app_init_params));
	app_init_params.linux_core_id = 0;
	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;

	if (ofp_init_global(&app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (ofp_init_local()) {
		OFP_ERR("Error: OFP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	build_classifier(app_init_params.if_count, app_init_params.if_names);

	/* Start CLI */
	ofp_start_cli_thread(app_init_params.linux_core_id, params.conf_file);
	sleep(1);

	memset(thread_tbl, 0, sizeof(thread_tbl));
	/* Start dataplane dispatcher worker threads */
	odph_linux_pthread_create(thread_tbl,
				  &cpumask,
				  default_event_dispatcher,
				  ofp_udp4_processing);

	app_processing();

	odph_linux_pthread_join(thread_tbl, num_workers);
	printf("End Main()\n");

	return 0;
}
/** main() Application entry point
 *
 * @param argc int
 * @param argv[] char*
 * @return int
 *
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS], dispatcher_thread;
	appl_args_t params;
	int core_count, num_workers;
	odp_cpumask_t cpu_mask;
	char cpumaskstr[64];
	int cpu, first_cpu, i;
	struct pktio_thr_arg pktio_thr_args[MAX_WORKERS];

	/* Parse and store the application arguments */
	parse_args(argc, argv, &params);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &params);

	if (odp_init_global(NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}
	if (odp_init_local(ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	memset(thread_tbl, 0, sizeof(thread_tbl));
	memset(pktio_thr_args, 0, sizeof(pktio_thr_args));

	core_count = odp_cpu_count();
	num_workers = core_count;
	first_cpu = 1;

	if (params.core_count)
		num_workers = params.core_count;
	if (num_workers > MAX_WORKERS)
		num_workers = MAX_WORKERS;

	/*
	 * By default core #0 runs Linux kernel background tasks.
	 * Start mapping thread from core #1
	 */
	memset(&app_init_params, 0, sizeof(app_init_params));

	app_init_params.linux_core_id = 0;

	if (core_count <= 1) {
		OFP_ERR("Burst mode requires multiple cores.\n");
		exit(EXIT_FAILURE);
	}
	num_workers--;

	printf("Num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", first_cpu);

	app_init_params.if_count = params.if_count;
	app_init_params.if_names = params.if_names;
	app_init_params.pkt_hook[OFP_HOOK_LOCAL] = fastpath_local_hook;
	app_init_params.burst_recv_mode = 1;
	if (ofp_init_global(&app_init_params)) {
		OFP_ERR("Error: OFP global init failed.\n");
		exit(EXIT_FAILURE);
	}

	if (num_workers < params.if_count) {
		OFP_ERR("At least %u fastpath cores required.\n",
			  params.if_count);
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < num_workers; ++i) {
		pktio_thr_args[i].pkt_func = ofp_eth_vlan_processing;
		pktio_thr_args[i].port = i % params.if_count;

		odp_cpumask_zero(&cpu_mask);
		cpu = first_cpu + i;
		odp_cpumask_set(&cpu_mask, cpu);
		odp_cpumask_to_str(&cpu_mask, cpumaskstr, sizeof(cpumaskstr));

		OFP_DBG("Starting pktio receive on core: %d port: %d\n",
			  cpu, pktio_thr_args[i].port);
		OFP_DBG("cpu mask: %s\n", cpumaskstr);

		ofp_linux_pthread_create(&thread_tbl[i],
					  &cpu_mask,
					  pkt_io_recv,
					  &pktio_thr_args[i],
					  ODP_THREAD_WORKER
					);
	}

	odp_cpumask_zero(&cpu_mask);
	odp_cpumask_set(&cpu_mask, app_init_params.linux_core_id);
	ofp_linux_pthread_create(&dispatcher_thread,
				  &cpu_mask,
				  event_dispatcher,
				  NULL,
				  ODP_THREAD_CONTROL
				);

	/* other app code here.*/
	/* Start CLI */
	ofp_start_cli_thread(app_init_params.linux_core_id, params.conf_file);

	odph_linux_pthread_join(thread_tbl, num_workers);
	printf("End Main()\n");

	return 0;
}