bpf: Add source ip in "struct bpf_tunnel_key"
authorKaixi Fan <fankaixi.li@bytedance.com>
Sat, 30 Apr 2022 07:48:42 +0000 (15:48 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 10 May 2022 17:49:03 +0000 (10:49 -0700)
Add tunnel source ip field in "struct bpf_tunnel_key". Add related code
to set and get tunnel source field.

Signed-off-by: Kaixi Fan <fankaixi.li@bytedance.com>
Link: https://lore.kernel.org/r/20220430074844.69214-2-fankaixi.li@bytedance.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
net/core/filter.c
tools/include/uapi/linux/bpf.h

index 444fe6f1cf35894d254c17de6e475c4f913f34d8..95a3d1ff62559394a264bd599a2102195a2c792d 100644 (file)
@@ -5604,6 +5604,10 @@ struct bpf_tunnel_key {
        __u8 tunnel_ttl;
        __u16 tunnel_ext;       /* Padding, future use. */
        __u32 tunnel_label;
+       union {
+               __u32 local_ipv4;
+               __u32 local_ipv6[4];
+       };
 };
 
 /* user accessible mirror of in-kernel xfrm_state.
index b741b9f7e6a9d7e56ca2ae2b72ee4b5fcea383fc..fe0da529d00fe1d5b2ea1686dfd774ca7a3284d8 100644 (file)
@@ -4498,6 +4498,7 @@ BPF_CALL_4(bpf_skb_get_tunnel_key, struct sk_buff *, skb, struct bpf_tunnel_key
        if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
                err = -EINVAL;
                switch (size) {
+               case offsetof(struct bpf_tunnel_key, local_ipv6[0]):
                case offsetof(struct bpf_tunnel_key, tunnel_label):
                case offsetof(struct bpf_tunnel_key, tunnel_ext):
                        goto set_compat;
@@ -4523,10 +4524,14 @@ set_compat:
        if (flags & BPF_F_TUNINFO_IPV6) {
                memcpy(to->remote_ipv6, &info->key.u.ipv6.src,
                       sizeof(to->remote_ipv6));
+               memcpy(to->local_ipv6, &info->key.u.ipv6.dst,
+                      sizeof(to->local_ipv6));
                to->tunnel_label = be32_to_cpu(info->key.label);
        } else {
                to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src);
                memset(&to->remote_ipv6[1], 0, sizeof(__u32) * 3);
+               to->local_ipv4 = be32_to_cpu(info->key.u.ipv4.dst);
+               memset(&to->local_ipv6[1], 0, sizeof(__u32) * 3);
                to->tunnel_label = 0;
        }
 
@@ -4597,6 +4602,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
                return -EINVAL;
        if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
                switch (size) {
+               case offsetof(struct bpf_tunnel_key, local_ipv6[0]):
                case offsetof(struct bpf_tunnel_key, tunnel_label):
                case offsetof(struct bpf_tunnel_key, tunnel_ext):
                case offsetof(struct bpf_tunnel_key, remote_ipv6[1]):
@@ -4639,10 +4645,13 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
                info->mode |= IP_TUNNEL_INFO_IPV6;
                memcpy(&info->key.u.ipv6.dst, from->remote_ipv6,
                       sizeof(from->remote_ipv6));
+               memcpy(&info->key.u.ipv6.src, from->local_ipv6,
+                      sizeof(from->local_ipv6));
                info->key.label = cpu_to_be32(from->tunnel_label) &
                                  IPV6_FLOWLABEL_MASK;
        } else {
                info->key.u.ipv4.dst = cpu_to_be32(from->remote_ipv4);
+               info->key.u.ipv4.src = cpu_to_be32(from->local_ipv4);
        }
 
        return 0;
index 444fe6f1cf35894d254c17de6e475c4f913f34d8..95a3d1ff62559394a264bd599a2102195a2c792d 100644 (file)
@@ -5604,6 +5604,10 @@ struct bpf_tunnel_key {
        __u8 tunnel_ttl;
        __u16 tunnel_ext;       /* Padding, future use. */
        __u32 tunnel_label;
+       union {
+               __u32 local_ipv4;
+               __u32 local_ipv6[4];
+       };
 };
 
 /* user accessible mirror of in-kernel xfrm_state.