xfrm_state_bpf.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Unstable XFRM state BPF helpers.
  3. *
  4. * Note that it is allowed to break compatibility for these functions since the
  5. * interface they are exposed through to BPF programs is explicitly unstable.
  6. */
  7. #include <linux/bpf.h>
  8. #include <linux/btf.h>
  9. #include <linux/btf_ids.h>
  10. #include <net/xdp.h>
  11. #include <net/xfrm.h>
  12. /* bpf_xfrm_state_opts - Options for XFRM state lookup helpers
  13. *
  14. * Members:
  15. * @error - Out parameter, set for any errors encountered
  16. * Values:
  17. * -EINVAL - netns_id is less than -1
  18. * -EINVAL - opts__sz isn't BPF_XFRM_STATE_OPTS_SZ
  19. * -ENONET - No network namespace found for netns_id
  20. * -ENOENT - No xfrm_state found
  21. * @netns_id - Specify the network namespace for lookup
  22. * Values:
  23. * BPF_F_CURRENT_NETNS (-1)
  24. * Use namespace associated with ctx
  25. * [0, S32_MAX]
  26. * Network Namespace ID
  27. * @mark - XFRM mark to match on
  28. * @daddr - Destination address to match on
  29. * @spi - Security parameter index to match on
  30. * @proto - IP protocol to match on (eg. IPPROTO_ESP)
  31. * @family - Protocol family to match on (AF_INET/AF_INET6)
  32. */
  33. struct bpf_xfrm_state_opts {
  34. s32 error;
  35. s32 netns_id;
  36. u32 mark;
  37. xfrm_address_t daddr;
  38. __be32 spi;
  39. u8 proto;
  40. u16 family;
  41. };
  42. enum {
  43. BPF_XFRM_STATE_OPTS_SZ = sizeof(struct bpf_xfrm_state_opts),
  44. };
  45. __bpf_kfunc_start_defs();
  46. /* bpf_xdp_get_xfrm_state - Get XFRM state
  47. *
  48. * A `struct xfrm_state *`, if found, must be released with a corresponding
  49. * bpf_xdp_xfrm_state_release.
  50. *
  51. * Parameters:
  52. * @ctx - Pointer to ctx (xdp_md) in XDP program
  53. * Cannot be NULL
  54. * @opts - Options for lookup (documented above)
  55. * Cannot be NULL
  56. * @opts__sz - Length of the bpf_xfrm_state_opts structure
  57. * Must be BPF_XFRM_STATE_OPTS_SZ
  58. */
  59. __bpf_kfunc struct xfrm_state *
  60. bpf_xdp_get_xfrm_state(struct xdp_md *ctx, struct bpf_xfrm_state_opts *opts, u32 opts__sz)
  61. {
  62. struct xdp_buff *xdp = (struct xdp_buff *)ctx;
  63. struct net *net = dev_net(xdp->rxq->dev);
  64. struct xfrm_state *x;
  65. if (!opts || opts__sz < sizeof(opts->error))
  66. return NULL;
  67. if (opts__sz != BPF_XFRM_STATE_OPTS_SZ) {
  68. opts->error = -EINVAL;
  69. return NULL;
  70. }
  71. if (unlikely(opts->netns_id < BPF_F_CURRENT_NETNS)) {
  72. opts->error = -EINVAL;
  73. return NULL;
  74. }
  75. if (opts->netns_id >= 0) {
  76. net = get_net_ns_by_id(net, opts->netns_id);
  77. if (unlikely(!net)) {
  78. opts->error = -ENONET;
  79. return NULL;
  80. }
  81. }
  82. x = xfrm_state_lookup(net, opts->mark, &opts->daddr, opts->spi,
  83. opts->proto, opts->family);
  84. if (opts->netns_id >= 0)
  85. put_net(net);
  86. if (!x)
  87. opts->error = -ENOENT;
  88. return x;
  89. }
  90. /* bpf_xdp_xfrm_state_release - Release acquired xfrm_state object
  91. *
  92. * This must be invoked for referenced PTR_TO_BTF_ID, and the verifier rejects
  93. * the program if any references remain in the program in all of the explored
  94. * states.
  95. *
  96. * Parameters:
  97. * @x - Pointer to referenced xfrm_state object, obtained using
  98. * bpf_xdp_get_xfrm_state.
  99. */
  100. __bpf_kfunc void bpf_xdp_xfrm_state_release(struct xfrm_state *x)
  101. {
  102. xfrm_state_put(x);
  103. }
  104. __bpf_kfunc_end_defs();
  105. BTF_KFUNCS_START(xfrm_state_kfunc_set)
  106. BTF_ID_FLAGS(func, bpf_xdp_get_xfrm_state, KF_RET_NULL | KF_ACQUIRE)
  107. BTF_ID_FLAGS(func, bpf_xdp_xfrm_state_release, KF_RELEASE)
  108. BTF_KFUNCS_END(xfrm_state_kfunc_set)
  109. static const struct btf_kfunc_id_set xfrm_state_xdp_kfunc_set = {
  110. .owner = THIS_MODULE,
  111. .set = &xfrm_state_kfunc_set,
  112. };
  113. int __init register_xfrm_state_bpf(void)
  114. {
  115. return register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP,
  116. &xfrm_state_xdp_kfunc_set);
  117. }