Merged PR 4175621: Update netsh program commands

Update to use improved error messages like the other netsh commands.

Signed-off-by: Dave Thaler <dthaler@ntdev.microsoft.com>
This commit is contained in:
Dave Thaler 2021-03-03 04:39:52 +00:00
Родитель 9a475b6170 344505bbb1
Коммит b87da5d4ab
4 изменённых файлов: 456 добавлений и 438 удалений

Просмотреть файл

@ -42,7 +42,6 @@ static char * allocate_error_string(const std::string& str)
static int analyze(raw_program& raw_prog, char ** error_message)
{
std::ostringstream oss;
const ebpf_platform_t* platform = &g_ebpf_platform_windows;
std::variant<InstructionSeq, std::string> prog_or_error = unmarshal(raw_prog, platform);
@ -50,12 +49,19 @@ static int analyze(raw_program& raw_prog, char ** error_message)
*error_message = allocate_error_string(std::get<std::string>(prog_or_error));
return 1; // Error;
}
auto& prog = std::get<InstructionSeq>(prog_or_error);
cfg_t cfg = prepare_cfg(prog, raw_prog.info, true);
InstructionSeq& prog = std::get<InstructionSeq>(prog_or_error);
// First try optimized for the success case.
ebpf_verifier_options_t options = ebpf_verifier_default_options;
options.print_failures = true;
bool res = run_ebpf_analysis(oss, cfg, raw_prog.info, &options);
options.check_termination = true;
bool res = ebpf_verify_program(std::cout, prog, raw_prog.info, &options);
if (!res) {
// On failure, retry to get the more detailed error message.
std::ostringstream oss;
options.no_simplify = true;
options.print_failures = true;
(void)ebpf_verify_program(oss, prog, raw_prog.info, &options);
*error_message = allocate_error_string(oss.str());
return 1; // Error;
}

Просмотреть файл

@ -148,17 +148,15 @@ static int create_map_function(uint32_t type, uint32_t key_size, uint32_t value_
_ebpf_operation_create_map_reply reply{};
auto retval = invoke_ioctl(device_handle, &request, &reply);
DWORD retval = invoke_ioctl(device_handle, &request, &reply);
if (retval != ERROR_SUCCESS)
{
printf("invoke_ioctl returning %d\n", retval);
return -1;
throw std::runtime_error(std::string("Error ") + std::to_string(retval) + " trying to create map");
}
if (reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP)
{
printf("reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP\n");
return -1;
throw std::runtime_error(std::string("reply.header.id != ebpf_operation_id_t::EBPF_OPERATION_CREATE_MAP"));
}
// TODO: Replace this with the CRT helper to create FD from handle once we have real handles.
@ -167,12 +165,22 @@ static int create_map_function(uint32_t type, uint32_t key_size, uint32_t value_
return _map_file_descriptors.size();
}
static map_cache_t& get_map_cache_entry(uint64_t map_fd)
{
return _map_file_descriptors[map_fd - 1];
}
static EbpfMapDescriptor& get_map_descriptor(int map_fd)
{
return get_map_cache_entry(map_fd - 1).ebpf_map_descriptor;
}
static uint64_t map_resolver(void* context, uint64_t fd)
{
_ebpf_operation_resolve_map_request request{
sizeof(request),
ebpf_operation_id_t::EBPF_OPERATION_RESOLVE_MAP,
_map_file_descriptors[fd-1].handle };
get_map_cache_entry(fd).handle };
_ebpf_operation_resolve_map_reply reply;
@ -228,7 +236,7 @@ DLL DWORD ebpf_api_load_program(const char* file_name, const char* section_name,
{
_map_file_descriptors.resize(0);
// Verify code.
if (verify(file_name, section_name, byte_code.data(), &byte_code_size, create_map_function, [](int fd) -> EbpfMapDescriptor& { return _map_file_descriptors[fd - 1].ebpf_map_descriptor; }, error_message) != 0)
if (verify(file_name, section_name, byte_code.data(), &byte_code_size, create_map_function, get_map_descriptor, error_message) != 0)
{
return ERROR_INVALID_PARAMETER;
}

Просмотреть файл

@ -273,6 +273,7 @@ DWORD handle_ebpf_show_verification(
}
ebpf_verifier_options_t verifier_options = ebpf_verifier_default_options;
verifier_options.check_termination = true;
verifier_options.print_failures = true;
std::vector<raw_program> raw_programs;
try {

Просмотреть файл

@ -60,7 +60,7 @@ unsigned long handle_ebpf_add_program(
tag_type);
std::string filename;
std::string section = ".text";
std::string section = ""; // Use the first code section by default.
EBPF_PROGRAM_TYPE type = EBPF_PROGRAM_TYPE_XDP;
PINNED_CONSTRAINT pinned = PINNED_ANY;
for (int i = 0; (status == NO_ERROR) && ((i + current_index) < argc); i++) {
@ -116,18 +116,21 @@ unsigned long handle_ebpf_add_program(
char* error_message = nullptr;
status = ebpf_api_load_program(filename.c_str(), section.c_str(), &_program_handle, &error_message);
if (status != ERROR_SUCCESS)
{
std::cerr << "ebpf_api_load_program failed with error " << status << " and message " << error_message << std::endl;
return status;
if (error_message != nullptr) {
std::cerr << error_message << std::endl;
} else {
std::cerr << "error " << status << ": could not load program" << std::endl;
}
return ERROR_SUPPRESS_OUTPUT;
}
status = ebpf_api_attach_program(_program_handle, type);
if (status != ERROR_SUCCESS)
{
std::cerr << "ebpf_api_attach_program failed with error " << status << std::endl;
return status;
std::cerr << "error " << status << ": could not attach program" << std::endl;
return ERROR_SUPPRESS_OUTPUT;
}
return ERROR_SUCCESS;
}
@ -158,7 +161,7 @@ DWORD handle_ebpf_delete_program(
tag_type);
std::string filename;
std::string section = ".text";
std::string section = ""; // Use the first code section by default.
for (int i = 0; (status == NO_ERROR) && ((i + current_index) < argc); i++) {
switch (tag_type[i]) {
case 0: // FILENAME
@ -217,7 +220,7 @@ DWORD handle_ebpf_set_program(
tag_type);
std::string filename;
std::string section = ".text";
std::string section = ""; // Use the first code section by default.
PINNED_CONSTRAINT pinned = PINNED_ANY;
for (int i = 0; (status == NO_ERROR) && ((i + current_index) < argc); i++) {
switch (tag_type[i]) {