ucli_status_t vt_ucli_module__ppedump__(ucli_context_t* uc) { int count = 0; UCLI_COMMAND_INFO(uc, "ppedump", 1, "$summary#PPE dump all packets on the given VPI." "$args#<vpi_spec>"); UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}", &vtc->vpi); while(1) { if(vpi_recv__(uc, vtc) > 0) { ppe_packet_t ppep; ppe_packet_init(&ppep, vtc->data, vtc->size); if(ppe_parse(&ppep) < 0) { ucli_printf(uc, "[%.3d] recv(%{vpi}):\n%{data}\n", count, vtc->vpi, vtc->data, vtc->size); } else { ucli_printf(uc, "[%.3d] recv(%{vpi}):\n", count, vtc->vpi); ppe_packet_dump(&ppep, &uc->pvs); } count++; } else { break; } } return UCLI_STATUS_OK; }
ucli_status_t vt_ucli_module__echo__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "echo", 2, "$summary#Send a VPI echo request." "$args#<vpi_spec> <data>"); UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}{idata}", &vtc->vpi, vtc->data, &vtc->size); ucli_printf(uc, "sending echo request.\n"); if(vpi_ioctl(vtc->vpi, VPI_PROTOCOL_OPCODE_ECHO, vtc->data, vtc->size) < 0) { return ucli_error(uc, "vpi_ioctl() failed."); } ucli_printf(uc, "waiting for response.\n"); memset(vtc->data, 0, sizeof(vtc->data)); if(vpi_recv__(uc, vtc) > 0) { ucli_printf(uc, "recv(%{vpi}):\n%{data}", vtc->vpi, vtc->data, vtc->size); return UCLI_STATUS_OK; } else { return UCLI_STATUS_E_ERROR; } }
int ucli_verror(ucli_context_t* uc, const char* fmt, va_list vargs) { if( (uc->flags & UCLI_CONTEXT_F_SILENT) == 0) { ucli_printf(uc, "error: "); ucli_vprintf(uc, fmt, vargs); ucli_printf(uc, "\n"); } return UCLI_STATUS_E_ERROR; }
int ucli_e_internal(ucli_context_t* uc, const char* fmt, ...) { va_list vargs; va_start(vargs, fmt); ucli_printf(uc, "internal error: "); ucli_vprintf(uc, fmt, vargs); ucli_printf(uc, "\n"); return UCLI_STATUS_E_INTERNAL; }
ucli_status_t vt_ucli_module__perf__(ucli_context_t* uc) { uint64_t last; uint64_t now; double seconds; uint64_t deltat = 2000000; int count = 0; int direction; uint8_t data[128] = {0}; int misscount = 0; int pid = 0; UCLI_COMMAND_INFO(uc, "perf", 2, "$summary#Receive performance test." "$args#[send|recv] vpi"); UCLI_ARGPARSE_OR_RETURN(uc, "{choice}{vpi}", &direction, "direction", 2, "send", "recv", &vtc->vpi); count = 0; last = os_time_monotonic(); while(1) { if(direction == 0) { /* send */ *(uint32_t*)(data) = pid++; vpi_send(vtc->vpi, data, sizeof(data)); count++; } else { /* recv */ if(vpi_recv__(uc, vtc) > 0) { uint32_t rpid = *(uint32_t*)(vtc->data); if(pid != rpid) { misscount += (rpid - pid); pid = rpid+1; } else { pid++; } count++; } } now = os_time_monotonic(); if((now - last) > deltat) { seconds = 1.0*(now-last)/1000000; ucli_printf(uc, "%d packets %s in %f seconds (%f pps) missed=%d\n", count, direction ? "received" : "sent", seconds, count/seconds, misscount); count=0; last = now; misscount=0; } } return UCLI_STATUS_OK; }
static ucli_status_t ppe_ucli_utm__dump__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "dump", 0, "Dump raw packet contents."); ucli_printf(uc, "%{data}", ppec->ppep.data, ppec->ppep.size); return UCLI_STATUS_OK; }
static ucli_status_t socketmanager_ucli_ucli__foo__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "foo", 0, "$summary#test command."); ucli_printf(uc, "foo command issued\n"); return UCLI_STATUS_OK; }
static ucli_status_t socketmanager_ucli_ucli__config__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "config", 0, "$summary#config command."); ucli_printf(uc, "todo: support config command\n"); return UCLI_STATUS_OK; }
static ucli_status_t utest_ucli_options__add3__(ucli_context_t* uc) { int n[3] = {0,0,0}; UCLI_COMMAND_INFO(uc, "add3", 3, "Add three numbers together."); UCLI_ARGPARSE_OR_RETURN(uc, "iii", n, n+1, n+2); ucli_printf(uc, "sum=%d\n", n[0]+n[1]+n[2]); return UCLI_STATUS_OK; }
static ucli_status_t ppe_ucli_utm__fdump__(ucli_context_t* uc) { ppe_field_t field; ppe_header_t format; UCLI_COMMAND_INFO(uc, "fdump", 0, "Dump all packet fields."); ppe_packet_format_get(&ppec->ppep, &format); ucli_printf(uc, "format=%{ppe_header}, size=%d\n", format, ppec->ppep.size); for(field = 0; field < PPE_FIELD_COUNT; field++) { const ppe_field_info_t* fi = ppe_field_info_get(field); if(fi->size_bits == 0) { continue; } if(ppe_field_exists(&ppec->ppep, field) == 0) { continue; } if(fi->size_bits <= 32) { uint32_t data; ppe_field_get(&ppec->ppep, field, &data); ucli_printf(uc, "%{ppe_field} = 0x%x (%d)\n", field, data, data); } else { uint8_t* p = ppe_fieldp_get(&ppec->ppep, field); ucli_printf(uc, "%{ppe_field} = %{data}\n", field, p, fi->size_bits/8); } } return UCLI_STATUS_OK; }
static int vpi_recv__(ucli_context_t* uc, vt_ctrl_t* vtc) { while(1) { vtc->size = vpi_recv(vtc->vpi, vtc->data, sizeof(vtc->data), 1); if(vtc->size == 0) { continue; } if(vtc->size < 0) { ucli_printf(uc, "vpi_recv(%{vpi}) returned %d\n", vtc->vpi, vtc->size); } return vtc->size; } }
static ucli_status_t ppe_ucli_utm__get__(ucli_context_t* uc) { ppe_field_info_t* fi; UCLI_COMMAND_INFO(uc, "get", 1, "Get a packet field."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_field_info}", &fi); PPE_FIELD_EXISTS_OR_RETURN(uc, fi->field); if(fi->size_bits <= 32) { uint32_t value; PPE_FIELD_GET_OR_RETURN(uc, &ppec->ppep, fi->field, &value); ucli_printf(uc, "%{ppe_field} = 0x%x (%d)\n", fi->field, value, value); return UCLI_STATUS_OK; } else { int rv; int size = fi->size_bits/8; uint8_t* data = aim_zmalloc(size); rv = ppe_wide_field_get(&ppec->ppep, fi->field, data); if(rv < 0) { ucli_e_internal(uc, "ppe_wide_field_get(%{ppe_field})", fi->field); } else { ucli_printf(uc, "%{ppe_field} = %{data}\n", data, size); } aim_free(data); return rv; } }
static ucli_status_t ppe_ucli_utm__listf__(ucli_context_t* uc) { ppe_field_info_t* fi; UCLI_COMMAND_INFO(uc, "listf", 0, "List known packet fields."); for(fi = ppe_field_info_table; fi->field != -1; fi++) { if(fi->size_bits != 0) { ucli_printf(uc, "%{ppe_field} sizebits=%d offset=%d shiftbits=%d\n", fi->field, fi->size_bits, fi->offset_bytes, fi->shift_bits); } } return UCLI_STATUS_OK; }
static ucli_status_t utest_ucli_options__ptest__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "ptest", 0, "Run the print test."); ucli_printf(uc, "None\n"); ucli_printf(uc, "%s:%d\n", __FILE__, __LINE__); ucli_printf(uc, "boolean(1)=%{bool}\n", 1); ucli_printf(uc, "boolean(0)=%{bool}\n", 0); ucli_printf(uc, "IPv4 Address=%{ipv4a}\n", 0x0A10FE02); ucli_printf(uc, "%s %d %{bool} %p %{ipv4a} %d\n", "String1", 1, 0, 0x1, 0x0A10FE02, 10); ucli_printf(uc, "%*s %*.*d %{bool}\n", 6, "X", 1, 2, 3, 1); ucli_printf(uc, "%{ip4conn}\n", "123.343.2.4", 0x10010); return UCLI_STATUS_OK; }
static ucli_status_t debug_counter_ucli_ucli__show__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "show", -1, "$summary#show all debug counters."); const char *prefix = NULL; if (uc->pargs->count > 0) { UCLI_ARGPARSE_OR_RETURN(uc, "s", &prefix); } list_head_t *counters = debug_counter_list(); list_links_t *cur; LIST_FOREACH(counters, cur) { debug_counter_t *counter = container_of(cur, links, debug_counter_t); if (prefix_match(counter->name, prefix)) { ucli_printf(uc, "%s: %"PRIu64"\n", counter->name, counter->value); } }
ucli_status_t vt_ucli_module__sendrecv__(ucli_context_t* uc) { UCLI_COMMAND_INFO(uc, "sendrecv", 2, "$summary#Send a single packet on the given VPI and wait for a response." "$args#<vpi_spec> <packet_data>"); vtc->size = sizeof(vtc->data); UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}{idata}", &vtc->vpi, vtc->data, &vtc->size); if(vpi_send(vtc->vpi, vtc->data, vtc->size) < 0) { return ucli_error(uc, "vpi_send() failed."); } if(vpi_recv__(uc, vtc) > 0) { ucli_printf(uc, "recv(%{vpi}):\n%{data}", vtc->vpi, vtc->data, vtc->size); return UCLI_STATUS_OK; } else { return UCLI_STATUS_E_ERROR; } }
ucli_status_t vt_ucli_module__spam__(ucli_context_t* uc) { aim_ratelimiter_t counter_rl; aim_ratelimiter_t send_rl; int count = 0; int last = 0; int pps = -1; UCLI_COMMAND_INFO(uc, "spam", 3, "$summary#Spam packet data on the given VPI." "$args#<vpi_spec> <packet_data> <pps>"); UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}{idata}i", &vtc->vpi, vtc->data, &vtc->size, &pps); aim_ratelimiter_init(&counter_rl, 1000000, 0, NULL); aim_ratelimiter_init(&send_rl, 1000000/pps, 0, NULL); for(;;) { uint64_t now = os_time_monotonic(); if(aim_ratelimiter_limit(&counter_rl, now) == 0) { ucli_printf(uc, "Sent %d packets - %d pps\n", count, (count - last)); last = count; } if(aim_ratelimiter_limit(&send_rl, now) == 0) { if(vpi_send(vtc->vpi, vtc->data, vtc->size) < 0) { return ucli_error(uc, "vpi_send() failed."); } count++; } else { os_sleep_usecs(1); } } return UCLI_STATUS_OK; }
ucli_status_t vt_ucli_module__dump__(ucli_context_t* uc) { int count = 0; UCLI_COMMAND_INFO(uc, "dump", 1, "$summary#Dump all packets on the given VPI." "$args#<vpi_spec>"); UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}", &vtc->vpi); while(1) { if(vpi_recv__(uc, vtc) > 0) { ucli_printf(uc, "[%.3d] recv(%{vpi}):\n%{data}\n", count++, vtc->vpi, vtc->data, vtc->size); } else { break; } } return UCLI_STATUS_OK; }
ucli_status_t vt_ucli_module__bridge__(ucli_context_t* uc) { vpi_t v1, v2; vpi_bridge_t vbridge; UCLI_COMMAND_INFO(uc, "bridge", 2, "$summary#Forward all packets between two VPI interfaces." "$args#<vpi_spec_1> <vpi_spec_2>"); UCLI_ARGPARSE_OR_RETURN(uc, "{vpi}{vpi}", &v1, &v2); vbridge = vpi_bridge_create(v1, v2); if(vbridge == NULL) { return ucli_error(uc, "vpi_bridge_create(%{vpi},%{vpi}) failed.", v1, v2); } if(vpi_bridge_start(vbridge) < 0) { return ucli_error(uc, "vpi_bridge_start() failed."); } vtc->bridges++; ucli_printf(uc, "bridging %s <-> %s\n", vpi_name_get(v1), vpi_name_get(v2)); return UCLI_STATUS_OK; }
static ucli_status_t fme_ucli_utm__perf__(ucli_context_t* uc) { int set_keymask; int table_size; int iterations; int i; fme_key_t mkey; fme_entry_t* match; fme_t* fme; double seconds; int keysize; uint64_t start, end; UCLI_COMMAND_INFO(uc, "perf", 3, "$summary#Run performance matching tests." "$args#<table_size> <iterations> <use_keymask>"); if(aim_valgrind_status() == 1) { ucli_printf(uc, "Skipping performance test while running under valgrind.\n"); return UCLI_STATUS_OK; } UCLI_ARGPARSE_OR_RETURN(uc, "iib", &table_size, &iterations, &set_keymask); fme_create(&fme, "fme_utm", table_size); keysize = sizeof(mkey.values); for(i = 0; i < table_size; i++) { fme_entry_t* entry; fme_key_t key; uint8_t byte = (i == 0 || i & 0xFF) ? i : 0x1; FME_MEMSET(&key, 0, sizeof(key)); FME_MEMSET(&key.values, byte, sizeof(key.values)); FME_MEMSET(&key.masks, byte, sizeof(key.masks)); key.size = keysize; if(set_keymask) { key.keymask = i; } fme_entry_create(&entry); fme_entry_key_set(entry, &key); entry->prio=i; fme_add_entry(fme, entry); } FME_MEMSET(&mkey, 0, sizeof(mkey)); mkey.size = keysize; start = os_time_thread(); for(i = 0; i < iterations; i++) { int rv = fme_match(fme, &mkey, 0, 0, NULL, NULL, &match); /* The lowest priority entry will always match */ if(rv != 1 || match->index != table_size-1){ return ucli_printf(uc, "i=%d error: rv=%d, index=%d\n", i, rv, (match) ? match->index : -1); } } end = os_time_thread(); seconds = (end - start) / (1000.0*1000); ucli_printf(uc, "%d matches in %f seconds (%f matches/sec)\n", iterations, seconds, iterations/seconds); fme_destroy_all(fme); return UCLI_STATUS_OK; }
static ucli_status_t ppe_ucli_utm__dfk__(ucli_context_t* uc) { ppe_dfk_t dfk; ppe_field_t fields[4]; uint8_t* verify_data; unsigned int verify_data_size; int rv = UCLI_STATUS_OK; unsigned int i; UCLI_COMMAND_INFO(uc, "dfk", AIM_ARRAYSIZE(fields)+1, "Generate and verify a dynamic field key."); UCLI_ARGPARSE_OR_RETURN(uc, "{ppe_field}{ppe_field}{ppe_field}{ppe_field}{data}", fields+0, fields+1, fields+2, fields+3, &verify_data, &verify_data_size); ppe_dfk_init(&dfk, fields, AIM_ARRAYSIZE(fields)); i = ppe_packet_dfk(&ppec->ppep, &dfk); if(i != verify_data_size) { rv = ucli_error(uc, "dfk size is %d, verify data size is %d", i, verify_data_size); goto dfk_error; } for(i = 0; i < AIM_ARRAYSIZE(fields); i++) { const ppe_field_info_t* fi = ppe_field_info_get(fields[i]); int exists = ppe_field_exists(&ppec->ppep, fi->field); if(exists && ( (dfk.mask & (1<<i)) == 0)) { /* Should be in the field key but isn't.*/ rv = ucli_error(uc, "%{ppe_field} exists in packet but not in field key.", fi->field); goto dfk_error; } if(!(exists) && (dfk.mask & (1<<i))) { /* Should not be in the field key but is. */ rv = ucli_error(uc, "%{ppe_field} is in the key but not the packet.", fi->field); goto dfk_error; } } for(i = 0; i < verify_data_size; i++) { if(verify_data[i] != dfk.data[i]) { rv = ucli_error(uc, "key data mismatch at byte %d.\nkey=%{data}, verify=%{data}", i, dfk.data, verify_data_size, verify_data, verify_data_size); goto dfk_error; } } for(i = 0; i < AIM_ARRAYSIZE(fields); i++) { if(dfk.mask & (1<<i)) { const ppe_field_info_t* fi = ppe_field_info_get(fields[i]); if(fi->size_bits <= 32) { uint32_t pdata; uint32_t kdata; ppe_field_get(&ppec->ppep, fi->field, &pdata); ppe_dfk_field_get(&dfk, fi->field, &kdata); if(pdata != kdata) { rv = ucli_error(uc, "field_get mismatch: p=0x%x, k=0x%x"); goto dfk_error; } } else { unsigned int i; uint8_t pdata[128]; uint8_t kdata[128]; ppe_wide_field_get(&ppec->ppep, fi->field, pdata); ppe_dfk_wide_field_get(&dfk, fi->field, kdata); for(i = 0; i < fi->size_bits/8; i++) { if(pdata[i] != kdata[i]) { rv = ucli_error(uc, "wide_field_get mismatch @ %d: p=0x%x k=0x%x", i, pdata[i], kdata[i]); goto dfk_error; } } } } } aim_free(verify_data); ppe_dfk_destroy(&dfk); return UCLI_STATUS_OK; dfk_error: ucli_printf(uc, "key: "); ppe_dfk_show(&dfk, &uc->pvs); ppe_dfk_destroy(&dfk); aim_free(verify_data); ucli_printf(uc, "\n"); return rv; }