From: Liu Jian liujian56@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8J90J
----------------------------------------------------
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 Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- include/linux/filter.h | 3 +++ include/linux/skbuff.h | 5 +++++ include/uapi/linux/bpf.h | 1 + net/core/filter.c | 14 ++++++++++++++ net/ipv4/tcp_input.c | 6 +++++- net/ipv4/tcp_output.c | 9 +++++++++ tools/include/uapi/linux/bpf.h | 1 + 7 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h index 761af6b3cf2b..95b8b5f15767 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1300,6 +1300,9 @@ struct bpf_sock_ops_kern { u8 op; u8 is_fullsock; u8 remaining_opt_len; +#if IS_ENABLED(CONFIG_NETACC_BPF) + u8 local_skb; +#endif 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 97bfef071255..e4524542a18f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1046,6 +1046,11 @@ struct sk_buff { u64 kcov_handle; #endif
+#if IS_ENABLED(CONFIG_NETACC_BPF) + __u8 local_skb; + __u8 pad0; + __u16 pad1; +#endif ); /* end headers group */
/* These elements must be at the end, see alloc_skb() for details. */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0448700890f7..4924f0cde1bc 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6666,6 +6666,7 @@ struct bpf_sock_ops { * been written yet. */ __u64 skb_hwtstamp; + __u32 local_skb; };
/* Definitions for bpf_sock_ops_cb_flags */ diff --git a/net/core/filter.c b/net/core/filter.c index d5a22975a885..efe4254c53d9 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9054,6 +9054,11 @@ static bool sock_ops_is_valid_access(int off, int size, if (off % size != 0) return false;
+#if !(IS_ENABLED(CONFIG_NETACC_BPF)) + if (off == offsetof(struct bpf_sock_ops, local_skb)) + return false; +#endif + if (type == BPF_WRITE) { switch (off) { case offsetof(struct bpf_sock_ops, reply): @@ -10593,6 +10598,15 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, insn - jmp_on_null_skb - 1); break; } +#if IS_ENABLED(CONFIG_NETACC_BPF) + 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; +#endif } return insn - insn_buf; } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 1f9d1d445fb3..fd5c13c1fbc8 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -186,8 +186,12 @@ 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)); +#if IS_ENABLED(CONFIG_NETACC_BPF) + sock_ops.local_skb = skb->local_skb; +#endif + }
BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops); } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9ccfdc825004..1917c62ad3bf 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3725,6 +3725,9 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, rcu_read_unlock(); #endif
+#if IS_ENABLED(CONFIG_NETACC_BPF) + skb->local_skb = 1; +#endif bpf_skops_write_hdr_opt((struct sock *)sk, skb, req, syn_skb, synack_type, &opts);
@@ -3965,6 +3968,9 @@ int tcp_connect(struct sock *sk) if (unlikely(!buff)) return -ENOBUFS;
+#if IS_ENABLED(CONFIG_NETACC_BPF) + buff->local_skb = 1; +#endif tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN); tcp_mstamp_refresh(tp); tp->retrans_stamp = tcp_time_stamp(tp); @@ -4083,6 +4089,9 @@ void __tcp_send_ack(struct sock *sk, u32 rcv_nxt)
/* Reserve space for headers and prepare control bits. */ skb_reserve(buff, MAX_TCP_HEADER); +#if IS_ENABLED(CONFIG_NETACC_BPF) + buff->local_skb = 1; +#endif 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 0448700890f7..4924f0cde1bc 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -6666,6 +6666,7 @@ struct bpf_sock_ops { * been written yet. */ __u64 skb_hwtstamp; + __u32 local_skb; };
/* Definitions for bpf_sock_ops_cb_flags */