/* * Should receive timeouts only */ static void *event_dispatcher(void *arg) { odp_event_t ev; (void)arg; ofp_init_local(); while (1) { ev = odp_schedule(NULL, ODP_SCHED_WAIT); if (ev == ODP_EVENT_INVALID) continue; if (odp_event_type(ev) == ODP_EVENT_TIMEOUT) { ofp_timer_handle(ev); continue; } OFP_ERR("Error: unexpected event type: %u\n", odp_event_type(ev)); odp_buffer_free(odp_buffer_from_event(ev)); } /* Never reached */ return NULL; }
static void *perf_client(void *arg) { (void) arg; #if ODP_VERSION < 106 if (odp_init_local(ODP_THREAD_CONTROL) != 0) { OFP_ERR("Error: ODP local init failed.\n"); return NULL; } #endif if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } ofp_set_stat_flags(OFP_STAT_COMPUTE_PERF); while (1) { struct ofp_perf_stat *ps = ofp_get_perf_statistics(); printf ("Mpps:%4.3f\n", ((float)ps->rx_fp_pps)/1000000); usleep(1000000UL); } return NULL; }
static void *suite_thread2(void *arg) { run_function run_func = (run_function)arg; if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } (void)run_func(fd_thread2); return NULL; }
static void *pkt_io_recv(void *arg) { odp_pktio_t pktio; odp_packet_t pkt, pkt_tbl[OFP_PKT_BURST_SIZE]; int pkt_idx, pkt_cnt; struct pktio_thr_arg *thr_args; ofp_pkt_processing_func pkt_func; thr_args = arg; pkt_func = thr_args->pkt_func; if (odp_init_local(ODP_THREAD_WORKER)) { OFP_ERR("Error: ODP local init failed.\n"); return NULL; } if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } pktio = ofp_port_pktio_get(thr_args->port); OFP_DBG("PKT-IO receive starting on port: %d, pktio-id: %"PRIX64"\n", thr_args->port, odp_pktio_to_u64(pktio)); while (1) { pkt_cnt = odp_pktio_recv(pktio, pkt_tbl, OFP_PKT_BURST_SIZE); for (pkt_idx = 0; pkt_idx < pkt_cnt; pkt_idx++) { pkt = pkt_tbl[pkt_idx]; if (odp_unlikely(odp_packet_has_error(pkt))) { OFP_DBG("Packet with error dropped.\n"); odp_packet_free(pkt); continue; } ofp_packet_input(pkt, ODP_QUEUE_INVALID, pkt_func); } #ifdef OFP_SEND_PKT_BURST ofp_send_pending_pkt_burst(); #endif /*OFP_SEND_PKT_BURST*/ } /* Never reached */ return NULL; }
static int webserver(void *arg) { int serv_fd, tmp_fd; struct ofp_sockaddr_in my_addr; (void)arg; OFP_INFO("HTTP thread started"); if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return -1; } sleep(1); myaddr = ofp_port_get_ipv4_addr(0, 0, OFP_PORTCONF_IP_TYPE_IP_ADDR); if ((serv_fd = ofp_socket(OFP_AF_INET, OFP_SOCK_STREAM, OFP_IPPROTO_TCP)) < 0) { OFP_ERR("ofp_socket failed"); perror("serv socket"); return -1; } memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = OFP_AF_INET; my_addr.sin_port = odp_cpu_to_be_16(2048); my_addr.sin_addr.s_addr = myaddr; my_addr.sin_len = sizeof(my_addr); if (ofp_bind(serv_fd, (struct ofp_sockaddr *)&my_addr, sizeof(struct ofp_sockaddr)) < 0) { OFP_ERR("Cannot bind http socket (%s)!", ofp_strerror(ofp_errno)); return -1; } ofp_listen(serv_fd, 10); #ifndef USE_EPOLL OFP_INFO("Using ofp_select"); ofp_fd_set read_fd; OFP_FD_ZERO(&read_fd); int nfds = serv_fd; #else OFP_INFO("Using ofp_epoll"); int epfd = ofp_epoll_create(1); struct ofp_epoll_event e = { OFP_EPOLLIN, { .fd = serv_fd } };
static void test_arp(void) { struct ofp_ifnet mock_ifnet; struct in_addr ip; uint8_t mac[OFP_ETHER_ADDR_LEN] = { 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, }; /* The buffer passed into ofp_ipv4_lookup_mac() must be 8 bytes since * a 64-bit operation is currently being used to copy a MAC address. */ uint8_t mac_result[OFP_ETHER_ADDR_LEN + 2]; CU_ASSERT(0 == ofp_init_local()); memset(&mock_ifnet, 0, sizeof(mock_ifnet)); CU_ASSERT(0 != inet_aton("1.1.1.1", &ip)); /* Test entry insert, lookup, and remove. */ CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet)); memset(mac_result, 0xFF, OFP_ETHER_ADDR_LEN); CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); CU_ASSERT(0 == memcmp(mac, mac_result, OFP_ETHER_ADDR_LEN)); CU_ASSERT(0 == ofp_arp_ipv4_remove(ip.s_addr, &mock_ifnet)); CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); /* Test entry is aged out. */ CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet)); OFP_INFO("Inserted ARP entry"); sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT); CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); /* Test entry is aged out after a few hits. */ CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet)); OFP_INFO("Inserted ARP entry"); sleep(ARP_AGE_INTERVAL); CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); sleep(ARP_AGE_INTERVAL); CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT); CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); }
static void *pkt_io_recv(void *arg) { odp_pktin_queue_t pktin; odp_packet_t pkt, pkt_tbl[PKT_BURST_SIZE]; int pkt_idx, pkt_cnt; struct pktio_thr_arg *thr_args; ofp_pkt_processing_func pkt_func; thr_args = arg; pkt_func = thr_args->pkt_func; pktin = thr_args->pktin; if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } OFP_DBG("PKT-IO receive starting on cpu: %d", odp_cpu_id()); while (1) { pkt_cnt = odp_pktin_recv(pktin, pkt_tbl, PKT_BURST_SIZE); for (pkt_idx = 0; pkt_idx < pkt_cnt; pkt_idx++) { pkt = pkt_tbl[pkt_idx]; if (odp_unlikely(odp_packet_has_error(pkt))) { OFP_DBG("Packet with error dropped.\n"); odp_packet_free(pkt); continue; } ofp_packet_input(pkt, ODP_QUEUE_INVALID, pkt_func); } ofp_send_pending_pkt(); } /* Never reached */ return NULL; }
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(¶ms); 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, ¶ms); ofp_init_local(); init_ifnet(); ofp_add_mac(dev, tun_rem_ip, tun_rem_mac); return 0; }
void *pp_thread(void *arg) { ALLOW_UNUSED_LOCAL(arg); if (ofp_init_local()) { OFP_ERR("ofp_init_local failed"); return NULL; } while (odp_atomic_load_u32(&still_running)) { odp_event_t event; odp_queue_t source_queue; event = odp_schedule(&source_queue, ODP_SCHED_WAIT); if (odp_event_type(event) != ODP_EVENT_TIMEOUT) { OFP_ERR("Unexpected event type %d", odp_event_type(event)); continue; } ofp_timer_handle(event); } return NULL; }
void *pp_thread(void *arg) { ALLOW_UNUSED_LOCAL(arg); #if ODP_VERSION >= 102 if (odp_init_local(ODP_THREAD_WORKER)) { #else if (odp_init_local()) { #endif OFP_ERR("odp_init_local failed"); return NULL; } if (ofp_init_local()) { OFP_ERR("ofp_init_local failed"); return NULL; } while (odp_atomic_load_u32(&still_running)) { odp_event_t event; odp_queue_t source_queue; event = odp_schedule(&source_queue, ODP_SCHED_WAIT); if (odp_event_type(event) != ODP_EVENT_TIMEOUT) { OFP_ERR("Unexpected event type %d", odp_event_type(event)); continue; } ofp_timer_handle(event); } return NULL; } static void test_arp(void) { struct ofp_ifnet mock_ifnet; struct in_addr ip; uint8_t mac[OFP_ETHER_ADDR_LEN] = { 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, }; /* The buffer passed into ofp_ipv4_lookup_mac() must be 8 bytes since * a 64-bit operation is currently being used to copy a MAC address. */ uint8_t mac_result[OFP_ETHER_ADDR_LEN + 2]; CU_ASSERT(0 == ofp_init_local()); memset(&mock_ifnet, 0, sizeof(mock_ifnet)); CU_ASSERT(0 != inet_aton("1.1.1.1", &ip)); /* Test entry insert, lookup, and remove. */ CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet)); memset(mac_result, 0xFF, OFP_ETHER_ADDR_LEN); CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); CU_ASSERT(0 == memcmp(mac, mac_result, OFP_ETHER_ADDR_LEN)); CU_ASSERT(0 == ofp_arp_ipv4_remove(ip.s_addr, &mock_ifnet)); CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); /* Test entry is aged out. */ CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet)); OFP_INFO("Inserted ARP entry"); sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT); CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); /* Test entry is aged out after a few hits. */ CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet)); OFP_INFO("Inserted ARP entry"); sleep(ARP_AGE_INTERVAL); CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); sleep(ARP_AGE_INTERVAL); CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT); CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet)); } int main(void) { CU_pSuite ptr_suite = NULL; int nr_of_failed_tests = 0; int nr_of_failed_suites = 0; /* Initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) return CU_get_error(); /* add a suite to the registry */ ptr_suite = CU_add_suite("ofp errno", init_suite, end_suite); if (NULL == ptr_suite) { CU_cleanup_registry(); return CU_get_error(); } if (NULL == CU_ADD_TEST(ptr_suite, test_arp)) { CU_cleanup_registry(); return CU_get_error(); } #if defined(OFP_TESTMODE_AUTO) CU_set_output_filename("CUnit-Util"); CU_automated_run_tests(); #else /* Run all tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); #endif nr_of_failed_tests = CU_get_number_of_tests_failed(); nr_of_failed_suites = CU_get_number_of_suites_failed(); CU_cleanup_registry(); return (nr_of_failed_suites > 0 ? nr_of_failed_suites : nr_of_failed_tests); }
/** 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, ¶ms); 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]), ¶ms); 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; }
/** 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, ¶ms); /* Print both system and application information */ print_info(NO_PATH(argv[0]), ¶ms); 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; }
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; }
static void *webserver(void *arg) { int serv_fd, tmp_fd, nfds; unsigned int alen; struct ofp_sockaddr_in my_addr, caller; ofp_fd_set read_fd; (void)arg; OFP_INFO("HTTP thread started"); if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } sleep(1); myaddr = ofp_port_get_ipv4_addr(0, 0, OFP_PORTCONF_IP_TYPE_IP_ADDR); if ((serv_fd = ofp_socket(OFP_AF_INET, OFP_SOCK_STREAM, OFP_IPPROTO_TCP)) < 0) { OFP_ERR("ofp_socket failed"); perror("serv socket"); return NULL; } memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = OFP_AF_INET; my_addr.sin_port = odp_cpu_to_be_16(2048); my_addr.sin_addr.s_addr = myaddr; my_addr.sin_len = sizeof(my_addr); if (ofp_bind(serv_fd, (struct ofp_sockaddr *)&my_addr, sizeof(struct ofp_sockaddr)) < 0) { OFP_ERR("Cannot bind http socket (%s)!", ofp_strerror(ofp_errno)); return 0; } ofp_listen(serv_fd, 10); OFP_FD_ZERO(&read_fd); nfds = serv_fd; for ( ; ; ) { int r, i; static char buf[1024]; struct ofp_timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 200000; OFP_FD_SET(serv_fd, &read_fd); monitor_connections(&read_fd); r = ofp_select(nfds + 1, &read_fd, NULL, NULL, &timeout); if (r <= 0) continue; if (OFP_FD_ISSET(serv_fd, &read_fd)) { alen = sizeof(caller); if ((tmp_fd = ofp_accept(serv_fd, (struct ofp_sockaddr *)&caller, &alen)) > 0) { OFP_INFO("accept fd=%d", tmp_fd); for (i = 0; i < NUM_CONNECTIONS; i++) if (connections[i].fd == 0) break; if (i >= NUM_CONNECTIONS) { OFP_ERR("Node cannot accept new connections!"); ofp_close(tmp_fd); continue; } #if 0 struct ofp_linger so_linger; so_linger.l_onoff = 1; so_linger.l_linger = 0; int r1 = ofp_setsockopt(tmp_fd, OFP_SOL_SOCKET, OFP_SO_LINGER, &so_linger, sizeof so_linger); if (r1) OFP_ERR("SO_LINGER failed!"); #endif struct ofp_timeval tv; tv.tv_sec = 3; tv.tv_usec = 0; int r2 = ofp_setsockopt(tmp_fd, OFP_SOL_SOCKET, OFP_SO_SNDTIMEO, &tv, sizeof tv); if (r2) OFP_ERR("SO_SNDTIMEO failed!"); connections[i].fd = tmp_fd; connections[i].addr = caller.sin_addr.s_addr; connections[i].closed = FALSE; if (tmp_fd > nfds) nfds = tmp_fd; } } for (i = 0; i < NUM_CONNECTIONS; i++) { if (connections[i].fd == 0) continue; if (!(OFP_FD_ISSET(connections[i].fd, &read_fd))) continue; r = ofp_recv(connections[i].fd, buf, sizeof(buf)-1, 0); if (r > 0) { buf[r] = 0; OFP_INFO("recv data: %s", buf); if (!strncmp(buf, "GET", 3)) analyze_http(buf, connections[i].fd); else OFP_INFO("Not a HTTP GET request"); OFP_INFO("closing %d\n", connections[i].fd); OFP_FD_CLR(connections[i].fd, &read_fd); while (ofp_close(connections[i].fd) < 0) { OFP_ERR("ofp_close failed, fd=%d err='%s'", connections[i].fd, ofp_strerror(ofp_errno)); sleep(1); } OFP_INFO("closed fd=%d", connections[i].fd); connections[i].fd = 0; } else if (r == 0) { if (connections[i].post) { OFP_INFO("File download finished"); fclose(connections[i].post); connections[i].post = NULL; } ofp_close(connections[i].fd); OFP_FD_CLR(connections[i].fd, &read_fd); connections[i].fd = 0; } } } OFP_INFO("httpd exiting"); return NULL; }
static void * sysctl(void *arg) { (void)arg; if (odp_init_local(ODP_THREAD_CONTROL)) { OFP_ERR("Error: ODP local init failed.\n"); return NULL; } if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } sleep(2); /* * Variables may be visible per thread. Addresses of the shared * variables are not known at compile time. Also sometimes it may be * necessary to create OIDs dynamically. * * Add an OID dynamically to the existing compile time * created branch: */ static int created; OFP_SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_mybranch), OFP_OID_AUTO, "created", OFP_CTLFLAG_RW, &created, 0, "Dynamically created"); /* * Create a branch dynamically: */ struct ofp_sysctl_oid *dyn_root; dyn_root = OFP_SYSCTL_ADD_NODE (NULL, SYSCTL_STATIC_CHILDREN(_mybranch), OFP_OID_AUTO, "subbranch", OFP_CTLFLAG_RW, 0, "Dynamically created branch"); /* * Add a variable to that, for example one from the shared memory. * Here we use a static integer. */ static int shared; OFP_SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(dyn_root), OFP_OID_AUTO, "shared", OFP_CTLFLAG_RW, &shared, 0, "Shared memory variable"); /* * Our branch is complete: * * 73 mybranch RW Node (My test branch) * 256 hello RW string (Hello message) * 261 ssh RW Node (Ssh control) * 257 counter R int64_t (Ssh counter) * 259 enabled RW int (Enable ssh protocol) * 262 telnet RW Node (Telnet control) * 258 counter R int64_t (Telnet counter) * 260 enabled RW int (Enable telnet protocol) * 328 created RW int (Dynamically created) * 329 subbranch RW Node (Dynamically created branch) * 330 shared RW int (Shared memory variable) */ /* * Use created variables. First set some meaningful values: */ telnet_bytes = 123456; ssh_bytes = 567890; strcpy(hello_msg, "Hello, world!"); /* * There are several functions to access MIB data. Simplest one * is the following: * * ofp_sysctl(const char *name, void *old, size_t *oldlenp, * const void *new, size_t newlen, size_t *retval) * * name: OID using string notation (like "net.inet.udp.checksum"). * old: Pointer to memory where old value will be saved. * Can be NULL. * oldlenp: Pointer to variable whose value is the result space * in bytes. Will be updated to the real space. * new: Pointer to the new value. Can be NULL. * newlen: Size of the new value in bytes or zero. * retval: Pointer to a variable that will be set to * response's length. */ /* * Read the telnet bytes: */ uint64_t counter; size_t counterlen = sizeof(counter); size_t retval; ofp_sysctl("mybranch.telnet.counter", &counter, &counterlen, NULL, 0, &retval); OFP_INFO("mybranch.telnet.counter=%"PRIu64" len=%zu retval=%zu\n", counter, counterlen, retval); /* * Read the ssh bytes: */ ofp_sysctl("mybranch.ssh.counter", &counter, &counterlen, NULL, 0, &retval); OFP_INFO("mybranch.ssh.counter=%"PRIu64" len=%zu retval=%zu\n", counter, counterlen, retval); /* * Check if telnet is enabled: */ int enabled; size_t enalen = sizeof(enabled); ofp_sysctl("mybranch.telnet.enabled", &enabled, &enalen, NULL, 0, &retval); OFP_INFO("mybranch.telnet.enabled=%d\n", enabled); /* * Disable telnet: */ enabled = 0; ofp_sysctl("mybranch.telnet.enabled", NULL, 0, &enabled, sizeof(enabled), &retval); /* * Check if that worked. Init variable with something to ensure it is * really changed: */ enabled = 123; enalen = sizeof(enabled); ofp_sysctl("mybranch.telnet.enabled", &enabled, &enalen, NULL, 0, &retval); OFP_INFO("After disabling: mybranch.telnet.enabled=%d, real value=%d\n", enabled, enable_telnet); /* * Read and change the hello message: */ char msg[32]; size_t msglen = sizeof(msg); ofp_sysctl("mybranch.hello", msg, &msglen, "Server is down.", 16, &retval); OFP_INFO("mybranch.hello: old value=%s, new value=%s\n", msg, hello_msg); /* * Make telnet connection to local address port 2345. * Try commands: * sysctl dump * sysctl r mybranch.ssh.counter * sysctl w mybranch.ssh.enabled 1 * sysctl w mybranch.ssh.counter 777 */ while (1) sleep(1); return NULL; }
static void *mcasttest(void *arg) { int fd; struct ofp_sockaddr_in my_addr; struct ofp_ip_mreq mreq; (void)arg; logprint("Multicast thread started\n"); if (odp_init_local(ODP_THREAD_CONTROL)) { OFP_ERR("Error: ODP local init failed.\n"); return NULL; } if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } sleep(1); while (myaddr == 0) { myaddr = ofp_port_get_ipv4_addr(0, 0, OFP_PORTCONF_IP_TYPE_IP_ADDR); sleep(1); } if ((fd = ofp_socket(OFP_AF_INET, OFP_SOCK_DGRAM, OFP_IPPROTO_UDP)) < 0) { perror("socket"); logprint("Cannot open socket!\n"); return NULL; } memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = OFP_AF_INET; my_addr.sin_port = odp_cpu_to_be_16(2048); my_addr.sin_addr.s_addr = 0; my_addr.sin_len = sizeof(my_addr); if (ofp_bind(fd, (struct ofp_sockaddr *)&my_addr, sizeof(struct ofp_sockaddr)) < 0) { logprint("Cannot bind socket (%s)!\n", ofp_strerror(ofp_errno)); return NULL; } memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,5,5,5); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,7,7,7); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } for (;;) { char buf[100]; int len = sizeof(buf); struct ofp_sockaddr_in addr = {0}; ofp_socklen_t addr_len = 0; len = ofp_recvfrom(fd, buf, len, 0, (struct ofp_sockaddr *)&addr, &addr_len); if (len == -1) { OFP_ERR("Faild to rcv data(errno = %d)\n", ofp_errno); continue; } buf[len] = 0; OFP_INFO("Data (%s, len = %d) was received.\n", buf, len); if (addr_len != sizeof(addr)) { OFP_ERR("Faild to rcv source address: %d (errno = %d)\n", addr_len, ofp_errno); continue; } if (strstr(buf, "add")) { OFP_INFO("Add membership to 234.7.7.7\n"); memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,7,7,7); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } } else if (strstr(buf, "drop")) { OFP_INFO("Drop membership from 234.7.7.7\n"); memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,7,7,7); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } } else if (strstr(buf, "quit")) { exit(0); } OFP_INFO("Data was received from address 0x%x, port = %d.\n", odp_be_to_cpu_32(addr.sin_addr.s_addr), odp_be_to_cpu_16(addr.sin_port)); sprintf(buf, "%d bytes\n", len); if (ofp_sendto(fd, buf, strlen(buf), 0, (struct ofp_sockaddr *)&addr, sizeof(addr)) == -1) { OFP_ERR("Faild to send data (errno = %d)\n", ofp_errno); } } logprint("mcast exit\n"); return NULL; }
/** 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, ¶ms); 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]), ¶ms); 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; }
/** * 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, ¶ms) != 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]), ¶ms); /* * 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; }
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, ¶ms); /* Print both system and application information */ print_info(NO_PATH(argv[0]), ¶ms); 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; }
int default_event_dispatcher(void *arg) { odp_event_t ev; odp_packet_t pkt; odp_queue_t in_queue; int event_idx = 0; int event_cnt = 0; ofp_pkt_processing_func pkt_func = (ofp_pkt_processing_func)arg; odp_bool_t *is_running = NULL; if (ofp_init_local()) { OFP_ERR("ofp_init_local failed"); return -1; } int rx_burst = global_param->evt_rx_burst_size; odp_event_t events[rx_burst]; is_running = ofp_get_processing_state(); if (is_running == NULL) { OFP_ERR("ofp_get_processing_state failed"); ofp_term_local(); return -1; } /* PER CORE DISPATCHER */ while (*is_running) { event_cnt = odp_schedule_multi(&in_queue, ODP_SCHED_WAIT, events, rx_burst); for (event_idx = 0; event_idx < event_cnt; event_idx++) { odp_event_type_t ev_type; ev = events[event_idx]; if (ev == ODP_EVENT_INVALID) continue; ev_type = odp_event_type(ev); if (odp_likely(ev_type == ODP_EVENT_PACKET)) { pkt = odp_packet_from_event(ev); #if 0 if (odp_unlikely(odp_packet_has_error(pkt))) { OFP_DBG("Dropping packet with error"); odp_packet_free(pkt); continue; } #endif ofp_packet_input(pkt, in_queue, pkt_func); continue; } if (ev_type == ODP_EVENT_TIMEOUT) { ofp_timer_handle(ev); continue; } OFP_ERR("Unexpected event type: %u", ev_type); odp_event_free(ev); } ofp_send_pending_pkt(); } if (ofp_term_local()) OFP_ERR("ofp_term_local failed"); return 0; }
void *default_event_dispatcher(void *arg) { odp_event_t ev; odp_packet_t pkt; odp_queue_t in_queue; odp_event_t events[OFP_EVT_RX_BURST_SIZE]; int event_idx = 0; int event_cnt = 0; ofp_pkt_processing_func pkt_func = (ofp_pkt_processing_func)arg; odp_bool_t *is_running = NULL; #if ODP_VERSION < 106 if (odp_init_local(ODP_THREAD_WORKER)) { OFP_ERR("odp_init_local failed"); return NULL; } #endif if (ofp_init_local()) { OFP_ERR("ofp_init_local failed"); return NULL; } is_running = ofp_get_processing_state(); if (is_running == NULL) { OFP_ERR("ofp_get_processing_state failed"); ofp_term_local(); return NULL; } /* PER CORE DISPATCHER */ while (*is_running) { event_cnt = odp_schedule_multi(&in_queue, ODP_SCHED_WAIT, events, OFP_EVT_RX_BURST_SIZE); for (event_idx = 0; event_idx < event_cnt; event_idx++) { ev = events[event_idx]; if (ev == ODP_EVENT_INVALID) continue; if (odp_event_type(ev) == ODP_EVENT_TIMEOUT) { ofp_timer_handle(ev); continue; } if (odp_event_type(ev) == ODP_EVENT_PACKET) { pkt = odp_packet_from_event(ev); #if 0 if (odp_unlikely(odp_packet_has_error(pkt))) { OFP_DBG("Dropping packet with error"); odp_packet_free(pkt); continue; } #endif ofp_packet_input(pkt, in_queue, pkt_func); continue; } OFP_ERR("Unexpected event type: %u", odp_event_type(ev)); /* Free events by type */ if (odp_event_type(ev) == ODP_EVENT_BUFFER) { odp_buffer_free(odp_buffer_from_event(ev)); continue; } if (odp_event_type(ev) == ODP_EVENT_CRYPTO_COMPL) { odp_crypto_compl_free( odp_crypto_compl_from_event(ev)); continue; } } ofp_send_pending_pkt(); } if (ofp_term_local()) OFP_ERR("ofp_term_local failed"); return NULL; }