hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7DNAP CVE: N/A
----------------------------------------------------
Add the local_skb parameter to struct sk_buff to identify the local connection. Currently, this function is used only on BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB and BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB to help the sockops bpf program check whether the current connection is a local connection. Updating the local_skb variable only when the ACK packet is sent is sufficient for this function to work.
Signed-off-by: Liu Jian liujian56@huawei.com --- v1->v2: Move local_skb to a reserved field instead of inserting it to a structure hole.
include/linux/filter.h | 1 + include/linux/skbuff.h | 2 +- include/uapi/linux/bpf.h | 1 + net/core/filter.c | 7 +++++++ net/ipv4/tcp_input.c | 4 +++- net/ipv4/tcp_output.c | 4 ++++ tools/include/uapi/linux/bpf.h | 1 + 7 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h index a2c9ca9626e9..4479a49a4f7c 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1284,6 +1284,7 @@ struct bpf_sock_ops_kern { u8 op; u8 is_fullsock; u8 remaining_opt_len; + u8 local_skb; u64 temp; /* temp and everything after is not * initialized to 0 before calling * the BPF program. New fields that diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d16c8bd085f3..a104fdd74aba 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -922,7 +922,7 @@ struct sk_buff { __u32 headers_end[0]; /* public: */
- KABI_USE(1, __u8 scm_io_uring:1) + KABI_USE2(1, __u8 scm_io_uring:1, __u8 local_skb:1) KABI_RESERVE(2) KABI_RESERVE(3) KABI_RESERVE(4) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 79d5e5850bf6..2f9e57e99bda 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -4707,6 +4707,7 @@ struct bpf_sock_ops { * the outgoing header has not * been written yet. */ + __u32 local_skb; };
/* Definitions for bpf_sock_ops_cb_flags */ diff --git a/net/core/filter.c b/net/core/filter.c index 6268ef7c8735..18d17598fcee 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9670,6 +9670,13 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, tcp_flags), si->dst_reg, si->dst_reg, off); break; + case offsetof(struct bpf_sock_ops, local_skb): + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sock_ops_kern, + local_skb), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_ops_kern, + local_skb)); + break; } return insn - insn_buf; } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 58a8f211b997..c18a0300abde 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -185,8 +185,10 @@ static void bpf_skops_established(struct sock *sk, int bpf_op, sock_ops.is_fullsock = 1; sock_ops.sk = sk; /* sk with TCP_REPAIR_ON does not have skb in tcp_finish_connect */ - if (skb) + if (skb) { bpf_skops_init_skb(&sock_ops, skb, tcp_hdrlen(skb)); + sock_ops.local_skb = skb->local_skb; + }
BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops); } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 680d7f06a51c..c3d87299f0ce 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3671,6 +3671,8 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, rcu_read_unlock(); #endif
+ skb->local_skb = 1; + bpf_skops_write_hdr_opt((struct sock *)sk, skb, req, syn_skb, synack_type, &opts);
@@ -3910,6 +3912,7 @@ int tcp_connect(struct sock *sk) if (unlikely(!buff)) return -ENOBUFS;
+ buff->local_skb = 1; tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN); tcp_mstamp_refresh(tp); tp->retrans_stamp = tcp_time_stamp(tp); @@ -4028,6 +4031,7 @@ void __tcp_send_ack(struct sock *sk, u32 rcv_nxt)
/* Reserve space for headers and prepare control bits. */ skb_reserve(buff, MAX_TCP_HEADER); + buff->local_skb = 1; tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPHDR_ACK);
/* We do not want pure acks influencing TCP Small Queues or fq/pacing diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 807232f0c7e0..96554988d8a8 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -4707,6 +4707,7 @@ struct bpf_sock_ops { * the outgoing header has not * been written yet. */ + __u32 local_skb; };
/* Definitions for bpf_sock_ops_cb_flags */