18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 28c2ecf20Sopenharmony_ci/* Copyright (C) 2020 Facebook, Inc. */ 38c2ecf20Sopenharmony_ci#include <stdlib.h> 48c2ecf20Sopenharmony_ci#include <errno.h> 58c2ecf20Sopenharmony_ci#include "testing_helpers.h" 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ciint parse_num_list(const char *s, bool **num_set, int *num_set_len) 88c2ecf20Sopenharmony_ci{ 98c2ecf20Sopenharmony_ci int i, set_len = 0, new_len, num, start = 0, end = -1; 108c2ecf20Sopenharmony_ci bool *set = NULL, *tmp, parsing_end = false; 118c2ecf20Sopenharmony_ci char *next; 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci while (s[0]) { 148c2ecf20Sopenharmony_ci errno = 0; 158c2ecf20Sopenharmony_ci num = strtol(s, &next, 10); 168c2ecf20Sopenharmony_ci if (errno) 178c2ecf20Sopenharmony_ci return -errno; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci if (parsing_end) 208c2ecf20Sopenharmony_ci end = num; 218c2ecf20Sopenharmony_ci else 228c2ecf20Sopenharmony_ci start = num; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci if (!parsing_end && *next == '-') { 258c2ecf20Sopenharmony_ci s = next + 1; 268c2ecf20Sopenharmony_ci parsing_end = true; 278c2ecf20Sopenharmony_ci continue; 288c2ecf20Sopenharmony_ci } else if (*next == ',') { 298c2ecf20Sopenharmony_ci parsing_end = false; 308c2ecf20Sopenharmony_ci s = next + 1; 318c2ecf20Sopenharmony_ci end = num; 328c2ecf20Sopenharmony_ci } else if (*next == '\0') { 338c2ecf20Sopenharmony_ci parsing_end = false; 348c2ecf20Sopenharmony_ci s = next; 358c2ecf20Sopenharmony_ci end = num; 368c2ecf20Sopenharmony_ci } else { 378c2ecf20Sopenharmony_ci return -EINVAL; 388c2ecf20Sopenharmony_ci } 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci if (start > end) 418c2ecf20Sopenharmony_ci return -EINVAL; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci if (end + 1 > set_len) { 448c2ecf20Sopenharmony_ci new_len = end + 1; 458c2ecf20Sopenharmony_ci tmp = realloc(set, new_len); 468c2ecf20Sopenharmony_ci if (!tmp) { 478c2ecf20Sopenharmony_ci free(set); 488c2ecf20Sopenharmony_ci return -ENOMEM; 498c2ecf20Sopenharmony_ci } 508c2ecf20Sopenharmony_ci for (i = set_len; i < start; i++) 518c2ecf20Sopenharmony_ci tmp[i] = false; 528c2ecf20Sopenharmony_ci set = tmp; 538c2ecf20Sopenharmony_ci set_len = new_len; 548c2ecf20Sopenharmony_ci } 558c2ecf20Sopenharmony_ci for (i = start; i <= end; i++) 568c2ecf20Sopenharmony_ci set[i] = true; 578c2ecf20Sopenharmony_ci } 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci if (!set) 608c2ecf20Sopenharmony_ci return -EINVAL; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci *num_set = set; 638c2ecf20Sopenharmony_ci *num_set_len = set_len; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return 0; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci__u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci __u32 info_len = sizeof(*info); 718c2ecf20Sopenharmony_ci int err; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci memset(info, 0, sizeof(*info)); 748c2ecf20Sopenharmony_ci err = bpf_obj_get_info_by_fd(bpf_link__fd(link), info, &info_len); 758c2ecf20Sopenharmony_ci if (err) { 768c2ecf20Sopenharmony_ci printf("failed to get link info: %d\n", -errno); 778c2ecf20Sopenharmony_ci return 0; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci return info->prog_id; 808c2ecf20Sopenharmony_ci} 81