Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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
  9#include <linux/bpf.h>
 10#include <linux/btf_ids.h>
 11
 12#include <net/dst_metadata.h>
 13#include <net/fou.h>
 14
 15struct bpf_fou_encap {
 16	__be16 sport;
 17	__be16 dport;
 18};
 19
 20enum bpf_fou_encap_type {
 21	FOU_BPF_ENCAP_FOU,
 22	FOU_BPF_ENCAP_GUE,
 23};
 24
 25__bpf_kfunc_start_defs();
 26
 27/* bpf_skb_set_fou_encap - Set FOU encap parameters
 28 *
 29 * This function allows for using GUE or FOU encapsulation together with an
 30 * ipip device in collect-metadata mode.
 31 *
 32 * It is meant to be used in BPF tc-hooks and after a call to the
 33 * bpf_skb_set_tunnel_key helper, responsible for setting IP addresses.
 34 *
 35 * Parameters:
 36 * @skb_ctx	Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
 37 * @encap	Pointer to a `struct bpf_fou_encap` storing UDP src and
 38 * 		dst ports. If sport is set to 0 the kernel will auto-assign a
 39 * 		port. This is similar to using `encap-sport auto`.
 40 * 		Cannot be NULL
 41 * @type	Encapsulation type for the packet. Their definitions are
 42 * 		specified in `enum bpf_fou_encap_type`
 43 */
 44__bpf_kfunc int bpf_skb_set_fou_encap(struct __sk_buff *skb_ctx,
 45				      struct bpf_fou_encap *encap, int type)
 46{
 47	struct sk_buff *skb = (struct sk_buff *)skb_ctx;
 48	struct ip_tunnel_info *info = skb_tunnel_info(skb);
 49
 50	if (unlikely(!encap))
 51		return -EINVAL;
 52
 53	if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX)))
 54		return -EINVAL;
 55
 56	switch (type) {
 57	case FOU_BPF_ENCAP_FOU:
 58		info->encap.type = TUNNEL_ENCAP_FOU;
 59		break;
 60	case FOU_BPF_ENCAP_GUE:
 61		info->encap.type = TUNNEL_ENCAP_GUE;
 62		break;
 63	default:
 64		info->encap.type = TUNNEL_ENCAP_NONE;
 65	}
 66
 67	if (test_bit(IP_TUNNEL_CSUM_BIT, info->key.tun_flags))
 68		info->encap.flags |= TUNNEL_ENCAP_FLAG_CSUM;
 69
 70	info->encap.sport = encap->sport;
 71	info->encap.dport = encap->dport;
 72
 73	return 0;
 74}
 75
 76/* bpf_skb_get_fou_encap - Get FOU encap parameters
 77 *
 78 * This function allows for reading encap metadata from a packet received
 79 * on an ipip device in collect-metadata mode.
 80 *
 81 * Parameters:
 82 * @skb_ctx	Pointer to ctx (__sk_buff) in TC program. Cannot be NULL
 83 * @encap	Pointer to a struct bpf_fou_encap storing UDP source and
 84 * 		destination port. Cannot be NULL
 85 */
 86__bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
 87				      struct bpf_fou_encap *encap)
 88{
 89	struct sk_buff *skb = (struct sk_buff *)skb_ctx;
 90	struct ip_tunnel_info *info = skb_tunnel_info(skb);
 91
 92	if (unlikely(!info))
 93		return -EINVAL;
 94
 95	encap->sport = info->encap.sport;
 96	encap->dport = info->encap.dport;
 97
 98	return 0;
 99}
100
101__bpf_kfunc_end_defs();
102
103BTF_KFUNCS_START(fou_kfunc_set)
104BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)
105BTF_ID_FLAGS(func, bpf_skb_get_fou_encap)
106BTF_KFUNCS_END(fou_kfunc_set)
107
108static const struct btf_kfunc_id_set fou_bpf_kfunc_set = {
109	.owner = THIS_MODULE,
110	.set   = &fou_kfunc_set,
111};
112
113int register_fou_bpf(void)
114{
115	return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
116					 &fou_bpf_kfunc_set);
117}