inline int check_core_task(int lcore_id, int task_id) { if (lcore_id >= RTE_MAX_LCORE) { plog_err("Invalid core id %u (lcore ID above %d)\n", lcore_id, RTE_MAX_LCORE); return 0; } else if (task_id >= lcore_cfg[lcore_id].nb_tasks) { plog_err("Invalid task id (valid task IDs for core %u are below %u)\n", lcore_id, lcore_cfg[lcore_id].nb_tasks); return 0; } return 1; }
static int file_read_cached(const char *file_name, uint8_t **mem, uint32_t beg, uint32_t len, uint32_t socket, struct hash_set *hs) { if (len == 0) { *mem = 0; return 0; } uint8_t *data_mem; /* Since the configuration can reference the same file from multiple places, use prox_shared infrastructure to detect this and return previously loaded data. */ char name[256]; snprintf(name, sizeof(name), "%u-%u:%s", beg, len, file_name); *mem = prox_sh_find_socket(socket, name); if (*mem) return 0; /* check if the file has been loaded on the other socket. */ if (socket == 1 && (data_mem = prox_sh_find_socket(0, name))) { uint8_t *data_find = hash_set_find(hs, data_mem, len); if (!data_find) { data_find = prox_zmalloc(len, socket); PROX_PANIC(data_find == NULL, "Failed to allocate memory (%u bytes) to hold header for peer\n", len); rte_memcpy(data_find, data_mem, len); hash_set_add(hs, data_find, len); } *mem = data_find; prox_sh_add_socket(socket, name, *mem); return 0; } /* It is possible that a file with a different name contains the same data. In that case, search all loaded files and compare the data to reduce memory utilization.*/ data_mem = malloc(len); PROX_PANIC(data_mem == NULL, "Failed to allocate temporary memory to hold data\n"); if (file_read_content(file_name, data_mem, beg, len)) { plog_err("%s\n", file_get_error()); return -1; } uint8_t *data_find = hash_set_find(hs, data_mem, len); if (!data_find) { data_find = prox_zmalloc(len, socket); PROX_PANIC(data_find == NULL, "Failed to allocate memory (%u bytes) to hold header for peer\n", len); rte_memcpy(data_find, data_mem, len); hash_set_add(hs, data_find, len); } free(data_mem); *mem = data_find; prox_sh_add_socket(socket, name, *mem); return 0; }
/* FSM error, unexpected event. This is error of BGP connection. So cut the peer and change to Idle status. */ static int bgp_fsm_event_error (struct peer *peer) { plog_err (peer->log, "%s [FSM] unexpected packet received in state %s", peer->host, LOOKUP (bgp_status_msg, peer->status)); return bgp_stop_with_notify (peer, BGP_NOTIFY_FSM_ERR, 0); }
void display_screen(unsigned screen_id) { if (screen_id >= n_screens) { plog_err("Unsupported screen %d\n", screen_id + 1); return; } if (screen_state.chosen_screen == screen_id) { stats_display_layout(1); } else { screen_state.chosen_screen = screen_id; current_screen = display_screens[screen_id]; stats_display_layout(0); } }
static int lua_to_peer_data(struct lua_State *L, enum lua_place from, const char *name, uint32_t socket, struct peer_data *peer_data, size_t *cl, struct hash_set *hs) { uint32_t hdr_len, hdr_beg, content_len, content_beg; char hdr_file[256], content_file[256]; int pop; if ((pop = lua_getfrom(L, from, name)) < 0) return -1; if (!lua_istable(L, -1)) return -1; if (lua_getfrom(L, TABLE, "header") < 0) return -1; if (lua_to_int(L, TABLE, "len", &hdr_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &hdr_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", hdr_file, sizeof(hdr_file)) < 0) return -1; lua_pop(L, 1); if (lua_getfrom(L, TABLE, "content") < 0) return -1; if (lua_to_int(L, TABLE, "len", &content_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &content_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", content_file, sizeof(content_file)) < 0) return -1; lua_pop(L, 1); if (hdr_len == UINT32_MAX) { long ret = file_get_size(hdr_file); if (ret < 0) { plog_err("%s", file_get_error()); return -1; } hdr_len = ret - hdr_beg; } if (content_len == UINT32_MAX) { long ret = file_get_size(content_file); if (ret < 0) { plog_err("%s", file_get_error()); return -1; } content_len = ret - content_beg; } *cl = content_len; peer_data->hdr_len = hdr_len; if (file_read_cached(hdr_file, &peer_data->hdr, hdr_beg, hdr_len, socket, hs)) return -1; if (file_read_cached(content_file, &peer_data->content, content_beg, content_len, socket, hs)) return -1; lua_pop(L, pop); return 0; }
static int handle_gen_queued(struct task_gen_server *task) { uint8_t out[MAX_PKT_BURST]; struct bundle_ctx *conn; struct pkt_tuple pkt_tuple; struct l4_meta l4_meta; uint16_t j; uint16_t cancelled = 0; int ret; if (task->cur_mbufs_beg == task->cur_mbufs_end) { task->cur_mbufs_end = fqueue_get(task->fqueue, task->cur_mbufs, MAX_PKT_BURST); task->cur_mbufs_beg = 0; } uint16_t n_pkts = task->cur_mbufs_end - task->cur_mbufs_beg; struct rte_mbuf **mbufs = task->cur_mbufs + task->cur_mbufs_beg; j = task->cancelled; if (task->cancelled) { uint16_t pkt_len = mbuf_wire_size(mbufs[0]); if (token_time_take(&task->token_time, pkt_len) != 0) return -1; out[0] = task->out_saved; task->cancelled = 0; } /* Main proc loop */ for (; j < n_pkts; ++j) { if (parse_pkt(mbufs[j], &pkt_tuple, &l4_meta)) { plogdx_err(mbufs[j], "Unknown packet, parsing failed\n"); out[j] = OUT_DISCARD; } conn = NULL; ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple); if (ret >= 0) conn = task->bundle_ctx_pool.hash_entries[ret]; else { /* If not part of existing connection, try to create a connection */ struct new_tuple nt; nt.dst_addr = pkt_tuple.dst_addr; nt.proto_id = pkt_tuple.proto_id; nt.dst_port = pkt_tuple.dst_port; rte_memcpy(nt.l2_types, pkt_tuple.l2_types, sizeof(nt.l2_types)); const struct bundle_cfg *n; if (NULL != (n = server_accept(task, &nt))) { conn = bundle_ctx_pool_get(&task->bundle_ctx_pool); if (!conn) { out[j] = OUT_DISCARD; plogx_err("No more free bundles to accept new connection\n"); continue; } ret = rte_hash_add_key(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple); if (ret < 0) { out[j] = OUT_DISCARD; bundle_ctx_pool_put(&task->bundle_ctx_pool, conn); plog_err("Adding key failed while trying to accept connection\n"); continue; } task->bundle_ctx_pool.hash_entries[ret] = conn; bundle_init_w_cfg(conn, n, task->heap, PEER_SERVER, &task->seed); conn->tuple = pkt_tuple; if (conn->ctx.stream_cfg->proto == IPPROTO_TCP) task->l4_stats.tcp_created++; else task->l4_stats.udp_created++; } else { plog_err("Packet received for service that does not exist :\n" "source ip = %0x:%u\n" "dst ip = %0x:%u\n", pkt_tuple.src_addr, rte_bswap16(pkt_tuple.src_port), pkt_tuple.dst_addr, rte_bswap16(pkt_tuple.dst_port)); } } /* bundle contains either an active connection or a newly created connection. If it is NULL, then not listening. */ if (NULL != conn) { ret = bundle_proc_data(conn, mbufs[j], &l4_meta, &task->bundle_ctx_pool, &task->seed, &task->l4_stats); out[j] = ret == 0? 0: OUT_HANDLED; if (ret == 0) { uint16_t pkt_len = mbuf_wire_size(mbufs[j]); if (token_time_take(&task->token_time, pkt_len) != 0) { task->out_saved = out[j]; task->cancelled = 1; task->base.tx_pkt(&task->base, mbufs, j, out); task->cur_mbufs_beg += j; return -1; } } } else { pkt_tuple_debug(&pkt_tuple); plogd_dbg(mbufs[j], NULL); out[j] = OUT_DISCARD; } } task->base.tx_pkt(&task->base, mbufs, j, out); task->cur_mbufs_beg += j; return 0; }
static int lua_to_peer_data(struct lua_State *L, enum lua_place from, const char *name, uint32_t socket, struct peer_data *peer_data, size_t *cl) { uint32_t hdr_len, hdr_beg, content_len, content_beg; char hdr_file[256], content_file[256]; int pop; if ((pop = lua_getfrom(L, from, name)) < 0) return -1; if (!lua_istable(L, -1)) return -1; if (lua_getfrom(L, TABLE, "header") < 0) return -1; if (lua_to_int(L, TABLE, "len", &hdr_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &hdr_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", hdr_file, sizeof(hdr_file)) < 0) return -1; lua_pop(L, 1); if (lua_getfrom(L, TABLE, "content") < 0) return -1; if (lua_to_int(L, TABLE, "len", &content_len) < 0) return -1; if (lua_to_int(L, TABLE, "beg", &content_beg) < 0) return -1; if (lua_to_string(L, TABLE, "file_name", content_file, sizeof(content_file)) < 0) return -1; lua_pop(L, 1); if (hdr_len == (uint32_t)-1) { char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), hdr_file); FILE *f = fopen(file_name, "r"); long file_beg; if (!f) return -1; fseek(f, hdr_beg, SEEK_SET); file_beg = ftell(f); fseek(f, 0, SEEK_END); hdr_len = ftell(f) - file_beg; fclose(f); } if (content_len == (uint32_t)-1) { char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), content_file); FILE *f = fopen(file_name, "r"); long file_beg; if (!f) return -1; fseek(f, content_beg, SEEK_SET); file_beg = ftell(f); fseek(f, 0, SEEK_END); content_len = ftell(f) - file_beg; fclose(f); } *cl = content_len; peer_data->mem = rte_zmalloc_socket(NULL, hdr_len + content_len, RTE_CACHE_LINE_SIZE, socket); PROX_PANIC(peer_data->mem == NULL, "Failed to allocate memory (%u bytes) to hold headers and contents for peer\n", hdr_len + content_len); peer_data->hdr = peer_data->mem; peer_data->hdr_len = hdr_len; peer_data->content = peer_data->mem + hdr_len; char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), hdr_file); FILE *f = fopen(file_name, "r"); if (!f) { return -1; } fseek(f, hdr_beg, SEEK_SET); size_t ret; ret = fread(peer_data->hdr, 1, hdr_len, f); if ((uint32_t)ret != hdr_len) { plog_err("Failed to read hdr, %zu, %u\n", ret, hdr_len); return -1; } fclose(f); snprintf(file_name, sizeof(file_name), "%s/%s", get_cfg_dir(), content_file); f = fopen(file_name, "r"); if (!f) return -1; fseek(f, content_beg, SEEK_SET); ret = fread(peer_data->content, 1, content_len, f); if ((uint32_t)ret != content_len) { plog_err("Failed to read content, %zu, %u\n", ret, content_len); return -1; } fclose(f); lua_pop(L, pop); return 0; }
static void handle_gen_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts) { struct task_gen_server *task = (struct task_gen_server *)tbase; struct pkt_tuple pkt_tuple[MAX_PKT_BURST]; uint8_t out[MAX_PKT_BURST]; struct l4_meta l4_meta[MAX_PKT_BURST]; struct bundle_ctx *conn; int ret; for (uint16_t j = 0; j < n_pkts; ++j) { if (parse_pkt(mbufs[j], &pkt_tuple[j], &l4_meta[j])) plogdx_err(mbufs[j], "Unknown packet, parsing failed\n"); } /* Main proc loop */ for (uint16_t j = 0; j < n_pkts; ++j) { conn = NULL; ret = rte_hash_lookup(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple[j]); if (ret >= 0) conn = task->bundle_ctx_pool.hash_entries[ret]; /* If not part of existing connection, try to create a connection */ if (NULL == conn) { struct new_tuple nt; nt.dst_addr = pkt_tuple[j].dst_addr; nt.proto_id = pkt_tuple[j].proto_id; nt.dst_port = pkt_tuple[j].dst_port; rte_memcpy(nt.l2_types, pkt_tuple[j].l2_types, sizeof(nt.l2_types)); const struct bundle_cfg *n; if (NULL != (n = server_accept(task, &nt))) { conn = bundle_ctx_pool_get(&task->bundle_ctx_pool); if (!conn) { out[j] = NO_PORT_AVAIL; plogx_err("No more free bundles to accept new connection\n"); continue; } ret = rte_hash_add_key(task->bundle_ctx_pool.hash, (const void *)&pkt_tuple[j]); if (ret < 0) { out[j] = NO_PORT_AVAIL; bundle_ctx_pool_put(&task->bundle_ctx_pool, conn); plog_err("Adding key failed while trying to accept connection\n"); continue; } task->bundle_ctx_pool.hash_entries[ret] = conn; bundle_init(conn, n, task->heap, PEER_SERVER, &task->seed); conn->tuple = pkt_tuple[j]; if (conn->ctx.stream_cfg->proto == IPPROTO_TCP) task->l4_stats.tcp_created++; else task->l4_stats.udp_created++; } } /* bundle contains either an active connection or a newly created connection. If it is NULL, then not listening. */ if (NULL != conn) { int ret = bundle_proc_data(conn, mbufs[j], &l4_meta[j], &task->bundle_ctx_pool, &task->seed, &task->l4_stats); out[j] = ret == 0? 0: NO_PORT_AVAIL; } else { plog_err("Packet received for service that does not exist\n"); pkt_tuple_debug(&pkt_tuple[j]); plogd_dbg(mbufs[j], NULL); out[j] = NO_PORT_AVAIL; } } conn = NULL; task->base.tx_pkt(&task->base, mbufs, n_pkts, out); if (!(task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap))) return ; if (task->n_new_mbufs < MAX_PKT_BURST) { if (rte_mempool_get_bulk(task->mempool, (void **)task->new_mbufs, MAX_PKT_BURST - task->n_new_mbufs) < 0) { return ; } for (uint32_t i = 0; i < MAX_PKT_BURST - task->n_new_mbufs; ++i) { init_mbuf_seg(task->new_mbufs[i]); } task->n_new_mbufs = MAX_PKT_BURST; } if (task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap)) { uint16_t n_called_back = 0; while (task->heap->n_elems && rte_rdtsc() > heap_peek_prio(task->heap) && n_called_back < MAX_PKT_BURST) { conn = BUNDLE_CTX_UPCAST(heap_pop(task->heap)); /* handle packet TX (retransmit or delayed transmit) */ ret = bundle_proc_data(conn, task->new_mbufs[n_called_back], NULL, &task->bundle_ctx_pool, &task->seed, &task->l4_stats); if (ret == 0) { out[n_called_back] = 0; n_called_back++; } } task->base.tx_pkt(&task->base, task->new_mbufs, n_called_back, out); task->n_new_mbufs -= n_called_back; } }
/* This function is the first starting point of all BGP connection. It try to connect to remote peer with non-blocking IO. */ int bgp_start (struct peer *peer) { int status; if (BGP_PEER_START_SUPPRESSED (peer)) { if (BGP_DEBUG (fsm, FSM)) plog_err (peer->log, "%s [FSM] Trying to start suppressed peer" " - this is never supposed to happen!", peer->host); return -1; } /* Scrub some information that might be left over from a previous, * session */ /* Connection information. */ if (peer->su_local) { sockunion_free (peer->su_local); peer->su_local = NULL; } if (peer->su_remote) { sockunion_free (peer->su_remote); peer->su_remote = NULL; } /* Clear remote router-id. */ peer->remote_id.s_addr = 0; /* Clear peer capability flag. */ peer->cap = 0; /* If the peer is passive mode, force to move to Active mode. */ if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)) { BGP_EVENT_ADD (peer, TCP_connection_open_failed); return 0; } status = bgp_connect (peer); switch (status) { case connect_error: if (BGP_DEBUG (fsm, FSM)) plog_debug (peer->log, "%s [FSM] Connect error", peer->host); BGP_EVENT_ADD (peer, TCP_connection_open_failed); break; case connect_success: if (BGP_DEBUG (fsm, FSM)) plog_debug (peer->log, "%s [FSM] Connect immediately success", peer->host); BGP_EVENT_ADD (peer, TCP_connection_open); break; case connect_in_progress: /* To check nonblocking connect, we wait until socket is readable or writable. */ if (BGP_DEBUG (fsm, FSM)) plog_debug (peer->log, "%s [FSM] Non blocking connect waiting result", peer->host); if (peer->fd < 0) { zlog_err ("bgp_start peer's fd is negative value %d", peer->fd); return -1; } BGP_READ_ON (peer->t_read, bgp_read, peer->fd); BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); break; } return 0; }
/** * Parse open option. * * @param[out] mp_capability @see bgp_capability_parse() for semantics. */ int bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability) { int ret; u_char *error; u_char error_data[BGP_MAX_PACKET_SIZE]; struct stream *s = BGP_INPUT(peer); size_t end = stream_get_getp (s) + length; ret = 0; error = error_data; if (BGP_DEBUG (normal, NORMAL)) zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u", peer->host, length); while (stream_get_getp(s) < end) { u_char opt_type; u_char opt_length; /* Must have at least an OPEN option header */ if (STREAM_READABLE(s) < 2) { zlog_info ("%s Option length error", peer->host); bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0); return -1; } /* Fetch option type and length. */ opt_type = stream_getc (s); opt_length = stream_getc (s); /* Option length check. */ if (STREAM_READABLE (s) < opt_length) { zlog_info ("%s Option length error", peer->host); bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0); return -1; } if (BGP_DEBUG (normal, NORMAL)) zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u", peer->host, opt_type, opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" : opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown", opt_length); switch (opt_type) { case BGP_OPEN_OPT_AUTH: ret = bgp_auth_parse (peer, opt_length); break; case BGP_OPEN_OPT_CAP: ret = bgp_capability_parse (peer, opt_length, mp_capability, &error); break; default: bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_PARAM); ret = -1; break; } /* Parse error. To accumulate all unsupported capability codes, bgp_capability_parse does not return -1 when encounter unsupported capability code. To detect that, please check error and erro_data pointer, like below. */ if (ret < 0) return -1; } /* All OPEN option is parsed. Check capability when strict compare flag is enabled.*/ if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) { /* If Unsupported Capability exists. */ if (error != error_data) { bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data, error - error_data); return -1; } /* Check local capability does not negotiated with remote peer. */ if (! strict_capability_same (peer)) { bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL); return -1; } } /* Check there are no common AFI/SAFIs and send Unsupported Capability error. */ if (*mp_capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) { if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST] && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST] && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]) { plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do not " "overlap with received MP capabilities", peer->host); if (error != error_data) bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data, error - error_data); else bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL); return -1; } } return 0; }
/* Parse open option */ int bgp_open_option_parse (struct peer *peer, u_char length, int *capability) { int ret; u_char *end; u_char opt_type; u_char opt_length; u_char *pnt; u_char *error; u_char error_data[BGP_MAX_PACKET_SIZE]; /* Fetch pointer. */ pnt = stream_pnt (peer->ibuf); ret = 0; opt_type = 0; opt_length = 0; end = pnt + length; error = error_data; if (BGP_DEBUG (normal, NORMAL)) zlog_info ("%s rcv OPEN w/ OPTION parameter len: %u", peer->host, length); while (pnt < end) { /* Check the length. */ if (pnt + 2 > end) { zlog_info ("%s Option length error", peer->host); bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0); return -1; } /* Fetch option type and length. */ opt_type = *pnt++; opt_length = *pnt++; /* Option length check. */ if (pnt + opt_length > end) { zlog_info ("%s Option length error", peer->host); bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0); return -1; } if (BGP_DEBUG (normal, NORMAL)) zlog_info ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u", peer->host, opt_type, opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" : opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown", opt_length); switch (opt_type) { case BGP_OPEN_OPT_AUTH: ret = bgp_auth_parse (peer, pnt, opt_length); break; case BGP_OPEN_OPT_CAP: ret = bgp_capability_parse (peer, pnt, opt_length, &error); *capability = 1; break; default: bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_PARAM); ret = -1; break; } /* Parse error. To accumulate all unsupported capability codes, bgp_capability_parse does not return -1 when encounter unsupported capability code. To detect that, please check error and erro_data pointer, like below. */ if (ret < 0) return -1; /* Forward pointer. */ pnt += opt_length; } /* All OPEN option is parsed. Check capability when strict compare flag is enabled.*/ if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) { /* If Unsupported Capability exists. */ if (error != error_data) { bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data, error - error_data); return -1; } /* Check local capability does not negotiated with remote peer. */ if (! strict_capability_same (peer)) { bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL); return -1; } } /* Check there is no common capability send Unsupported Capability error. */ if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) { if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST] && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST] && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]) { plog_err (peer->log, "%s [Error] No common capability", peer->host); if (error != error_data) bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data, error - error_data); else bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSUP_CAPBL); return -1; } } return 0; }
void process_input(int* needs_refresh, const char *str, int fd, void (*cb)(int fd, const char *data, size_t len)) { static unsigned lcore_id, task_id, nb_packets, val, id, port, queue, rate, ip[4], prefix, next_hop_idx, interface, gre_id, svlan, cvlan, mac[6], user; unsigned count; float speed; uint32_t pkt_size; static char mode[20]; struct rte_ring *ring; unsigned short offset; uint32_t value; uint8_t value_len; if (strcmp(str, "quit") == 0) { plog_info("Leaving...\n"); stop_core_all(); stop_dppd = 1; } else if (sscanf(str, "dump %u %u %u", &lcore_id, &task_id, &nb_packets) == 3) { if (lcore_id >= RTE_MAX_LCORE) { plog_err("Invalid core id %u (lcore ID above %d)\n", lcore_id, RTE_MAX_LCORE); } else if (!dppd_core_active(lcore_id, 0)) { plog_err("Invalid core id %u (lcore is not active)\n", lcore_id); } else { cmd_dump(lcore_id, task_id, nb_packets); } } else if (sscanf(str, "rate %u %u %u", &queue, &port, &rate) == 3) { if (port > DPPD_MAX_PORTS) { plog_err("Max port id allowed is %u (specified %u)\n", DPPD_MAX_PORTS, port); } else if (!dppd_port_cfg[port].active) { plog_err("Port %u not active\n", port); } else if (queue >= dppd_port_cfg[port].n_txq) { plog_err("Number of active queues is %u\n", dppd_port_cfg[port].n_txq); } else if (rate > dppd_port_cfg[port].link_speed) { plog_err("Max rate allowed on port %u queue %u is %u Mbps\n", port, queue, dppd_port_cfg[port].link_speed); } else { if (rate == 0) { plog_info("Disabling rate limiting on port %u queue %u\n", port, queue); } else { plog_info("Setting rate limiting to %u Mbps on port %u queue %u\n", rate, port, queue); } rte_eth_set_queue_rate_limit(port, queue, rate); } } else if (sscanf(str, "count %u %u %u", &lcore_id, &task_id, &count) == 3) { if (check_core_task(lcore_id, task_id)) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen")) { plog_err("Core %u task %u is not generating packets\n", lcore_id, task_id); } else { ((struct task_gen *)lcore_cfg[lcore_id].task[task_id])->pkt_count = count; plog_info("Core %u task %u stopping after %u packets\n", lcore_id, task_id, count); } } } else if (sscanf(str, "pkt_size %u %u %d", &lcore_id, &task_id, &pkt_size) == 3) { if (check_core_task(lcore_id, task_id)) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen")) { plog_err("Core %u task %u is not generating packets\n", lcore_id, task_id); } else if (pkt_size > 1514 || pkt_size < 34) { // 34 for 14 + 20 (MAC, EtherType and IP) plog_err("pkt_size out of range (must be betweeen 34 and 1514)\n"); } else { ((struct task_gen *)lcore_cfg[lcore_id].task[task_id])->pkt_size = pkt_size; plog_info("Setting pkt_size to %u \n", pkt_size); } } } else if (sscanf(str, "speed %u %u %f", &lcore_id, &task_id, &speed) == 3) { if (check_core_task(lcore_id, task_id)) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen")) { plog_err("Core %u task %u is not generating packets\n", lcore_id, task_id); } else if (speed > 100.0f || speed < 0.0f) { plog_err("Speed out of range (must be betweeen 0%% and 100%%)\n"); } else { uint64_t bps = speed * 12500000; ((struct task_gen *)lcore_cfg[lcore_id].task[task_id])->rate_bps = bps; plog_info("Setting rate to %"PRIu64" Bps\n", bps); } } } else if (sscanf(str, "speed_byte %u %u %u", &lcore_id, &task_id, &value) == 3) { if (check_core_task(lcore_id, task_id)) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen")) { plog_err("Core %u task %u is not generating packets\n", lcore_id, task_id); } else if (value > 1250000000) { plog_err("Speed out of range (must be <= 1250000000)\n"); } else { ((struct task_gen *)lcore_cfg[lcore_id].task[task_id])->rate_bps = value; plog_info("Setting rate to %"PRIu32" Bps\n", value); } } } else if (strcmp(str, "reset values all") == 0) { lcore_id = -1; while (dppd_core_next(&lcore_id, 0) == 0) { for (task_id = 0; task_id < lcore_cfg[lcore_id].nb_tasks; task_id++) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen") == 0) { struct task_gen *task = ((struct task_gen *)lcore_cfg[lcore_id].task[task_id]); plog_info("Resetting values on core %d task %d from %d values\n", lcore_id, task_id, task->n_values); task->n_values = 0; } } } } else if (sscanf(str, "reset values %u %u", &lcore_id, &task_id) == 2) { if (check_core_task(lcore_id, task_id)) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen")) { plog_err("Core %u task %u is not generating packets\n", lcore_id, task_id); } else { struct task_gen *task = ((struct task_gen *)lcore_cfg[lcore_id].task[task_id]); plog_info("Resetting values on core %d task %d from %d values\n", lcore_id, task_id, task->n_values); task->n_values = 0; } } } else if (sscanf(str, "set value %u %u %hu %u %hhu", &lcore_id, &task_id, &offset, &value, &value_len) == 5) { if (check_core_task(lcore_id, task_id)) { if (strcmp(lcore_cfg[lcore_id].targs[task_id].task_init->mode_str, "gen")) { plog_err("Core %u task %u is not generating packets\n", lcore_id, task_id); } else if (offset > ETHER_MAX_LEN) { plog_err("Offset out of range (must be less then %u)\n", ETHER_MAX_LEN); } else if (value_len > 4) { plog_err("Length out of range (must be less then 4)\n"); } else { struct task_gen *task = ((struct task_gen *)lcore_cfg[lcore_id].task[task_id]); if (task->n_values >= 64) { plog_info("Unable to set Byte %"PRIu16" to %"PRIu8" - too many value set\n", offset, value); } else { task->value[task->n_values] = rte_cpu_to_be_32(value) >> ((4 - value_len) * 8); task->offset[task->n_values] = offset; task->value_len[task->n_values] = value_len; task->n_values++; plog_info("Setting Byte %"PRIu16" to %"PRIu32"\n", offset, value); } } } } else if (sscanf(str, "thread info %u %u", &lcore_id, &task_id) == 2) {