test_stub.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
  2. *
  3. * This program is free software; you can redistribute it and/or
  4. * modify it under the terms of version 2 of the GNU General Public
  5. * License as published by the Free Software Foundation.
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/types.h>
  9. #include <linux/slab.h>
  10. #include <linux/err.h>
  11. #include <linux/bpf.h>
  12. /* test stubs for BPF_MAP_TYPE_UNSPEC and for BPF_PROG_TYPE_UNSPEC
  13. * to be used by user space verifier testsuite
  14. */
  15. struct bpf_context {
  16. u64 arg1;
  17. u64 arg2;
  18. };
  19. static u64 test_func(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
  20. {
  21. return 0;
  22. }
  23. static struct bpf_func_proto test_funcs[] = {
  24. [BPF_FUNC_unspec] = {
  25. .func = test_func,
  26. .gpl_only = true,
  27. .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
  28. .arg1_type = ARG_CONST_MAP_PTR,
  29. .arg2_type = ARG_PTR_TO_MAP_KEY,
  30. },
  31. };
  32. static const struct bpf_func_proto *test_func_proto(enum bpf_func_id func_id)
  33. {
  34. if (func_id < 0 || func_id >= ARRAY_SIZE(test_funcs))
  35. return NULL;
  36. return &test_funcs[func_id];
  37. }
  38. static const struct bpf_context_access {
  39. int size;
  40. enum bpf_access_type type;
  41. } test_ctx_access[] = {
  42. [offsetof(struct bpf_context, arg1)] = {
  43. FIELD_SIZEOF(struct bpf_context, arg1),
  44. BPF_READ
  45. },
  46. [offsetof(struct bpf_context, arg2)] = {
  47. FIELD_SIZEOF(struct bpf_context, arg2),
  48. BPF_READ
  49. },
  50. };
  51. static bool test_is_valid_access(int off, int size, enum bpf_access_type type)
  52. {
  53. const struct bpf_context_access *access;
  54. if (off < 0 || off >= ARRAY_SIZE(test_ctx_access))
  55. return false;
  56. access = &test_ctx_access[off];
  57. if (access->size == size && (access->type & type))
  58. return true;
  59. return false;
  60. }
  61. static struct bpf_verifier_ops test_ops = {
  62. .get_func_proto = test_func_proto,
  63. .is_valid_access = test_is_valid_access,
  64. };
  65. static struct bpf_prog_type_list tl_prog = {
  66. .ops = &test_ops,
  67. .type = BPF_PROG_TYPE_UNSPEC,
  68. };
  69. static struct bpf_map *test_map_alloc(union bpf_attr *attr)
  70. {
  71. struct bpf_map *map;
  72. map = kzalloc(sizeof(*map), GFP_USER);
  73. if (!map)
  74. return ERR_PTR(-ENOMEM);
  75. map->key_size = attr->key_size;
  76. map->value_size = attr->value_size;
  77. map->max_entries = attr->max_entries;
  78. return map;
  79. }
  80. static void test_map_free(struct bpf_map *map)
  81. {
  82. kfree(map);
  83. }
  84. static struct bpf_map_ops test_map_ops = {
  85. .map_alloc = test_map_alloc,
  86. .map_free = test_map_free,
  87. };
  88. static struct bpf_map_type_list tl_map = {
  89. .ops = &test_map_ops,
  90. .type = BPF_MAP_TYPE_UNSPEC,
  91. };
  92. static int __init register_test_ops(void)
  93. {
  94. bpf_register_map_type(&tl_map);
  95. bpf_register_prog_type(&tl_prog);
  96. return 0;
  97. }
  98. late_initcall(register_test_ops);