fou_bpf.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Unstable Fou Helpers for TC-BPF hook
  3. *
  4. * These are called from SCHED_CLS BPF programs. Note that it is
  5. * allowed to break compatibility for these functions since the interface they
  6. * are exposed through to BPF programs is explicitly unstable.
  7. */
  8. #include <linux/bpf.h>
  9. #include <linux/btf_ids.h>
  10. #include <net/dst_metadata.h>
  11. #include <net/fou.h>
  12. struct bpf_fou_encap {
  13. __be16 sport;
  14. __be16 dport;
  15. };
  16. enum bpf_fou_encap_type {
  17. FOU_BPF_ENCAP_FOU,
  18. FOU_BPF_ENCAP_GUE,
  19. };
  20. __bpf_kfunc_start_defs();
  21. /* bpf_skb_set_fou_encap - Set FOU encap parameters
  22. *
  23. * This function allows for using GUE or FOU encapsulation together with an
  24. * ipip device in collect-metadata mode.
  25. *
  26. * It is meant to be used in BPF tc-hooks and after a call to the
  27. * bpf_skb_set_tunnel_key helper, responsible for setting IP addresses.
  28. *
  29. * Parameters:
  30. * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
  31. * @encap Pointer to a `struct bpf_fou_encap` storing UDP src and
  32. * dst ports. If sport is set to 0 the kernel will auto-assign a
  33. * port. This is similar to using `encap-sport auto`.
  34. * Cannot be NULL
  35. * @type Encapsulation type for the packet. Their definitions are
  36. * specified in `enum bpf_fou_encap_type`
  37. */
  38. __bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
  39. struct bpf_fou_encap *encap, int type)
  40. {
  41. struct sk_buff *skb = (struct sk_buff *)skb_ctx;
  42. struct ip_tunnel_info *info = skb_tunnel_info(skb);
  43. if (unlikely(!encap))
  44. return -EINVAL;
  45. if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX)))
  46. return -EINVAL;
  47. switch (type) {
  48. case FOU_BPF_ENCAP_FOU:
  49. info->encap.type = TUNNEL_ENCAP_FOU;
  50. break;
  51. case FOU_BPF_ENCAP_GUE:
  52. info->encap.type = TUNNEL_ENCAP_GUE;
  53. break;
  54. default:
  55. info->encap.type = TUNNEL_ENCAP_NONE;
  56. }
  57. if (test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags))
  58. info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM;
  59. info->encap.sport = encap->sport;
  60. info->encap.dport = encap->dport;
  61. return 0;
  62. }
  63. /* bpf_skb_get_fou_encap - Get FOU encap parameters
  64. *
  65. * This function allows for reading encap metadata from a packet received
  66. * on an ipip device in collect-metadata mode.
  67. *
  68. * Parameters:
  69. * @skb_ctx Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
  70. * @encap Pointer to a struct bpf_fou_encap storing UDP source and
  71. * destination port. Cannot be NULL
  72. */
  73. __bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
  74. struct bpf_fou_encap *encap)
  75. {
  76. struct sk_buff *skb = (struct sk_buff *)skb_ctx;
  77. struct ip_tunnel_info *info = skb_tunnel_info(skb);
  78. if (unlikely(!info))
  79. return -EINVAL;
  80. encap->sport = info->encap.sport;
  81. encap->dport = info->encap.dport;
  82. return 0;
  83. }
  84. __bpf_kfunc_end_defs();
  85. BTF_KFUNCS_START(fou_kfunc_set)
  86. BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)
  87. BTF_ID_FLAGS(func, bpf_skb_get_fou_encap)
  88. BTF_KFUNCS_END(fou_kfunc_set)
  89. static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {
  90. .owner = THIS_MODULE,
  91. .set = &fou_kfunc_set,
  92. };
  93. int register_fou_bpf(void)
  94. {
  95. return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
  96. &fou_bpf_kfunc_set);
  97. }