[PATCH OLK-5.10 00/13] HiSock Enhancement
Pu Lehui (12): bpf: Add BPF_HISOCK_INGRESS attach type bpf: Add bpf_set_ingress_dst helper function bpf: Add bpf_get_skb_ethhdr helper function bpf: Add bpf_set_ingress/egress_dev helper function bpf: Add bpf_handle_ingress/egress_ptype helper function bpf: Apply BPF_HISOCK_INGRESS to hisock ingress bpf: Only deploy hisock in server bpf: Add multi port parse to hisock_cmd bpf: Add target comm parse to hisock_cmd bpf: Add ipv4-mapped ipv6 addr support for hisock bpf: Add local connect support for hisock bpf: Deprecate hisock unused helpers and orig ingress logic Vladimir Oltean (1): net: move the ptype_all and ptype_base declarations to include/linux/netdevice.h arch/arm64/include/asm/insn.h | 4 - arch/arm64/kernel/insn.c | 8 - arch/arm64/net/bpf_jit.h | 15 -- arch/arm64/net/bpf_jit_comp.c | 266 ---------------------- include/linux/filter.h | 27 ++- include/linux/netdevice.h | 7 + include/net/xdp.h | 5 - include/uapi/linux/bpf.h | 51 +++-- kernel/bpf/core.c | 7 - kernel/bpf/helpers.c | 27 --- kernel/bpf/syscall.c | 33 ++- kernel/bpf/verifier.c | 25 -- net/Kconfig | 1 + net/core/dev.c | 53 +++-- net/core/filter.c | 322 +++++++++++++++++--------- net/core/net-procfs.c | 3 - net/ipv4/ip_output.c | 31 +-- samples/bpf/hisock/bpf.c | 391 ++++++++++++++++++++++++-------- samples/bpf/hisock/hisock_cmd.c | 198 +++++++++++----- tools/bpf/bpftool/common.c | 1 + tools/include/uapi/linux/bpf.h | 53 +++-- tools/lib/bpf/libbpf.c | 4 +- 22 files changed, 803 insertions(+), 729 deletions(-) -- 2.34.1
From: Vladimir Oltean <vladimir.oltean@nxp.com> mainline inclusion from mainline-v5.13-rc1 commit 744b8376632208137fe4acc9967b93e2970732a3 category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- ptype_all and ptype_base are declared in net/core/dev.c as non-static, because they are used by net-procfs.c too. However, a "make W=1" build complains that there was no previous declaration of ptype_all and ptype_base in a header file, so this way of declaring things constitutes a violation of coding style. Let's move the extern declarations of ptype_all and ptype_base to the linux/netdevice.h file, which is included by net-procfs.c too. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/linux/netdevice.h | 3 +++ net/core/net-procfs.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4b7b6fa1dcb1..598f96f82874 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -5380,6 +5380,9 @@ do { \ #define PTYPE_HASH_SIZE (16) #define PTYPE_HASH_MASK (PTYPE_HASH_SIZE - 1) +extern struct list_head ptype_all __read_mostly; +extern struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; + extern struct net_device *blackhole_netdev; /* Note: Avoid these macros in fast path, prefer per-cpu or per-queue counters. */ diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c index eadb696360b4..88cc0ad7d386 100644 --- a/net/core/net-procfs.c +++ b/net/core/net-procfs.c @@ -10,9 +10,6 @@ #define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1)) #define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o)) -extern struct list_head ptype_all __read_mostly; -extern struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; - static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos) { struct net *net = seq_file_net(seq); -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add BPF_HISOCK_INGRESS attach type, which will replace the XDP_HISOCK_REDIRECT action to redirect target receive skb to TCP. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/linux/filter.h | 24 ++++++++++++ include/linux/netdevice.h | 4 ++ include/uapi/linux/bpf.h | 1 + kernel/bpf/syscall.c | 33 +++++++++++++--- net/Kconfig | 1 + net/core/dev.c | 36 +++++++++++++++--- net/core/filter.c | 69 +++++++++++++++++++++++++++++++--- tools/bpf/bpftool/common.c | 1 + tools/include/uapi/linux/bpf.h | 1 + tools/lib/bpf/libbpf.c | 4 +- 10 files changed, 157 insertions(+), 17 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 3c43603bfb62..5b9f8648b1ab 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1533,4 +1533,28 @@ static inline void run_gnet_bpf(enum gnet_bpf_attach_type atype, #endif +#ifdef CONFIG_HISOCK +DECLARE_STATIC_KEY_FALSE(hisock_ingress_key); + +int hisock_ingress_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog); +int hisock_ingress_prog_detach(const union bpf_attr *attr); + +static inline int hisock_ingress_bpf_run(struct bpf_prog *prog, struct sk_buff *skb) +{ + void *saved_data_end; + int ret; + + if (unlikely(!prog)) + return HISOCK_PASS; + + rcu_read_lock(); + bpf_compute_and_save_data_end(skb, &saved_data_end); + ret = bpf_prog_run_pin_on_cpu(prog, skb); + bpf_restore_data_end(skb, saved_data_end); + rcu_read_unlock(); + + return ret; +} +#endif + #endif /* __LINUX_FILTER_H__ */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 598f96f82874..5fd82c8e2b89 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2266,7 +2266,11 @@ struct net_device { /* protected by rtnl_lock */ struct bpf_xdp_entity xdp_state[__MAX_XDP_MODE]; +#ifdef CONFIG_HISOCK + KABI_USE(1, struct bpf_prog __rcu *hisock_ingress) +#else KABI_RESERVE(1) +#endif KABI_RESERVE(2) KABI_RESERVE(3) KABI_RESERVE(4) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index a83e3fac7e01..faf056fccf13 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -252,6 +252,7 @@ enum bpf_attach_type { BPF_GNET_RCV_NIC_NODE, BPF_GNET_SEND_NIC_NODE, BPF_HISOCK_EGRESS, + BPF_HISOCK_INGRESS, #endif __MAX_BPF_ATTACH_TYPE }; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 72ba7f768280..8b54354c0ce0 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2089,6 +2089,16 @@ bpf_prog_load_check_attach(enum bpf_prog_type prog_type, if (expected_attach_type == BPF_SK_LOOKUP) return 0; return -EINVAL; +#ifdef CONFIG_HISOCK + case BPF_PROG_TYPE_HISOCK: + switch (expected_attach_type) { + case BPF_HISOCK_EGRESS: + case BPF_HISOCK_INGRESS: + return 0; + default: + return -EINVAL; + } +#endif case BPF_PROG_TYPE_EXT: if (expected_attach_type) return -EINVAL; @@ -3013,6 +3023,7 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type) return BPF_PROG_TYPE_CGROUP_SOCKOPT; #ifdef CONFIG_HISOCK case BPF_HISOCK_EGRESS: + case BPF_HISOCK_INGRESS: return BPF_PROG_TYPE_HISOCK; #endif case BPF_TRACE_ITER: @@ -3111,15 +3122,20 @@ static int bpf_prog_attach(const union bpf_attr *attr) case BPF_PROG_TYPE_CGROUP_SOCKOPT: case BPF_PROG_TYPE_CGROUP_SYSCTL: case BPF_PROG_TYPE_SOCK_OPS: -#ifdef CONFIG_HISOCK - case BPF_PROG_TYPE_HISOCK: -#endif ret = cgroup_bpf_prog_attach(attr, ptype, prog); break; #ifdef CONFIG_BPF_NET_GLOBAL_PROG case BPF_PROG_TYPE_NET_GLOBAL: ret = gnet_bpf_prog_attach(attr, ptype, prog); break; +#endif +#ifdef CONFIG_HISOCK + case BPF_PROG_TYPE_HISOCK: + if (attr->attach_type == BPF_HISOCK_EGRESS) + ret = cgroup_bpf_prog_attach(attr, ptype, prog); + else if (attr->attach_type == BPF_HISOCK_INGRESS) + ret = hisock_ingress_prog_attach(attr, prog); + break; #endif default: ret = -EINVAL; @@ -3156,13 +3172,18 @@ static int bpf_prog_detach(const union bpf_attr *attr) case BPF_PROG_TYPE_CGROUP_SOCKOPT: case BPF_PROG_TYPE_CGROUP_SYSCTL: case BPF_PROG_TYPE_SOCK_OPS: -#ifdef CONFIG_HISOCK - case BPF_PROG_TYPE_HISOCK: -#endif return cgroup_bpf_prog_detach(attr, ptype); #ifdef CONFIG_BPF_NET_GLOBAL_PROG case BPF_PROG_TYPE_NET_GLOBAL: return gnet_bpf_prog_detach(attr, ptype); +#endif +#ifdef CONFIG_HISOCK + case BPF_PROG_TYPE_HISOCK: + if (attr->attach_type == BPF_HISOCK_EGRESS) + return cgroup_bpf_prog_detach(attr, ptype); + else if (attr->attach_type == BPF_HISOCK_INGRESS) + return hisock_ingress_prog_detach(attr); + return -EINVAL; #endif default: return -EINVAL; diff --git a/net/Kconfig b/net/Kconfig index d6d925d0712f..1e7f8a5b9008 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -332,6 +332,7 @@ config EULER_SOCKETMAP config HISOCK bool "enable HiSock Redirect Framework" depends on INET + depends on ARM64 depends on CGROUP_BPF depends on BPF_SYSCALL default n diff --git a/net/core/dev.c b/net/core/dev.c index 372bab73b8bf..27cb74f9ea32 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5019,7 +5019,7 @@ void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog) } #ifdef CONFIG_HISOCK -static int generic_xdp_hisock_redirect(struct sk_buff *skb) +static int do_hisock_ingress_redirect(struct sk_buff *skb) { const struct iphdr *iph; u32 len; @@ -5053,9 +5053,10 @@ static int generic_xdp_hisock_redirect(struct sk_buff *skb) iph = ip_hdr(skb); skb->transport_header = skb->network_header + iph->ihl * 4; - skb_orphan(skb); + if (!skb_sk_is_prefetched(skb)) + skb_orphan(skb); - if (!skb_valid_dst(skb)) { + if (unlikely(!skb_valid_dst(skb))) { if (ip_route_input_noref(skb, iph->daddr, iph->saddr, iph->tos, skb->dev)) goto free_skb; @@ -5072,7 +5073,7 @@ static int generic_xdp_hisock_redirect(struct sk_buff *skb) free_skb: kfree_skb(skb); out: - return -EFAULT; + return NET_RX_DROP; } #endif @@ -5101,7 +5102,7 @@ int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb) break; #ifdef CONFIG_HISOCK case XDP_HISOCK_REDIRECT: - err = generic_xdp_hisock_redirect(skb); + err = do_hisock_ingress_redirect(skb); if (err == -EOPNOTSUPP) return XDP_PASS; break; @@ -5540,6 +5541,31 @@ static int __netif_receive_skb_core(struct sk_buff **pskb, bool pfmemalloc, } skip_taps: +#ifdef CONFIG_HISOCK + if (static_branch_unlikely(&hisock_ingress_key)) { + int act; + + if (pt_prev) { + ret = deliver_skb(skb, pt_prev, orig_dev); + pt_prev = NULL; + } + + act = hisock_ingress_bpf_run(rcu_dereference(skb->dev->hisock_ingress), skb); + switch (act) { + case HISOCK_PASS: + break; + case HISOCK_REDIRECT: + ret = do_hisock_ingress_redirect(skb); + if (ret != -EOPNOTSUPP) + goto out; + break; + case HISOCK_DROP: + default: + ret = NET_RX_DROP; + goto out; + } + } +#endif #ifdef CONFIG_NET_INGRESS if (static_branch_unlikely(&ingress_needed_key)) { bool another = false; diff --git a/net/core/filter.c b/net/core/filter.c index adacca9ee505..cec7eace2d5c 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7984,12 +7984,25 @@ static bool hisock_is_valid_access(int off, int size, const struct bpf_prog *prog, struct bpf_insn_access_aux *info) { - switch (off) { - case bpf_ctx_range(struct __sk_buff, tc_classid): - case bpf_ctx_range(struct __sk_buff, data_meta): - case bpf_ctx_range(struct __sk_buff, tstamp): - case bpf_ctx_range(struct __sk_buff, wire_len): + if (type == BPF_WRITE) return false; + + if (prog->expected_attach_type == BPF_HISOCK_EGRESS) { + switch (off) { + case bpf_ctx_range(struct __sk_buff, tc_classid): + case bpf_ctx_range(struct __sk_buff, data_meta): + case bpf_ctx_range(struct __sk_buff, tstamp): + case bpf_ctx_range(struct __sk_buff, wire_len): + return false; + } + } else if (prog->expected_attach_type == BPF_HISOCK_INGRESS) { + switch (off) { + case bpf_ctx_range_till(struct __sk_buff, mark, queue_mapping): + case bpf_ctx_range(struct __sk_buff, priority): + case bpf_ctx_range_till(struct __sk_buff, tc_index, tc_classid): + case bpf_ctx_range_till(struct __sk_buff, napi_id, gso_size): + return false; + } } switch (off) { @@ -10237,6 +10250,52 @@ const struct bpf_prog_ops flow_dissector_prog_ops = { .test_run = bpf_prog_test_run_flow_dissector, }; +#ifdef CONFIG_HISOCK +DEFINE_STATIC_KEY_FALSE(hisock_ingress_key); + +static int hisock_ingress_prog_install(const union bpf_attr *attr, struct bpf_prog *new) +{ + struct net *net = current->nsproxy->net_ns; + struct net_device *dev; + struct bpf_prog *old; + int ret = 0; + + if (attr->attach_type != BPF_HISOCK_INGRESS) + return -EINVAL; + + rtnl_lock(); + dev = __dev_get_by_index(net, attr->target_fd); + if (!dev) { + ret = -ENODEV; + goto out; + } + + old = rtnl_dereference(dev->hisock_ingress); + rcu_assign_pointer(dev->hisock_ingress, new); + + if (new && !old) + static_branch_inc(&hisock_ingress_key); + else if (!new && old) + static_branch_dec(&hisock_ingress_key); + + if (old) + bpf_prog_put(old); +out: + rtnl_unlock(); + return ret; +} + +int hisock_ingress_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) +{ + return hisock_ingress_prog_install(attr, prog); +} + +int hisock_ingress_prog_detach(const union bpf_attr *attr) +{ + return hisock_ingress_prog_install(attr, NULL); +} +#endif + int sk_detach_filter(struct sock *sk) { int ret = -ENOENT; diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index c16dc2ba847e..52c9e84c05af 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -68,6 +68,7 @@ const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = { [BPF_SK_LOOKUP] = "sk_lookup", [BPF_SCHED] = "sched", [BPF_HISOCK_EGRESS] = "hisock_egress", + [BPF_HISOCK_INGRESS] = "hisock_ingress", }; void p_err(const char *fmt, ...) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index cab6526158fd..3501e5461a0a 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -252,6 +252,7 @@ enum bpf_attach_type { BPF_GNET_RCV_NIC_NODE, BPF_GNET_SEND_NIC_NODE, BPF_HISOCK_EGRESS, + BPF_HISOCK_INGRESS, #endif __MAX_BPF_ATTACH_TYPE }; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 3eaf5c353008..3293f87e3a65 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8502,8 +8502,10 @@ static const struct bpf_sec_def section_defs[] = { BPF_GNET_RCV_NIC_NODE), BPF_EAPROG_SEC("gnet/send_nic_node", BPF_PROG_TYPE_NET_GLOBAL, BPF_GNET_SEND_NIC_NODE), - BPF_APROG_SEC("hisock_egress", BPF_PROG_TYPE_HISOCK, + BPF_EAPROG_SEC("hisock_egress", BPF_PROG_TYPE_HISOCK, BPF_HISOCK_EGRESS), + BPF_EAPROG_SEC("hisock_ingress", BPF_PROG_TYPE_HISOCK, + BPF_HISOCK_INGRESS), }; #undef BPF_PROG_SEC_IMPL -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add bpf_set_ingress_dst helper function to set the receive dst entry of sock to ingress skb. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/uapi/linux/bpf.h | 15 +++++++++---- net/core/filter.c | 39 ++++++++++++++++++++++++++++++++-- samples/bpf/hisock/bpf.c | 4 ++-- tools/include/uapi/linux/bpf.h | 15 +++++++++---- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index faf056fccf13..3a415984bc27 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3944,14 +3944,14 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * void *bpf_get_ingress_dst(struct bpf_sock_ops *skops) + * void *bpf_get_rx_dst(struct bpf_sock_ops *skops) * Description * Get the ingress dst entry of the full sock. * Return * Valid ingress dst on success, or negative error * in case of failure. * - * int bpf_set_ingress_dst(struct xdp_buff *xdp, void *dst) + * int bpf_set_rx_dst(struct xdp_buff *xdp, void *dst) * Description * Set valid ingress dst entry to the skb associated * with xdp_buff. @@ -3974,6 +3974,12 @@ union bpf_attr { * Copy *src_sz* bytes from *src* to *dst* if *dst_sz* >= *src_sz*. * Return * 0 on success, or negative error in case of failure. + * + * int bpf_set_ingress_dst(struct sk_buff *skb, void *sk) + * Description + * Set skb ingress dst entry with valid sock rx dst entry. + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4152,10 +4158,11 @@ union bpf_attr { FN(get_node_stats), \ FN(sched_net_rship_submit), \ FN(sched_set_task_prefer_cpumask), \ - FN(get_ingress_dst), \ - FN(set_ingress_dst), \ + FN(get_rx_dst), \ + FN(set_rx_dst), \ FN(change_skb_dev), \ FN(ext_memcpy), \ + FN(set_ingress_dst), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index cec7eace2d5c..ff0a2845ae13 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3701,6 +3701,36 @@ static const struct bpf_func_proto bpf_skb_adjust_room_proto = { }; #ifdef CONFIG_HISOCK +BPF_CALL_2(bpf_set_ingress_dst, struct sk_buff *, skb, unsigned long, _sk) +{ + struct sock *sk = (struct sock *)_sk; + struct dst_entry *dst; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + if (!sk || !virt_addr_valid(sk)) + return -EFAULT; + + if (!sk_fullsock(sk)) + return -EINVAL; + + dst = rcu_dereference(sk->sk_rx_dst); + if (dst) + dst = dst_check(dst, 0); + if (dst && inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) + skb_dst_set_noref(skb, dst); + + return 0; +} + +static const struct bpf_func_proto bpf_set_ingress_dst_proto = { + .func = bpf_set_ingress_dst, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + BPF_CALL_2(bpf_skb_change_skb_dev, struct sk_buff *, skb, u32, ifindex) { struct net_device *dev; @@ -7410,6 +7440,8 @@ cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) static const struct bpf_func_proto * hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { + bool is_ingress = prog->expected_attach_type == BPF_HISOCK_INGRESS; + switch (func_id) { case BPF_FUNC_skb_store_bytes: return &bpf_skb_store_bytes_proto; @@ -7425,6 +7457,9 @@ hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_skb_adjust_room_proto; case BPF_FUNC_change_skb_dev: return &bpf_skb_change_skb_dev_proto; + case BPF_FUNC_set_ingress_dst: + return is_ingress ? &bpf_set_ingress_dst_proto : NULL; + default: return bpf_base_func_proto(func_id); } @@ -7575,7 +7610,7 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_fib_lookup: return &bpf_xdp_fib_lookup_proto; #ifdef CONFIG_HISOCK - case BPF_FUNC_set_ingress_dst: + case BPF_FUNC_set_rx_dst: return &bpf_xdp_set_ingress_dst_proto; case BPF_FUNC_change_skb_dev: return &bpf_xdp_change_skb_dev_proto; @@ -7642,7 +7677,7 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_reserve_hdr_opt: return &bpf_sock_ops_reserve_hdr_opt_proto; #ifdef CONFIG_HISOCK - case BPF_FUNC_get_ingress_dst: + case BPF_FUNC_get_rx_dst: return &bpf_sock_ops_get_ingress_dst_proto; #endif case BPF_FUNC_tcp_sock: diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 375f33fdf2e7..c87ddad7fe2f 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -84,7 +84,7 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) switch (skops->op) { case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: - dst = bpf_get_ingress_dst(skops); + dst = bpf_get_rx_dst(skops); if (!dst) return SOCKOPS_FAIL; @@ -178,7 +178,7 @@ int hisock_ingress_prog(struct xdp_md *ctx) val->ingress_ifindex = ctx->ingress_ifindex; if (likely(val->ingress_dst)) - bpf_set_ingress_dst(ctx, val->ingress_dst); + bpf_set_rx_dst(ctx, val->ingress_dst); return XDP_HISOCK_REDIRECT; } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 3501e5461a0a..48c0c054f82d 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3944,14 +3944,14 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * void *bpf_get_ingress_dst(struct bpf_sock_ops *skops) + * void *bpf_get_rx_dst(struct bpf_sock_ops *skops) * Description * Get the ingress dst entry of the full sock. * Return * Valid ingress dst on success, or negative error * in case of failure. * - * int bpf_set_ingress_dst(struct xdp_buff *xdp, void *dst) + * int bpf_set_rx_dst(struct xdp_buff *xdp, void *dst) * Description * Set valid ingress dst entry to the skb associated * with xdp_buff. @@ -3974,6 +3974,12 @@ union bpf_attr { * Copy *src_sz* bytes from *src* to *dst* if *dst_sz* >= *src_sz*. * Return * 0 on success, or negative error in case of failure. + * + * int bpf_set_ingress_dst(struct sk_buff *skb, void *sk) + * Description + * Set skb ingress dst entry with valid sock rx dst entry. + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4152,10 +4158,11 @@ union bpf_attr { FN(get_node_stats), \ FN(sched_net_rship_submit), \ FN(sched_set_task_prefer_cpumask), \ - FN(get_ingress_dst), \ - FN(set_ingress_dst), \ + FN(get_rx_dst), \ + FN(set_rx_dst), \ FN(change_skb_dev), \ FN(ext_memcpy), \ + FN(set_ingress_dst), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add bpf_get_skb_ethhdr helper function to fetch the ether header of the ingress skb. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/uapi/linux/bpf.h | 7 +++++++ net/core/filter.c | 22 ++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 7 +++++++ 3 files changed, 36 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 3a415984bc27..353561c18652 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3980,6 +3980,12 @@ union bpf_attr { * Set skb ingress dst entry with valid sock rx dst entry. * Return * 0 on success, or a negative error in case of failure. + * + * int bpf_get_skb_ethhdr(struct sk_buff *skb, void *peth, int size) + * Description + * Get the ether header of ingress skb. + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4163,6 +4169,7 @@ union bpf_attr { FN(change_skb_dev), \ FN(ext_memcpy), \ FN(set_ingress_dst), \ + FN(get_skb_ethhdr), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index ff0a2845ae13..53027d8d122b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3731,6 +3731,26 @@ static const struct bpf_func_proto bpf_set_ingress_dst_proto = { .arg2_type = ARG_ANYTHING, }; +BPF_CALL_3(bpf_get_skb_ethhdr, struct sk_buff *, skb, void *, peth, int, size) +{ + struct ethhdr *eth = eth_hdr(skb); + + if (size != sizeof(struct ethhdr)) + return -EINVAL; + + memcpy(peth, eth, size); + return 0; +} + +static const struct bpf_func_proto bpf_get_skb_ethhdr_proto = { + .func = bpf_get_skb_ethhdr, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_PTR_TO_MEM, + .arg3_type = ARG_CONST_SIZE, +}; + BPF_CALL_2(bpf_skb_change_skb_dev, struct sk_buff *, skb, u32, ifindex) { struct net_device *dev; @@ -7459,6 +7479,8 @@ hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_skb_change_skb_dev_proto; case BPF_FUNC_set_ingress_dst: return is_ingress ? &bpf_set_ingress_dst_proto : NULL; + case BPF_FUNC_get_skb_ethhdr: + return is_ingress ? &bpf_get_skb_ethhdr_proto : NULL; default: return bpf_base_func_proto(func_id); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 48c0c054f82d..2bf6ef95e964 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3980,6 +3980,12 @@ union bpf_attr { * Set skb ingress dst entry with valid sock rx dst entry. * Return * 0 on success, or a negative error in case of failure. + * + * int bpf_get_skb_ethhdr(struct sk_buff *skb, void *peth, int size) + * Description + * Get the ether header of ingress skb. + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4163,6 +4169,7 @@ union bpf_attr { FN(change_skb_dev), \ FN(ext_memcpy), \ FN(set_ingress_dst), \ + FN(get_skb_ethhdr), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add bpf_set_ingress/egress_dev helper function to set network device to ingress or egress skb. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/uapi/linux/bpf.h | 14 +++++++++++ net/core/filter.c | 44 ++++++++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 14 +++++++++++ 3 files changed, 72 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 353561c18652..8d393472de02 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3986,6 +3986,18 @@ union bpf_attr { * Get the ether header of ingress skb. * Return * 0 on success, or a negative error in case of failure. + * + * int bpf_set_ingress_dev(struct sk_buff *skb, void *dev) + * Description + * Set valid net device to ingress skb. + * Return + * 0 on success, or negative error in case of failure. + * + * int bpf_set_egress_dev(struct sk_buff *skb, void *dev) + * Description + * Set valid net device to egress skb. + * Return + * 0 on success, or negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4170,6 +4182,8 @@ union bpf_attr { FN(ext_memcpy), \ FN(set_ingress_dst), \ FN(get_skb_ethhdr), \ + FN(set_ingress_dev), \ + FN(set_egress_dev), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index 53027d8d122b..0ee0c974b17b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3751,6 +3751,46 @@ static const struct bpf_func_proto bpf_get_skb_ethhdr_proto = { .arg3_type = ARG_CONST_SIZE, }; +BPF_CALL_2(bpf_set_ingress_dev, struct sk_buff *, skb, void *, _dev) +{ + struct net_device *dev = (struct net_device *)_dev; + + if (!dev || !virt_addr_valid(dev)) + return -EFAULT; + + skb->dev = dev; + skb->skb_iif = dev->ifindex; + skb->pkt_type = PACKET_HOST; + return 0; +} + +static const struct bpf_func_proto bpf_set_ingress_dev_proto = { + .func = bpf_set_ingress_dev, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + +BPF_CALL_2(bpf_set_egress_dev, struct sk_buff *, skb, void *, _dev) +{ + struct net_device *dev = (struct net_device *)_dev; + + if (!dev || !virt_addr_valid(dev)) + return -EFAULT; + + skb->dev = dev; + return 0; +} + +static const struct bpf_func_proto bpf_set_egress_dev_proto = { + .func = bpf_set_egress_dev, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + BPF_CALL_2(bpf_skb_change_skb_dev, struct sk_buff *, skb, u32, ifindex) { struct net_device *dev; @@ -7481,6 +7521,10 @@ hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return is_ingress ? &bpf_set_ingress_dst_proto : NULL; case BPF_FUNC_get_skb_ethhdr: return is_ingress ? &bpf_get_skb_ethhdr_proto : NULL; + case BPF_FUNC_set_ingress_dev: + return is_ingress ? &bpf_set_ingress_dev_proto : NULL; + case BPF_FUNC_set_egress_dev: + return !is_ingress ? &bpf_set_egress_dev_proto : NULL; default: return bpf_base_func_proto(func_id); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 2bf6ef95e964..9dfe2ea7a018 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3986,6 +3986,18 @@ union bpf_attr { * Get the ether header of ingress skb. * Return * 0 on success, or a negative error in case of failure. + * + * int bpf_set_ingress_dev(struct sk_buff *skb, void *dev) + * Description + * Set valid net device to ingress skb. + * Return + * 0 on success, or negative error in case of failure. + * + * int bpf_set_egress_dev(struct sk_buff *skb, void *dev) + * Description + * Set valid net device to egress skb. + * Return + * 0 on success, or negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4170,6 +4182,8 @@ union bpf_attr { FN(ext_memcpy), \ FN(set_ingress_dst), \ FN(get_skb_ethhdr), \ + FN(set_ingress_dev), \ + FN(set_egress_dev), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add bpf_handle_ingress/egress_ptype helper function to handle the ingress or egress ptype logic. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/uapi/linux/bpf.h | 16 ++++++++++ net/core/filter.c | 58 ++++++++++++++++++++++++++++++++++ net/ipv4/ip_output.c | 31 +----------------- tools/include/uapi/linux/bpf.h | 16 ++++++++++ 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 8d393472de02..f0840df75d35 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3998,6 +3998,20 @@ union bpf_attr { * Set valid net device to egress skb. * Return * 0 on success, or negative error in case of failure. + * + * void bpf_handle_ingress_ptype(struct sk_buff *skb) + * Description + * Handle ingress ptype all logic based on the current + * net device of skb. + * Return + * Void. + * + * void bpf_handle_egress_ptype(struct sk_buff *skb) + * Description + * Handle egress ptype all logic based on the current + * net device of skb. + * Return + * Void. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4184,6 +4198,8 @@ union bpf_attr { FN(get_skb_ethhdr), \ FN(set_ingress_dev), \ FN(set_egress_dev), \ + FN(handle_ingress_ptype), \ + FN(handle_egress_ptype), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index 0ee0c974b17b..567bdb3cf0ba 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3791,6 +3791,60 @@ static const struct bpf_func_proto bpf_set_egress_dev_proto = { .arg2_type = ARG_ANYTHING, }; +BPF_CALL_1(bpf_handle_ingress_ptype, struct sk_buff *, skb) +{ + struct list_head *ptype_list = &ptype_all; + struct packet_type *ptype; + + rcu_read_lock(); +again: + list_for_each_entry_rcu(ptype, ptype_list, list) { + if (likely(!skb_orphan_frags_rx(skb, GFP_ATOMIC))) { + refcount_inc(&skb->users); + ptype->func(skb, skb->dev, ptype, skb->dev); + } + } + + if (ptype_list == &ptype_all) { + ptype_list = &skb->dev->ptype_all; + goto again; + } + + rcu_read_unlock(); + return 0; +} + +static const struct bpf_func_proto bpf_handle_ingress_ptype_proto = { + .func = bpf_handle_ingress_ptype, + .gpl_only = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, +}; + +BPF_CALL_1(bpf_handle_egress_ptype, struct sk_buff *, skb) +{ + struct net_device *dev, *orig_dev = skb->dev; + + rcu_read_lock(); + dev = skb_dst_dev_rcu(skb); + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + + if (dev_nit_active(skb->dev)) + dev_queue_xmit_nit(skb, skb->dev); + + skb->dev = orig_dev; + rcu_read_unlock(); + return 0; +} + +static const struct bpf_func_proto bpf_handle_egress_ptype_proto = { + .func = bpf_handle_egress_ptype, + .gpl_only = false, + .ret_type = RET_VOID, + .arg1_type = ARG_PTR_TO_CTX, +}; + BPF_CALL_2(bpf_skb_change_skb_dev, struct sk_buff *, skb, u32, ifindex) { struct net_device *dev; @@ -7525,6 +7579,10 @@ hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return is_ingress ? &bpf_set_ingress_dev_proto : NULL; case BPF_FUNC_set_egress_dev: return !is_ingress ? &bpf_set_egress_dev_proto : NULL; + case BPF_FUNC_handle_ingress_ptype: + return is_ingress ? &bpf_handle_ingress_ptype_proto : NULL; + case BPF_FUNC_handle_egress_ptype: + return !is_ingress ? &bpf_handle_egress_ptype_proto : NULL; default: return bpf_base_func_proto(func_id); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 587668db4ea4..5ef7653fa994 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -463,35 +463,6 @@ static void ip_copy_addrs(struct iphdr *iph, const struct flowi4 *fl4) } #ifdef CONFIG_HISOCK -static int hisock_egress_redirect_xmit(struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - struct netdev_queue *txq; - bool free_skb = true; - int cpu, rc; - - rcu_read_lock_bh(); - - txq = netdev_core_pick_tx(dev, skb, NULL); - cpu = smp_processor_id(); - HARD_TX_LOCK(dev, txq, cpu); - if (!netif_xmit_stopped(txq)) { - rc = netdev_start_xmit(skb, dev, txq, 0); - if (dev_xmit_complete(rc)) - free_skb = false; - } - HARD_TX_UNLOCK(dev, txq); - - rcu_read_unlock_bh(); - - if (free_skb) { - rc = -ENETDOWN; - kfree_skb(skb); - } - - return rc; -} - static int do_hisock_egress_redirect(struct net *net, struct sock *sk, struct sk_buff *skb) { struct iphdr *iph; @@ -501,7 +472,7 @@ static int do_hisock_egress_redirect(struct net *net, struct sock *sk, struct sk skb->dev = skb_dst(skb)->dev; if (skb_mac_header_was_set(skb)) - return hisock_egress_redirect_xmit(skb); + return dev_queue_xmit(skb); iph = ip_hdr(skb); iph->tot_len = htons(skb->len); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 9dfe2ea7a018..7729ba3a13bb 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3998,6 +3998,20 @@ union bpf_attr { * Set valid net device to egress skb. * Return * 0 on success, or negative error in case of failure. + * + * void bpf_handle_ingress_ptype(struct sk_buff *skb) + * Description + * Handle ingress ptype all logic based on the current + * net device of skb. + * Return + * Void. + * + * void bpf_handle_egress_ptype(struct sk_buff *skb) + * Description + * Handle egress ptype all logic based on the current + * net device of skb. + * Return + * Void. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4184,6 +4198,8 @@ union bpf_attr { FN(get_skb_ethhdr), \ FN(set_ingress_dev), \ FN(set_egress_dev), \ + FN(handle_ingress_ptype), \ + FN(handle_egress_ptype), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Apply BPF_HISOCK_INGRESS to hisock ingress. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 129 +++++++++++++++++++------------- samples/bpf/hisock/hisock_cmd.c | 28 +++---- 2 files changed, 85 insertions(+), 72 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index c87ddad7fe2f..0478aa00e7ea 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -4,23 +4,23 @@ * * Description: End-to-End HiSock Redirect sample. */ +#define KBUILD_MODNAME "foo" #include <uapi/linux/in.h> #include <uapi/linux/if_ether.h> #include <linux/if_vlan.h> +#include <linux/filter.h> #include <uapi/linux/ip.h> #include <uapi/linux/tcp.h> #include <uapi/linux/bpf.h> #include <bpf/bpf_endian.h> #include <bpf/bpf_helpers.h> +#include <bpf/bpf_core_read.h> #define IP_MF 0x2000 #define IP_OFFSET 0x1FFF #define CSUM_SHIFT_BITS 16 -#define SOCKOPS_SUCC 1 -#define SOCKOPS_FAIL 0 - #define PORT_LOCAL 1 #define PORT_REMOTE 2 @@ -36,10 +36,11 @@ struct sock_tuple { }; struct sock_value { + void *sk; + void *egress_dev; + void *ingress_dev; struct ethhdr ingress_eth; bool eth_updated; - u32 ingress_ifindex; - void *ingress_dst; }; struct { @@ -71,29 +72,46 @@ static inline bool is_speed_flow(u32 local, u32 remote) return false; } +static inline void *parse_ingress_dev(struct bpf_sock_ops *skops) +{ + struct sk_buff *skb; + struct net_device *dev; + + skb = BPF_CORE_READ((struct bpf_sock_ops_kern *)skops, skb); + dev = BPF_CORE_READ(skb, dev); + + return dev; +} + +static inline void *parse_egress_dev(struct __sk_buff *skb) +{ + struct net_device *dev; + + dev = BPF_CORE_READ((struct sk_buff *)skb, dev); + + return dev; +} + SEC("hisock_sockops") int hisock_sockops_prog(struct bpf_sock_ops *skops) { struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; - void *dst; if (!is_speed_flow(skops->local_port, bpf_ntohl(skops->remote_port))) - return SOCKOPS_SUCC; + return 1; switch (skops->op) { case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: - dst = bpf_get_rx_dst(skops); - if (!dst) - return SOCKOPS_FAIL; - key.saddr = skops->remote_ip4; key.sport = bpf_ntohl(skops->remote_port); key.daddr = skops->local_ip4; key.dport = skops->local_port; - val.ingress_dst = dst; + val.sk = skops->sk; + val.ingress_dev = parse_ingress_dev(skops); + bpf_map_update_elem(&connmap, &key, &val, BPF_ANY); bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); @@ -118,43 +136,39 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) break; } - return SOCKOPS_SUCC; + return 1; } SEC("hisock_ingress") -int hisock_ingress_prog(struct xdp_md *ctx) +int hisock_ingress_prog(struct __sk_buff *skb) { - void *data_end = (void *)(long)ctx->data_end; - void *data = (void *)(long)ctx->data; + void *data_end = (void *)(long)skb->data_end; + void *data = (void *)(long)skb->data; struct sock_tuple key = { 0 }; struct sock_value *val; - struct ethhdr *ehdr; struct tcphdr *thdr; struct iphdr *ihdr; + struct ethhdr ehdr; - ehdr = (struct ethhdr *)data; - if (ehdr + 1 > data_end) - return XDP_PASS; - - if (ehdr->h_proto != bpf_htons(ETH_P_IP)) - return XDP_PASS; + if (skb->protocol != bpf_htons(ETH_P_IP)) + return HISOCK_PASS; - ihdr = (struct iphdr *)(ehdr + 1); + ihdr = (struct iphdr *)data; if (ihdr + 1 > data_end) - return XDP_PASS; + return HISOCK_PASS; if (ihdr->ihl != 5 || ihdr->protocol != IPPROTO_TCP) - return XDP_PASS; + return HISOCK_PASS; if (ihdr->frag_off & bpf_htons(IP_MF | IP_OFFSET)) - return XDP_PASS; + return HISOCK_PASS; thdr = (struct tcphdr *)(ihdr + 1); if (thdr + 1 > data_end) - return XDP_PASS; + return HISOCK_PASS; if (thdr->syn || thdr->fin || thdr->rst) - return XDP_PASS; + return HISOCK_PASS; key.saddr = ihdr->saddr; key.sport = bpf_ntohs(thdr->source); @@ -163,24 +177,25 @@ int hisock_ingress_prog(struct xdp_md *ctx) val = bpf_map_lookup_elem(&connmap, &key); if (!val) - return XDP_PASS; - - if (unlikely(!val->eth_updated)) { - bpf_ext_memcpy(val->ingress_eth.h_source, ETH_ALEN, - ehdr->h_dest, ETH_ALEN); - bpf_ext_memcpy(val->ingress_eth.h_dest, ETH_ALEN, - ehdr->h_source, ETH_ALEN); - val->ingress_eth.h_proto = ehdr->h_proto; - val->eth_updated = true; + return HISOCK_PASS; + + if (!val->eth_updated) { + if (!(bpf_get_skb_ethhdr(skb, &ehdr, sizeof(ehdr)))) { + memcpy(val->ingress_eth.h_source, ehdr.h_dest, ETH_ALEN); + memcpy(val->ingress_eth.h_dest, ehdr.h_source, ETH_ALEN); + val->ingress_eth.h_proto = ehdr.h_proto; + val->eth_updated = true; + } } - if (unlikely(!val->ingress_ifindex)) - val->ingress_ifindex = ctx->ingress_ifindex; + if (!val->egress_dev) + val->egress_dev = parse_egress_dev(skb); - if (likely(val->ingress_dst)) - bpf_set_rx_dst(ctx, val->ingress_dst); + bpf_set_ingress_dev(skb, val->ingress_dev); + bpf_handle_ingress_ptype(skb); + bpf_set_ingress_dst(skb, val->sk); - return XDP_HISOCK_REDIRECT; + return HISOCK_REDIRECT; } static inline void ipv4_csum(struct iphdr *ihdr) @@ -203,8 +218,19 @@ int hisock_egress_prog(struct __sk_buff *skb) struct sock_tuple key = { 0 }; struct sock_value *val; struct ethhdr *ehdr; + struct tcphdr *thdr; struct iphdr *ihdr; - int ret; + + ihdr = (struct iphdr *)data; + if (ihdr + 1 > data_end) + return HISOCK_PASS; + + thdr = (struct tcphdr *)(ihdr + 1); + if (thdr + 1 > data_end) + return HISOCK_PASS; + + if (thdr->syn || thdr->fin || thdr->rst) + return HISOCK_PASS; key.saddr = skb->remote_ip4; key.sport = bpf_ntohl(skb->remote_port); @@ -215,18 +241,13 @@ int hisock_egress_prog(struct __sk_buff *skb) if (!val) return HISOCK_PASS; - if (unlikely(!val->eth_updated)) + if (!val->eth_updated) goto redirect; - ihdr = (struct iphdr *)data; - if (ihdr + 1 > data_end) - return HISOCK_PASS; - ihdr->tot_len = bpf_htons(skb->len); ipv4_csum(ihdr); - ret = bpf_skb_change_head(skb, ETH_HLEN, 0); - if (ret < 0) + if (bpf_skb_change_head(skb, ETH_HLEN, 0) < 0) goto redirect; data = (void *)(long)skb->data; @@ -236,10 +257,10 @@ int hisock_egress_prog(struct __sk_buff *skb) if (ehdr + 1 > data_end) return HISOCK_DROP; - bpf_ext_memcpy(ehdr, ETH_HLEN, &val->ingress_eth, ETH_HLEN); + memcpy(ehdr, &val->ingress_eth, ETH_HLEN); + bpf_handle_egress_ptype(skb); redirect: - if (likely(val->ingress_ifindex)) - bpf_change_skb_dev(skb, val->ingress_ifindex); + bpf_set_egress_dev(skb, val->egress_dev); return HISOCK_REDIRECT; } diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index cc00aebcb581..ea70fcbfc0ac 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -48,9 +48,8 @@ struct hisock_prog_info { const char *sec_name; enum bpf_prog_type prog_type; enum bpf_attach_type attach_type; - int attach_flag; + bool is_dev_attach; int prog_fd; - bool is_xdp; }; static struct hisock_prog_info prog_infos[] = { @@ -58,22 +57,17 @@ static struct hisock_prog_info prog_infos[] = { .sec_name = "hisock_sockops", .prog_type = BPF_PROG_TYPE_SOCK_OPS, .attach_type = BPF_CGROUP_SOCK_OPS, - .attach_flag = 0, - .is_xdp = false, }, { .sec_name = "hisock_ingress", - .prog_type = BPF_PROG_TYPE_XDP, - .attach_type = BPF_XDP, - .attach_flag = XDP_FLAGS_SKB_MODE, - .is_xdp = true, + .prog_type = BPF_PROG_TYPE_HISOCK, + .attach_type = BPF_HISOCK_INGRESS, + .is_dev_attach = true, }, { .sec_name = "hisock_egress", .prog_type = BPF_PROG_TYPE_HISOCK, .attach_type = BPF_HISOCK_EGRESS, - .attach_flag = 0, - .is_xdp = false, }, }; @@ -208,10 +202,9 @@ static int detach_progs(void) for (i = 0; i < ARRAY_SIZE(prog_infos); i++) { info = &prog_infos[i]; - if (info->is_xdp) { + if (info->is_dev_attach) { for (j = 0; j < hisock.if_num; j++) { - if (bpf_set_link_xdp_fd(hisock.ifindex[j], -1, - info->attach_flag)) { + if (bpf_prog_detach(hisock.ifindex[j], info->attach_type)) { fprintf(stderr, "ERROR: failed to detach prog %s\n", info->sec_name); @@ -244,17 +237,16 @@ static int attach_progs(void) for (i = 0; i < ARRAY_SIZE(prog_infos); i++) { info = &prog_infos[i]; - if (info->is_xdp) { + if (info->is_dev_attach) { for (j = 0; j < hisock.if_num; j++) { - if (bpf_set_link_xdp_fd(hisock.ifindex[j], info->prog_fd, - info->attach_flag)) + if (bpf_prog_attach(info->prog_fd, hisock.ifindex[j], + info->attach_type, 0)) goto fail; } continue; } - if (bpf_prog_attach(info->prog_fd, cgrp_fd, info->attach_type, - info->attach_flag)) + if (bpf_prog_attach(info->prog_fd, cgrp_fd, info->attach_type, 0)) goto fail; } -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Only deploy hisock in server. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 16 +++-------- samples/bpf/hisock/hisock_cmd.c | 50 +++++++++++++++------------------ 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 0478aa00e7ea..b56ac0b47062 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -21,9 +21,6 @@ #define IP_OFFSET 0x1FFF #define CSUM_SHIFT_BITS 16 -#define PORT_LOCAL 1 -#define PORT_REMOTE 2 - #define MAX_NUMA 8 #define MAX_CONN_NUMA 4096 #define MAX_CONN (MAX_CONN_NUMA * MAX_NUMA * 2) @@ -57,16 +54,12 @@ struct { __uint(max_entries, 128); } speed_port SEC(".maps"); -static inline bool is_speed_flow(u32 local, u32 remote) +static inline bool is_speed_flow(u16 port) { u8 *val; - val = bpf_map_lookup_elem(&speed_port, &local); - if (val && *val == PORT_LOCAL) - return true; - - val = bpf_map_lookup_elem(&speed_port, &remote); - if (val && *val == PORT_REMOTE) + val = bpf_map_lookup_elem(&speed_port, &port); + if (val && *val == 1) return true; return false; @@ -98,12 +91,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; - if (!is_speed_flow(skops->local_port, bpf_ntohl(skops->remote_port))) + if (!is_speed_flow(skops->local_port)) return 1; switch (skops->op) { case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: key.saddr = skops->remote_ip4; key.sport = bpf_ntohl(skops->remote_port); key.daddr = skops->local_ip4; diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index ea70fcbfc0ac..302be05f10f6 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -29,15 +29,12 @@ #include <bpf/libbpf.h> #define DEF_BPF_PATH "bpf.o" -#define PORT_LOCAL 1 -#define PORT_REMOTE 2 #define MAX_IF_NUM 8 struct { __u32 ifindex[MAX_IF_NUM]; int if_num; - char *local_port; - char *remote_port; + char *port; char *cgrp_path; char *bpf_path; bool unload; @@ -125,10 +122,11 @@ static int find_progs(struct bpf_object *obj) return 0; } -static int parse_port_range(const char *port_str, __u8 status, int map_fd) +static int parse_port_range(const char *port_str, int map_fd) { char *str = strdup(port_str); char *token, *rest = str; + __u8 val = 1; __u16 port; while ((token = strtok_r(rest, ",", &rest))) { @@ -144,18 +142,27 @@ static int parse_port_range(const char *port_str, __u8 status, int map_fd) return -1; } - for (port = start; port <= end; port++) - bpf_map_update_elem(map_fd, &port, &status, BPF_ANY); + for (port = start; port <= end; port++) { + if (bpf_map_update_elem(map_fd, &port, &val, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update port range\n"); + return -1; + } + } - printf("Speed port range %u-%u:%u\n", start, end, status); + printf("Speed port range: %u-%u\n", start, end); } else { port = atoi(token); if (port == 0 || port > 65535) { fprintf(stderr, "Invalid port: %s\n", token); return -1; } - bpf_map_update_elem(map_fd, &port, &status, BPF_ANY); - printf("Speed port %u:%u\n", port, status); + + if (bpf_map_update_elem(map_fd, &port, &val, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update port\n"); + return -1; + } + + printf("Speed port: %u\n", port); } } @@ -173,15 +180,8 @@ static int set_speed_port(struct bpf_object *obj) return -1; } - if (hisock.local_port && - parse_port_range(hisock.local_port, PORT_LOCAL, map_fd)) { - fprintf(stderr, "ERROR: failed to update local port\n"); - return -1; - } - - if (hisock.remote_port && - parse_port_range(hisock.remote_port, PORT_REMOTE, map_fd)) { - fprintf(stderr, "ERROR: failed to update remote port\n"); + if (hisock.port && parse_port_range(hisock.port, map_fd)) { + fprintf(stderr, "ERROR: failed to update speed port\n"); return -1; } @@ -310,7 +310,7 @@ static void do_help(void) { fprintf(stderr, "Load: hisock_cmd [-f BPF_FILE] [-c CGRP_PATH] " - "[-p LOCAL_PORT] [-r REMOTE_PORT] [-i INTERFACE]\n" + "[-p PORT] [-i INTERFACE]\n" "Unload: hisock_cmd -u [-c CGRP_PATH] [-i INTERFACE]\n"); } @@ -322,7 +322,7 @@ static int parse_args(int argc, char **argv) hisock.bpf_path = DEF_BPF_PATH; hisock.if_num = 0; - while ((opt = getopt(argc, argv, "f:c:p:r:i:uh")) != -1) { + while ((opt = getopt(argc, argv, "f:c:p:i:uh")) != -1) { switch (opt) { case 'f': hisock.bpf_path = optarg; @@ -331,10 +331,7 @@ static int parse_args(int argc, char **argv) hisock.cgrp_path = optarg; break; case 'p': - hisock.local_port = optarg; - break; - case 'r': - hisock.remote_port = optarg; + hisock.port = optarg; break; case 'i': ifname = optarg; @@ -356,8 +353,7 @@ static int parse_args(int argc, char **argv) if (hisock.cgrp_path == NULL || hisock.if_num == 0 || (!hisock.unload && - hisock.local_port == NULL && - hisock.remote_port == NULL)) { + hisock.port == NULL)) { do_help(); return -1; } -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add multi port parse to hisock_cmd. Now we can execute the following command to add multi port: hisock_cmd -p 5201 -p 5302 -p 5400-5411 Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/hisock_cmd.c | 45 +++++++++++++++++---------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 302be05f10f6..52f4d7d7978e 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -30,15 +30,16 @@ #define DEF_BPF_PATH "bpf.o" #define MAX_IF_NUM 8 +#define MAX_PORT_NUM 8 struct { __u32 ifindex[MAX_IF_NUM]; int if_num; - char *port; + char *port[MAX_PORT_NUM]; + int port_num; char *cgrp_path; char *bpf_path; bool unload; - bool help; } hisock; struct hisock_prog_info { @@ -172,7 +173,7 @@ static int parse_port_range(const char *port_str, int map_fd) static int set_speed_port(struct bpf_object *obj) { - int map_fd; + int map_fd, i; map_fd = bpf_object__find_map_fd_by_name(obj, "speed_port"); if (map_fd < 0) { @@ -180,9 +181,11 @@ static int set_speed_port(struct bpf_object *obj) return -1; } - if (hisock.port && parse_port_range(hisock.port, map_fd)) { - fprintf(stderr, "ERROR: failed to update speed port\n"); - return -1; + for (i = 0; i < hisock.port_num; i++) { + if (hisock.port[i] && parse_port_range(hisock.port[i], map_fd)) { + fprintf(stderr, "ERROR: failed to update speed port\n"); + return -1; + } } return 0; @@ -316,11 +319,9 @@ static void do_help(void) static int parse_args(int argc, char **argv) { - char *ifname; int opt; hisock.bpf_path = DEF_BPF_PATH; - hisock.if_num = 0; while ((opt = getopt(argc, argv, "f:c:p:i:uh")) != -1) { switch (opt) { @@ -331,29 +332,34 @@ static int parse_args(int argc, char **argv) hisock.cgrp_path = optarg; break; case 'p': - hisock.port = optarg; + hisock.port[hisock.port_num] = optarg; + hisock.port_num++; break; case 'i': - ifname = optarg; - hisock.ifindex[hisock.if_num] = if_nametoindex(ifname); + hisock.ifindex[hisock.if_num] = if_nametoindex(optarg); hisock.if_num++; break; case 'u': hisock.unload = true; break; case 'h': - hisock.help = true; - break; + do_help(); + exit(0); default: fprintf(stderr, "ERROR: unknown option %c\n", opt); return -1; } } - if (hisock.cgrp_path == NULL || - hisock.if_num == 0 || - (!hisock.unload && - hisock.port == NULL)) { + if (hisock.unload && + (hisock.cgrp_path == NULL || hisock.if_num == 0)) { + do_help(); + return -1; + } + + if (!hisock.unload && + (hisock.cgrp_path == NULL || hisock.if_num == 0 || + hisock.port_num == 0)) { do_help(); return -1; } @@ -368,11 +374,6 @@ int main(int argc, char **argv) return -1; } - if (hisock.help) { - do_help(); - return 0; - } - if (hisock.unload) { if (detach_progs()) { fprintf(stderr, "ERROR: failed to detach progs\n"); -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add target comm parse to hisock_cmd. Now we can execute the following command to speed up specific tasks: hisock_cmd -C iperf3 Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 30 +++++++++++++++++++++ samples/bpf/hisock/hisock_cmd.c | 48 ++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index b56ac0b47062..4536ea892bae 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -25,6 +25,8 @@ #define MAX_CONN_NUMA 4096 #define MAX_CONN (MAX_CONN_NUMA * MAX_NUMA * 2) +#define MAX_COMM_NUM 8 + struct sock_tuple { u32 saddr; u32 daddr; @@ -54,6 +56,13 @@ struct { __uint(max_entries, 128); } speed_port SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, sizeof(char[TASK_COMM_LEN])); + __uint(value_size, sizeof(u8)); + __uint(max_entries, MAX_COMM_NUM); +} target_comm SEC(".maps"); + static inline bool is_speed_flow(u16 port) { u8 *val; @@ -85,12 +94,33 @@ static inline void *parse_egress_dev(struct __sk_buff *skb) return dev; } +static void handle_listen_cb(struct bpf_sock_ops *skops) +{ + char comm[TASK_COMM_LEN] = { 0 }; + u8 *comm_val; + + bpf_get_current_comm(comm, sizeof(comm)); + + comm_val = bpf_map_lookup_elem(&target_comm, comm); + if (comm_val && *comm_val == 1) { + u16 key = skops->local_port; + u8 val = 1; + + bpf_map_update_elem(&speed_port, &key, &val, BPF_ANY); + } +} + SEC("hisock_sockops") int hisock_sockops_prog(struct bpf_sock_ops *skops) { struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; + if (skops->op == BPF_SOCK_OPS_TCP_LISTEN_CB) { + handle_listen_cb(skops); + return 1; + } + if (!is_speed_flow(skops->local_port)) return 1; diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 52f4d7d7978e..76422d7fa7eb 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -28,15 +28,22 @@ #include <bpf/bpf.h> #include <bpf/libbpf.h> +#ifndef TASK_COMM_LEN +#define TASK_COMM_LEN 16 +#endif + #define DEF_BPF_PATH "bpf.o" #define MAX_IF_NUM 8 #define MAX_PORT_NUM 8 +#define MAX_COMM_NUM 8 struct { __u32 ifindex[MAX_IF_NUM]; int if_num; char *port[MAX_PORT_NUM]; int port_num; + char *comm[MAX_COMM_NUM]; + int comm_num; char *cgrp_path; char *bpf_path; bool unload; @@ -191,6 +198,31 @@ static int set_speed_port(struct bpf_object *obj) return 0; } +static int set_target_comm(struct bpf_object *obj) +{ + int map_fd, i; + + map_fd = bpf_object__find_map_fd_by_name(obj, "target_comm"); + if (map_fd < 0) { + fprintf(stderr, "ERROR: failed to find map fd\n"); + return -1; + } + + for (i = 0; i < hisock.comm_num; i++) { + char key[TASK_COMM_LEN] = { 0 }; + __u8 val = 1; + + strncpy(key, hisock.comm[i], sizeof(key) - 1); + if (bpf_map_update_elem(map_fd, &key, &val, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update comm\n"); + return -1; + } + printf("Target comm: %s\n", key); + } + + return 0; +} + static int detach_progs(void) { struct hisock_prog_info *info; @@ -299,6 +331,12 @@ static int do_hisock(void) return -1; } + if (set_target_comm(obj)) { + fprintf(stderr, "ERROR: failed to set target comm\n"); + bpf_object__close(obj); + return -1; + } + if (attach_progs()) { fprintf(stderr, "ERROR: failed to attach progs\n"); bpf_object__close(obj); @@ -313,7 +351,7 @@ static void do_help(void) { fprintf(stderr, "Load: hisock_cmd [-f BPF_FILE] [-c CGRP_PATH] " - "[-p PORT] [-i INTERFACE]\n" + "[-p PORT] [-C COMM] [-i INTERFACE]\n" "Unload: hisock_cmd -u [-c CGRP_PATH] [-i INTERFACE]\n"); } @@ -323,7 +361,7 @@ static int parse_args(int argc, char **argv) hisock.bpf_path = DEF_BPF_PATH; - while ((opt = getopt(argc, argv, "f:c:p:i:uh")) != -1) { + while ((opt = getopt(argc, argv, "f:c:p:i:C:uh")) != -1) { switch (opt) { case 'f': hisock.bpf_path = optarg; @@ -339,6 +377,10 @@ static int parse_args(int argc, char **argv) hisock.ifindex[hisock.if_num] = if_nametoindex(optarg); hisock.if_num++; break; + case 'C': + hisock.comm[hisock.comm_num] = optarg; + hisock.comm_num++; + break; case 'u': hisock.unload = true; break; @@ -359,7 +401,7 @@ static int parse_args(int argc, char **argv) if (!hisock.unload && (hisock.cgrp_path == NULL || hisock.if_num == 0 || - hisock.port_num == 0)) { + (hisock.port_num == 0 && hisock.comm_num == 0))) { do_help(); return -1; } -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add ipv4-mapped ipv6 addr support for hisock. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 123 ++++++++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 34 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 4536ea892bae..a21aebe128be 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -74,6 +74,12 @@ static inline bool is_speed_flow(u16 port) return false; } +static inline bool is_ipv6_addr_mapped(u32 *addr6) +{ + return addr6[0] == 0 && addr6[1] == 0 && + addr6[2] == bpf_htonl(0x0000ffff); +} + static inline void *parse_ingress_dev(struct bpf_sock_ops *skops) { struct sk_buff *skb; @@ -110,52 +116,101 @@ static void handle_listen_cb(struct bpf_sock_ops *skops) } } -SEC("hisock_sockops") -int hisock_sockops_prog(struct bpf_sock_ops *skops) +static void +handle_remote_estd_cb(struct bpf_sock_ops *skops, u32 *laddr, u32 *raddr) { struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; - if (skops->op == BPF_SOCK_OPS_TCP_LISTEN_CB) { - handle_listen_cb(skops); - return 1; - } + key.saddr = *raddr; + key.daddr = *laddr; + key.sport = bpf_ntohl(skops->remote_port); + key.dport = skops->local_port; - if (!is_speed_flow(skops->local_port)) - return 1; + val.sk = skops->sk; + val.ingress_dev = parse_ingress_dev(skops); + + bpf_map_update_elem(&connmap, &key, &val, BPF_ANY); - switch (skops->op) { - case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - key.saddr = skops->remote_ip4; - key.sport = bpf_ntohl(skops->remote_port); - key.daddr = skops->local_ip4; - key.dport = skops->local_port; + bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); +} - val.sk = skops->sk; - val.ingress_dev = parse_ingress_dev(skops); +static inline void handle_passive_estd_inet_cb(struct bpf_sock_ops *skops) +{ + handle_remote_estd_cb(skops, &skops->local_ip4, &skops->remote_ip4); +} - bpf_map_update_elem(&connmap, &key, &val, BPF_ANY); +static inline void handle_passive_estd_inet6_cb(struct bpf_sock_ops *skops) +{ + handle_remote_estd_cb(skops, &skops->local_ip6[3], &skops->remote_ip6[3]); +} - bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); - break; - case BPF_SOCK_OPS_STATE_CB: - if (skops->args[1] != BPF_TCP_CLOSE_WAIT && - skops->args[1] != BPF_TCP_FIN_WAIT1 && - skops->args[1] != BPF_TCP_CLOSE) - break; +static void +handle_terminate_cb(struct bpf_sock_ops *skops, u32 *laddr, u32 *raddr) +{ + struct sock_tuple key = { 0 }; + + if (skops->args[1] != BPF_TCP_CLOSE_WAIT && + skops->args[1] != BPF_TCP_FIN_WAIT1 && + skops->args[1] != BPF_TCP_CLOSE) + return; + + key.saddr = *raddr; + key.daddr = *laddr; + key.sport = bpf_ntohl(skops->remote_port); + key.dport = skops->local_port; + + bpf_map_delete_elem(&connmap, &key); - key.saddr = skops->remote_ip4; - key.sport = bpf_ntohl(skops->remote_port); - key.daddr = skops->local_ip4; - key.dport = skops->local_port; + bpf_sock_ops_cb_flags_set(skops, + skops->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_STATE_CB_FLAG); +} + +static inline void handle_terminate_inet_cb(struct bpf_sock_ops *skops) +{ + handle_terminate_cb(skops, &skops->local_ip4, &skops->remote_ip4); +} - bpf_map_delete_elem(&connmap, &key); +static inline void handle_terminate_inet6_cb(struct bpf_sock_ops *skops) +{ + handle_terminate_cb(skops, &skops->local_ip6[3], &skops->remote_ip6[3]); +} + +SEC("hisock_sockops") +int hisock_sockops_prog(struct bpf_sock_ops *skops) +{ + if (skops->op == BPF_SOCK_OPS_TCP_LISTEN_CB) { + handle_listen_cb(skops); + return 1; + } - bpf_sock_ops_cb_flags_set(skops, - skops->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_STATE_CB_FLAG); - break; - default: - break; + if (skops->family == AF_INET) { + switch (skops->op) { + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + if (!is_speed_flow(skops->local_port)) + break; + handle_passive_estd_inet_cb(skops); + break; + case BPF_SOCK_OPS_STATE_CB: + handle_terminate_inet_cb(skops); + break; + default: + break; + } + } else if (skops->family == AF_INET6 && + is_ipv6_addr_mapped(skops->local_ip6)) { + switch (skops->op) { + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + if (!is_speed_flow(skops->local_port)) + break; + handle_passive_estd_inet6_cb(skops); + break; + case BPF_SOCK_OPS_STATE_CB: + handle_terminate_inet6_cb(skops); + break; + default: + break; + } } return 1; -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add local connect support for hisock. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- net/core/filter.c | 4 ++ samples/bpf/hisock/bpf.c | 107 +++++++++++++++++++++++++++++++- samples/bpf/hisock/hisock_cmd.c | 49 ++++++++++++++- 3 files changed, 156 insertions(+), 4 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 567bdb3cf0ba..37b41798d8bd 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7806,6 +7806,10 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) #endif case BPF_FUNC_tcp_sock: return &bpf_tcp_sock_proto; +#ifdef CONFIG_HISOCK + case BPF_FUNC_sk_release: + return &bpf_sk_release_proto; +#endif #endif /* CONFIG_INET */ case BPF_FUNC_get_current_comm: return &bpf_get_current_comm_proto; diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index a21aebe128be..1e05acc036fd 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -49,6 +49,13 @@ struct { __uint(max_entries, MAX_CONN); } connmap SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_SOCKHASH); + __uint(key_size, sizeof(struct sock_tuple)); + __uint(value_size, sizeof(int)); + __uint(max_entries, MAX_CONN); +} local_connmap SEC(".maps"); + struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(key_size, sizeof(u16)); @@ -74,6 +81,28 @@ static inline bool is_speed_flow(u16 port) return false; } +static inline bool +is_local_conn(struct bpf_sock_ops *skops, u32 *laddr, u32 *raddr) +{ + struct sock_tuple key = { 0 }; + struct bpf_sock *sk; + + if (*laddr == *raddr) + return true; + + key.saddr = *laddr; + key.daddr = *raddr; + key.sport = skops->local_port; + key.dport = bpf_ntohl(skops->remote_port); + + sk = bpf_map_lookup_elem(&local_connmap, &key); + if (!sk) + return false; + + bpf_sk_release(sk); + return true; +} + static inline bool is_ipv6_addr_mapped(u32 *addr6) { return addr6[0] == 0 && addr6[1] == 0 && @@ -116,6 +145,19 @@ static void handle_listen_cb(struct bpf_sock_ops *skops) } } +static void +handle_local_estd_cb(struct bpf_sock_ops *skops, u32 *laddr, u32 *raddr) +{ + struct sock_tuple key = { 0 }; + + key.saddr = *raddr; + key.daddr = *laddr; + key.sport = bpf_ntohl(skops->remote_port); + key.dport = skops->local_port; + + bpf_sock_hash_update(skops, &local_connmap, &key, BPF_NOEXIST); +} + static void handle_remote_estd_cb(struct bpf_sock_ops *skops, u32 *laddr, u32 *raddr) { @@ -137,12 +179,28 @@ handle_remote_estd_cb(struct bpf_sock_ops *skops, u32 *laddr, u32 *raddr) static inline void handle_passive_estd_inet_cb(struct bpf_sock_ops *skops) { - handle_remote_estd_cb(skops, &skops->local_ip4, &skops->remote_ip4); + if (is_local_conn(skops, &skops->local_ip4, &skops->remote_ip4)) + handle_local_estd_cb(skops, &skops->local_ip4, &skops->remote_ip4); + else + handle_remote_estd_cb(skops, &skops->local_ip4, &skops->remote_ip4); } static inline void handle_passive_estd_inet6_cb(struct bpf_sock_ops *skops) { - handle_remote_estd_cb(skops, &skops->local_ip6[3], &skops->remote_ip6[3]); + if (is_local_conn(skops, &skops->local_ip6[3], &skops->remote_ip6[3])) + handle_local_estd_cb(skops, &skops->local_ip6[3], &skops->remote_ip6[3]); + else + handle_remote_estd_cb(skops, &skops->local_ip6[3], &skops->remote_ip6[3]); +} + +static inline void handle_active_estd_inet_cb(struct bpf_sock_ops *skops) +{ + handle_local_estd_cb(skops, &skops->local_ip4, &skops->remote_ip4); +} + +static inline void handle_active_estd_inet6_cb(struct bpf_sock_ops *skops) +{ + handle_local_estd_cb(skops, &skops->local_ip6[3], &skops->remote_ip6[3]); } static void @@ -191,6 +249,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) break; handle_passive_estd_inet_cb(skops); break; + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + if (!is_speed_flow(bpf_ntohl(skops->remote_port))) + break; + handle_active_estd_inet_cb(skops); + break; case BPF_SOCK_OPS_STATE_CB: handle_terminate_inet_cb(skops); break; @@ -205,6 +268,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) break; handle_passive_estd_inet6_cb(skops); break; + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + if (!is_speed_flow(bpf_ntohl(skops->remote_port))) + break; + handle_active_estd_inet6_cb(skops); + break; case BPF_SOCK_OPS_STATE_CB: handle_terminate_inet6_cb(skops); break; @@ -216,6 +284,41 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) return 1; } +static void +msg_redirect_cb(struct sk_msg_md *msg, u32 *laddr, u32 *raddr) +{ + struct sock_tuple key = { 0 }; + + key.daddr = *raddr; + key.saddr = *laddr; + key.dport = bpf_ntohl(msg->remote_port); + key.sport = msg->local_port; + + bpf_msg_redirect_hash(msg, &local_connmap, &key, BPF_F_INGRESS); +} + +static inline void msg_redirect_inet_cb(struct sk_msg_md *msg) +{ + msg_redirect_cb(msg, &msg->local_ip4, &msg->remote_ip4); +} + +static inline void msg_redirect_inet6_cb(struct sk_msg_md *msg) +{ + msg_redirect_cb(msg, &msg->local_ip6[3], &msg->remote_ip6[3]); +} + +SEC("hisock_skmsg") +int hisock_skmsg_prog(struct sk_msg_md *msg) +{ + if (msg->family == AF_INET) + msg_redirect_inet_cb(msg); + else if (msg->family == AF_INET6 && + is_ipv6_addr_mapped(msg->local_ip6)) + msg_redirect_inet6_cb(msg); + + return SK_PASS; +} + SEC("hisock_ingress") int hisock_ingress_prog(struct __sk_buff *skb) { diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 76422d7fa7eb..874008e66732 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -32,6 +32,7 @@ #define TASK_COMM_LEN 16 #endif +#define HISOCK_BPFFS "/sys/fs/bpf/hisock" #define DEF_BPF_PATH "bpf.o" #define MAX_IF_NUM 8 #define MAX_PORT_NUM 8 @@ -51,9 +52,11 @@ struct { struct hisock_prog_info { const char *sec_name; + const char *pin_map; enum bpf_prog_type prog_type; enum bpf_attach_type attach_type; bool is_dev_attach; + bool is_skmsg; int prog_fd; }; @@ -63,6 +66,13 @@ static struct hisock_prog_info prog_infos[] = { .prog_type = BPF_PROG_TYPE_SOCK_OPS, .attach_type = BPF_CGROUP_SOCK_OPS, }, + { + .sec_name = "hisock_skmsg", + .prog_type = BPF_PROG_TYPE_SK_MSG, + .attach_type = BPF_SK_MSG_VERDICT, + .pin_map = "local_connmap", + .is_skmsg = true, + }, { .sec_name = "hisock_ingress", .prog_type = BPF_PROG_TYPE_HISOCK, @@ -249,6 +259,16 @@ static int detach_progs(void) continue; } + if (info->is_skmsg) { + char pin_path[64]; + + snprintf(pin_path, sizeof(pin_path), "%s/%s", + HISOCK_BPFFS, info->pin_map); + + unlink(pin_path); + continue; + } + if (bpf_prog_detach(cgrp_fd, info->attach_type)) { fprintf(stderr, "ERROR: failed to detach prog %s\n", info->sec_name); err_cnt++; @@ -259,7 +279,7 @@ static int detach_progs(void) return -err_cnt; } -static int attach_progs(void) +static int attach_progs(struct bpf_object *obj) { struct hisock_prog_info *info; int i, j, cgrp_fd; @@ -281,6 +301,31 @@ static int attach_progs(void) continue; } + if (info->is_skmsg) { + struct bpf_map *map; + char pin_path[64]; + + map = bpf_object__find_map_by_name(obj, info->pin_map); + if (!map) { + fprintf(stderr, "ERROR: failed to find pin map\n"); + goto fail; + } + + snprintf(pin_path, sizeof(pin_path), "%s/%s", + HISOCK_BPFFS, info->pin_map); + + if (bpf_map__pin(map, pin_path)) { + fprintf(stderr, "ERROR: failed to pin map\n"); + goto fail; + } + + if (bpf_prog_attach(info->prog_fd, bpf_map__fd(map), + info->attach_type, 0)) + goto fail; + + continue; + } + if (bpf_prog_attach(info->prog_fd, cgrp_fd, info->attach_type, 0)) goto fail; } @@ -337,7 +382,7 @@ static int do_hisock(void) return -1; } - if (attach_progs()) { + if (attach_progs(obj)) { fprintf(stderr, "ERROR: failed to attach progs\n"); bpf_object__close(obj); return -1; -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Deprecate hisock unused helpers and orig ingress logic. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- arch/arm64/include/asm/insn.h | 4 - arch/arm64/kernel/insn.c | 8 - arch/arm64/net/bpf_jit.h | 15 -- arch/arm64/net/bpf_jit_comp.c | 266 --------------------------------- include/linux/filter.h | 3 - include/net/xdp.h | 5 - include/uapi/linux/bpf.h | 36 ----- kernel/bpf/core.c | 7 - kernel/bpf/helpers.c | 27 ---- kernel/bpf/verifier.c | 25 ---- net/core/dev.c | 19 +-- net/core/filter.c | 120 --------------- tools/include/uapi/linux/bpf.h | 36 ----- 13 files changed, 3 insertions(+), 568 deletions(-) diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 01faf12ddaac..9b9ad2f6d4aa 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -208,10 +208,6 @@ enum aarch64_insn_ldst_type { AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX, AARCH64_INSN_LDST_LOAD_EX, AARCH64_INSN_LDST_STORE_EX, -#ifdef CONFIG_HISOCK - AARCH64_INSN_LDST_LOAD_PAIR_SIGNED_OFFSET, - AARCH64_INSN_LDST_STORE_PAIR_SIGNED_OFFSET, -#endif }; enum aarch64_insn_adsb_type { diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index 25390b069a05..fbd2b7eec1dc 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -745,14 +745,6 @@ u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1, case AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX: insn = aarch64_insn_get_stp_post_value(); break; -#ifdef CONFIG_HISOCK - case AARCH64_INSN_LDST_LOAD_PAIR_SIGNED_OFFSET: - insn = aarch64_insn_get_ldp_value(); - break; - case AARCH64_INSN_LDST_STORE_PAIR_SIGNED_OFFSET: - insn = aarch64_insn_get_stp_value(); - break; -#endif default: pr_err("%s: unknown load/store encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h index c670f35f302c..1835dffb8104 100644 --- a/arch/arm64/net/bpf_jit.h +++ b/arch/arm64/net/bpf_jit.h @@ -96,21 +96,6 @@ /* Rt = Rn[0]; Rt2 = Rn[8]; Rn += 16; */ #define A64_POP(Rt, Rt2, Rn) A64_LS_PAIR(Rt, Rt2, Rn, 16, LOAD, POST_INDEX) -#ifdef CONFIG_HISOCK -#define A64_STP(Rt, Rt2, Rn, offset) \ - A64_LS_PAIR(Rt, Rt2, Rn, offset, STORE, SIGNED_OFFSET) -#define A64_LDP(Rt, Rt2, Rn, offset) \ - A64_LS_PAIR(Rt, Rt2, Rn, offset, LOAD, SIGNED_OFFSET) -#define A64_STP32(Wt, Wt2, Rn, offset) \ - aarch64_insn_gen_load_store_pair(Wt, Wt2, Rn, offset, \ - AARCH64_INSN_VARIANT_32BIT, \ - AARCH64_INSN_LDST_STORE_PAIR_SIGNED_OFFSET) -#define A64_LDP32(Wt, Wt2, Rn, offset) \ - aarch64_insn_gen_load_store_pair(Wt, Wt2, Rn, offset, \ - AARCH64_INSN_VARIANT_32BIT, \ - AARCH64_INSN_LDST_LOAD_PAIR_SIGNED_OFFSET) -#endif - /* Load/store exclusive */ #define A64_SIZE(sf) \ ((sf) ? AARCH64_INSN_SIZE_64 : AARCH64_INSN_SIZE_32) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index e2e065382984..af5760c0d2e7 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -21,26 +21,11 @@ #include "bpf_jit.h" -#ifdef CONFIG_HISOCK -#define TCALL_CNT (MAX_BPF_JIT_REG + 0) -#define FP_BOTTOM (MAX_BPF_JIT_REG + 1) -#define TMP_REG_1 (MAX_BPF_JIT_REG + 2) -#define TMP_REG_2 (MAX_BPF_JIT_REG + 3) -#define TMP_REG_3 (MAX_BPF_JIT_REG + 4) -#define TMP_REG_4 (MAX_BPF_JIT_REG + 5) -#define TMP_REG_5 (MAX_BPF_JIT_REG + 6) -#define TMP_REG_6 (MAX_BPF_JIT_REG + 7) -#define TMP_REG_7 (MAX_BPF_JIT_REG + 8) -#define TMP_REG_8 (MAX_BPF_JIT_REG + 9) -#define TMP_REG_9 (MAX_BPF_JIT_REG + 10) -#define TMP_REG_10 (MAX_BPF_JIT_REG + 11) -#else #define TMP_REG_1 (MAX_BPF_JIT_REG + 0) #define TMP_REG_2 (MAX_BPF_JIT_REG + 1) #define TCALL_CNT (MAX_BPF_JIT_REG + 2) #define TMP_REG_3 (MAX_BPF_JIT_REG + 3) #define FP_BOTTOM (MAX_BPF_JIT_REG + 4) -#endif /* Map BPF registers to A64 registers */ static const int bpf2a64[] = { @@ -63,15 +48,6 @@ static const int bpf2a64[] = { [TMP_REG_1] = A64_R(10), [TMP_REG_2] = A64_R(11), [TMP_REG_3] = A64_R(12), -#ifdef CONFIG_HISOCK - [TMP_REG_4] = A64_R(13), - [TMP_REG_5] = A64_R(14), - [TMP_REG_6] = A64_R(15), - [TMP_REG_7] = A64_R(5), - [TMP_REG_8] = A64_R(6), - [TMP_REG_9] = A64_R(7), - [TMP_REG_10] = A64_R(28), -#endif /* tail_call_cnt */ [TCALL_CNT] = A64_R(26), /* temporary register for blinding constants */ @@ -589,234 +565,6 @@ static int add_exception_handler(const struct bpf_insn *insn, return 0; } -#ifdef CONFIG_HISOCK -static bool support_unaligned_access(void) -{ - unsigned long sctlr = SCTLR_ELx_A; - - switch (read_sysreg(CurrentEL)) { - case CurrentEL_EL1: - sctlr = read_sysreg(sctlr_el1); - break; - case CurrentEL_EL2: - sctlr = read_sysreg(sctlr_el2); - break; - default: - /* not EL1 and EL2 ? */ - break; - } - - return (sctlr & SCTLR_ELx_A) ? false : true; -} - -extern u64 bpf_ext_memcpy(void *dst, size_t dst_sz, - const void *src, size_t src_sz); - -static void emit_memcpy(struct jit_ctx *ctx, int size) -{ - u8 dst = bpf2a64[BPF_REG_1]; - u8 src = bpf2a64[BPF_REG_3]; - u8 tmp1 = bpf2a64[TMP_REG_1]; - u8 tmp2 = bpf2a64[TMP_REG_2]; - u8 tmp3 = bpf2a64[TMP_REG_3]; - u8 tmp4 = bpf2a64[TMP_REG_4]; - u8 tmp5 = bpf2a64[TMP_REG_5]; - u8 tmp6 = bpf2a64[TMP_REG_6]; - u8 tmp7 = bpf2a64[TMP_REG_7]; - u8 tmp8 = bpf2a64[TMP_REG_8]; - u8 tmp9 = bpf2a64[TMP_REG_9]; - u8 tmp10 = bpf2a64[TMP_REG_10]; - - if (!support_unaligned_access()) { - emit_call((u64)bpf_ext_memcpy, ctx); - return; - } - - switch (size) { - case 0: - break; - case 1: - emit(A64_LDRBI(tmp1, src, 0), ctx); - emit(A64_STRBI(tmp1, dst, 0), ctx); - break; - case 2: - emit(A64_LDRHI(tmp1, src, 0), ctx); - emit(A64_STRHI(tmp1, dst, 0), ctx); - break; - case 3: - emit(A64_LDRHI(tmp1, src, 0), ctx); - emit(A64_LDRBI(tmp2, src, 2), ctx); - emit(A64_STRHI(tmp1, dst, 0), ctx); - emit(A64_STRBI(tmp2, dst, 2), ctx); - break; - case 4: - emit(A64_LDR32I(tmp1, src, 0), ctx); - emit(A64_STR32I(tmp1, dst, 0), ctx); - break; - case 5: - emit(A64_LDR32I(tmp1, src, 0), ctx); - emit(A64_LDRBI(tmp2, src, 4), ctx); - emit(A64_STR32I(tmp1, dst, 0), ctx); - emit(A64_STRBI(tmp2, dst, 4), ctx); - break; - case 6: - emit(A64_LDR32I(tmp1, src, 0), ctx); - emit(A64_LDRHI(tmp2, src, 4), ctx); - emit(A64_STR32I(tmp1, dst, 0), ctx); - emit(A64_STRHI(tmp2, dst, 4), ctx); - break; - case 7: - emit(A64_LDR32I(tmp1, src, 0), ctx); - emit(A64_LDRHI(tmp2, src, 4), ctx); - emit(A64_LDRBI(tmp3, src, 6), ctx); - emit(A64_STR32I(tmp1, src, 0), ctx); - emit(A64_STRHI(tmp2, dst, 4), ctx); - emit(A64_STRBI(tmp3, dst, 6), ctx); - break; - case 8: - emit(A64_LDR64I(tmp1, src, 0), ctx); - emit(A64_STR64I(tmp1, dst, 0), ctx); - break; - case 9 ... 15: - emit(A64_ADD_I(1, tmp1, src, size), ctx); - emit(A64_ADD_I(1, tmp2, dst, size), ctx); - emit(A64_LDR64I(tmp3, src, 0), ctx); - emit(A64_LDP32(tmp4, tmp5, tmp1, -8), ctx); - emit(A64_STR64I(tmp3, dst, 0), ctx); - emit(A64_STP32(tmp4, tmp5, tmp2, -8), ctx); - break; - case 16: - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - break; - case 17 ... 31: - emit(A64_ADD_I(1, tmp1, src, size), ctx); - emit(A64_ADD_I(1, tmp2, dst, size), ctx); - emit(A64_LDP(tmp3, tmp4, src, 0), ctx); - emit(A64_LDP(tmp5, tmp6, tmp1, -16), ctx); - emit(A64_STP(tmp3, tmp4, dst, 0), ctx); - emit(A64_STP(tmp5, tmp6, tmp2, -16), ctx); - break; - case 32: - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_LDP(tmp3, tmp4, src, 16), ctx); - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - emit(A64_STP(tmp3, tmp4, dst, 16), ctx); - break; - case 33 ... 63: - emit(A64_ADD_I(1, tmp1, src, size), ctx); - emit(A64_ADD_I(1, tmp2, dst, size), ctx); - emit(A64_LDP(tmp3, tmp4, src, 0), ctx); - emit(A64_LDP(tmp5, tmp6, src, 16), ctx); - emit(A64_STP(tmp3, tmp4, dst, 0), ctx); - emit(A64_STP(tmp5, tmp6, dst, 16), ctx); - emit(A64_LDP(tmp3, tmp4, tmp1, -32), ctx); - emit(A64_LDP(tmp5, tmp6, tmp1, -16), ctx); - emit(A64_STP(tmp3, tmp4, tmp2, -32), ctx); - emit(A64_STP(tmp5, tmp6, tmp2, -16), ctx); - break; - case 64: - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_LDP(tmp3, tmp4, src, 16), ctx); - emit(A64_LDP(tmp5, tmp6, src, 32), ctx); - emit(A64_LDP(tmp7, tmp8, src, 48), ctx); - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - emit(A64_STP(tmp3, tmp4, dst, 16), ctx); - emit(A64_STP(tmp5, tmp6, dst, 32), ctx); - emit(A64_STP(tmp7, tmp8, dst, 48), ctx); - break; - case 65 ... 95: - /* copy first 48 bytes */ - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_LDP(tmp3, tmp4, src, 16), ctx); - emit(A64_LDP(tmp5, tmp6, src, 32), ctx); - - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - emit(A64_STP(tmp3, tmp4, dst, 16), ctx); - emit(A64_STP(tmp5, tmp6, dst, 32), ctx); - - /* copy last 48 bytes */ - emit(A64_ADD_I(1, tmp7, src, size), ctx); - emit(A64_ADD_I(1, tmp8, dst, size), ctx); - - emit(A64_LDP(tmp1, tmp2, tmp7, -48), ctx); - emit(A64_LDP(tmp3, tmp4, tmp7, -32), ctx); - emit(A64_LDP(tmp5, tmp6, tmp7, -16), ctx); - - emit(A64_STP(tmp1, tmp2, tmp8, -48), ctx); - emit(A64_STP(tmp3, tmp4, tmp8, -32), ctx); - emit(A64_STP(tmp5, tmp6, tmp8, -16), ctx); - break; - case 96: - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_LDP(tmp3, tmp4, src, 16), ctx); - emit(A64_LDP(tmp5, tmp6, src, 32), ctx); - emit(A64_LDP(tmp7, tmp8, src, 48), ctx); - - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - emit(A64_STP(tmp3, tmp4, dst, 16), ctx); - emit(A64_STP(tmp5, tmp6, dst, 32), ctx); - emit(A64_STP(tmp7, tmp8, dst, 48), ctx); - - emit(A64_LDP(tmp1, tmp2, src, 64), ctx); - emit(A64_LDP(tmp3, tmp4, src, 80), ctx); - emit(A64_STP(tmp1, tmp2, dst, 64), ctx); - emit(A64_STP(tmp3, tmp4, dst, 80), ctx); - break; - case 97 ... 127: - emit(A64_ADD_I(1, tmp9, src, size), ctx); - emit(A64_ADD_I(1, tmp10, dst, size), ctx); - - /* copy first 64 bytes */ - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_LDP(tmp3, tmp4, src, 16), ctx); - emit(A64_LDP(tmp5, tmp6, src, 32), ctx); - emit(A64_LDP(tmp7, tmp8, src, 48), ctx); - - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - emit(A64_STP(tmp3, tmp4, dst, 16), ctx); - emit(A64_STP(tmp5, tmp6, dst, 32), ctx); - emit(A64_STP(tmp7, tmp8, dst, 48), ctx); - - /* copy last 64 bytes */ - emit(A64_LDP(tmp1, tmp2, tmp9, -64), ctx); - emit(A64_LDP(tmp3, tmp4, tmp9, -48), ctx); - emit(A64_LDP(tmp5, tmp6, tmp9, -32), ctx); - emit(A64_LDP(tmp7, tmp8, tmp9, -16), ctx); - - emit(A64_STP(tmp1, tmp2, tmp10, -64), ctx); - emit(A64_STP(tmp3, tmp4, tmp10, -48), ctx); - emit(A64_STP(tmp5, tmp6, tmp10, -32), ctx); - emit(A64_STP(tmp7, tmp8, tmp10, -16), ctx); - break; - case 128: - emit(A64_LDP(tmp1, tmp2, src, 0), ctx); - emit(A64_LDP(tmp3, tmp4, src, 16), ctx); - emit(A64_LDP(tmp5, tmp6, src, 32), ctx); - emit(A64_LDP(tmp7, tmp8, src, 48), ctx); - - emit(A64_STP(tmp1, tmp2, dst, 0), ctx); - emit(A64_STP(tmp3, tmp4, dst, 16), ctx); - emit(A64_STP(tmp5, tmp6, dst, 32), ctx); - emit(A64_STP(tmp7, tmp8, dst, 48), ctx); - - emit(A64_LDP(tmp1, tmp2, src, 64), ctx); - emit(A64_LDP(tmp3, tmp4, src, 80), ctx); - emit(A64_LDP(tmp5, tmp6, src, 96), ctx); - emit(A64_LDP(tmp7, tmp8, src, 112), ctx); - - emit(A64_STP(tmp1, tmp2, dst, 64), ctx); - emit(A64_STP(tmp3, tmp4, dst, 80), ctx); - emit(A64_STP(tmp5, tmp6, dst, 96), ctx); - emit(A64_STP(tmp7, tmp8, dst, 112), ctx); - break; - default: - emit_call((u64)bpf_ext_memcpy, ctx); - break; - } -} -#endif - /* JITs an eBPF instruction. * Returns: * 0 - successfully JITed an 8-byte eBPF instruction. @@ -1167,13 +915,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool func_addr_fixed; u64 func_addr; -#ifdef CONFIG_HISOCK - if (insn->src_reg == 0 && insn->imm == BPF_FUNC_ext_memcpy) { - emit_memcpy(ctx, insn->off); - break; - } -#endif - ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &func_addr, &func_addr_fixed); if (ret < 0) @@ -1720,13 +1461,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) return prog; } -#ifdef CONFIG_HISOCK -bool bpf_jit_supports_ext_helper(void) -{ - return true; -} -#endif - u64 bpf_jit_alloc_exec_limit(void) { return BPF_JIT_REGION_SIZE; diff --git a/include/linux/filter.h b/include/linux/filter.h index 5b9f8648b1ab..3f533983b23e 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -922,9 +922,6 @@ u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog); void bpf_jit_compile(struct bpf_prog *prog); bool bpf_jit_needs_zext(void); -#ifdef CONFIG_HISOCK -bool bpf_jit_supports_ext_helper(void); -#endif u64 bpf_arch_uaddress_limit(void); bool bpf_helper_changes_pkt_data(enum bpf_func_id func_id); diff --git a/include/net/xdp.h b/include/net/xdp.h index 66434c2eae0d..90064cdab519 100644 --- a/include/net/xdp.h +++ b/include/net/xdp.h @@ -107,11 +107,6 @@ static __always_inline void xdp_buff_clear_frags_flag(struct xdp_buff *xdp) } #endif -struct hisock_xdp_buff { - struct xdp_buff xdp; - struct sk_buff *skb; -}; - /* Reserve memory area at end-of data area. * * This macro reserves tailroom in the XDP buffer by limiting the diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index f0840df75d35..fd5d840f8aae 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3944,37 +3944,6 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * void *bpf_get_rx_dst(struct bpf_sock_ops *skops) - * Description - * Get the ingress dst entry of the full sock. - * Return - * Valid ingress dst on success, or negative error - * in case of failure. - * - * int bpf_set_rx_dst(struct xdp_buff *xdp, void *dst) - * Description - * Set valid ingress dst entry to the skb associated - * with xdp_buff. - * Return - * 0 on success, or a negative error in case of failure. - * - * int bpf_change_skb_dev(void *ctx, u32 ifindex) - * Description - * Change ingress or egress device of the associated skb. - * Supports only BPF_PROG_TYPE_HISOCK and BPF_PROG_TYPE_XDP - * program types. - * - * *ctx* is either **struct xdp_md** for XDP programs or - * **struct __sk_buff** hisock_egress programs. - * Return - * 0 on success, or negative error in case of failure. - * - * int bpf_ext_memcpy(void *dst, size_t dst_sz, const void *src, size_t src_sz) - * Description - * Copy *src_sz* bytes from *src* to *dst* if *dst_sz* >= *src_sz*. - * Return - * 0 on success, or negative error in case of failure. - * * int bpf_set_ingress_dst(struct sk_buff *skb, void *sk) * Description * Set skb ingress dst entry with valid sock rx dst entry. @@ -4190,10 +4159,6 @@ union bpf_attr { FN(get_node_stats), \ FN(sched_net_rship_submit), \ FN(sched_set_task_prefer_cpumask), \ - FN(get_rx_dst), \ - FN(set_rx_dst), \ - FN(change_skb_dev), \ - FN(ext_memcpy), \ FN(set_ingress_dst), \ FN(get_skb_ethhdr), \ FN(set_ingress_dev), \ @@ -4567,7 +4532,6 @@ enum xdp_action { XDP_PASS, XDP_TX, XDP_REDIRECT, - XDP_HISOCK_REDIRECT = 100, }; /* user accessible metadata for XDP packet hook diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 6abc58b682a4..c2f5ff16b742 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2376,13 +2376,6 @@ bool __weak bpf_jit_needs_zext(void) return false; } -#ifdef CONFIG_HISOCK -bool __weak bpf_jit_supports_ext_helper(void) -{ - return false; -} -#endif - /* To execute LD_ABS/LD_IND instructions __bpf_prog_run() may call * skb_copy_bits(), so provide a weak definition of it for NET-less config. */ diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index be142202bb6f..205c880d9e01 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -665,29 +665,6 @@ const struct bpf_func_proto bpf_this_cpu_ptr_proto = { .arg1_type = ARG_PTR_TO_PERCPU_BTF_ID, }; -#ifdef CONFIG_HISOCK -BPF_CALL_4(bpf_ext_memcpy, void *, dst, size_t, dst_sz, - const void *, src, size_t, src_sz) -{ - if (dst_sz < src_sz) - return -EINVAL; - - memcpy(dst, src, src_sz); - return 0; -} - -const struct bpf_func_proto bpf_ext_memcpy_proto = { - .func = bpf_ext_memcpy, - .gpl_only = false, - .pkt_access = true, - .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM | MEM_UNINIT, - .arg2_type = ARG_CONST_SIZE, - .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, - .arg4_type = ARG_CONST_SIZE, -}; -#endif - const struct bpf_func_proto bpf_get_current_task_proto __weak; const struct bpf_func_proto bpf_probe_read_user_proto __weak; const struct bpf_func_proto bpf_probe_read_user_str_proto __weak; @@ -744,10 +721,6 @@ bpf_base_func_proto(enum bpf_func_id func_id) return &bpf_sched_tg_tag_of_proto; case BPF_FUNC_sched_task_tag_of: return &bpf_sched_task_tag_of_proto; -#ifdef CONFIG_HISOCK - case BPF_FUNC_ext_memcpy: - return &bpf_ext_memcpy_proto; -#endif default: break; } diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index fe05d95569d8..13df8a2fc4d7 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5894,21 +5894,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn return -EINVAL; } -#ifdef CONFIG_HISOCK - if (func_id == BPF_FUNC_ext_memcpy) { - /* XXX: cleanup & check if allowed to access dst mem */ - u32 regno = BPF_REG_1 + 3; - struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno]; - struct bpf_insn *insn = &env->prog->insnsi[env->insn_idx]; - - if (!bpf_jit_supports_ext_helper() || - reg->umax_value <= 0 || reg->umax_value > 4096) - return -ENOTSUPP; - - insn->off = reg->umax_value; - } -#endif - /* reset caller saved regs */ for (i = 0; i < CALLER_SAVED_REGS; i++) { mark_reg_not_init(env, regs, caller_saved[i]); @@ -10510,11 +10495,7 @@ static int do_check(struct bpf_verifier_env *env) env->jmps_processed++; if (opcode == BPF_CALL) { if (BPF_SRC(insn->code) != BPF_K || -#ifdef CONFIG_HISOCK - (insn->off != 0 && insn->imm != BPF_FUNC_ext_memcpy) || -#else insn->off != 0 || -#endif (insn->src_reg != BPF_REG_0 && insn->src_reg != BPF_PSEUDO_CALL) || insn->dst_reg != BPF_REG_0 || @@ -12240,12 +12221,6 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) continue; } -#ifdef CONFIG_HISOCK - /* will fixup bpf extension helper in jit */ - if (insn->imm == BPF_FUNC_ext_memcpy) - continue; -#endif - patch_call_imm: fn = env->ops->get_func_proto(insn->imm, env->prog); /* all functions that have prototype and verifier allowed diff --git a/net/core/dev.c b/net/core/dev.c index 27cb74f9ea32..00d7a299211c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4974,10 +4974,6 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, if (metalen) skb_metadata_set(skb, metalen); break; -#ifdef CONFIG_HISOCK - case XDP_HISOCK_REDIRECT: - break; -#endif default: bpf_warn_invalid_xdp_action(act); fallthrough; @@ -5082,31 +5078,22 @@ static DEFINE_STATIC_KEY_FALSE(generic_xdp_needed_key); int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb) { if (xdp_prog) { - struct hisock_xdp_buff hxdp; - struct xdp_buff *xdp = &hxdp.xdp; + struct xdp_buff xdp; u32 act; int err; - hxdp.skb = skb; - act = netif_receive_generic_xdp(skb, xdp, xdp_prog); + act = netif_receive_generic_xdp(skb, &xdp, xdp_prog); if (act != XDP_PASS) { switch (act) { case XDP_REDIRECT: err = xdp_do_generic_redirect(skb->dev, skb, - xdp, xdp_prog); + &xdp, xdp_prog); if (err) goto out_redir; break; case XDP_TX: generic_xdp_tx(skb, xdp_prog); break; -#ifdef CONFIG_HISOCK - case XDP_HISOCK_REDIRECT: - err = do_hisock_ingress_redirect(skb); - if (err == -EOPNOTSUPP) - return XDP_PASS; - break; -#endif } return XDP_DROP; } diff --git a/net/core/filter.c b/net/core/filter.c index 37b41798d8bd..e28857036d90 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3844,28 +3844,6 @@ static const struct bpf_func_proto bpf_handle_egress_ptype_proto = { .ret_type = RET_VOID, .arg1_type = ARG_PTR_TO_CTX, }; - -BPF_CALL_2(bpf_skb_change_skb_dev, struct sk_buff *, skb, u32, ifindex) -{ - struct net_device *dev; - - WARN_ON_ONCE(!rcu_read_lock_held()); - - dev = dev_get_by_index_rcu(&init_net, ifindex); - if (!dev) - return -ENODEV; - - skb->dev = dev; - return 0; -} - -static const struct bpf_func_proto bpf_skb_change_skb_dev_proto = { - .func = bpf_skb_change_skb_dev, - .gpl_only = false, - .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_ANYTHING, -}; #endif static u32 __bpf_skb_min_len(const struct sk_buff *skb) @@ -6537,64 +6515,6 @@ static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = { .arg5_type = ARG_ANYTHING, }; -#ifdef CONFIG_HISOCK -BPF_CALL_2(bpf_xdp_set_ingress_dst, struct xdp_buff *, xdp, void *, dst) -{ - struct hisock_xdp_buff *hxdp = (struct hisock_xdp_buff *)xdp; - struct dst_entry *_dst = (struct dst_entry *)dst; - - if (!hxdp->skb) - return -EOPNOTSUPP; - - if (!_dst || !virt_addr_valid(_dst)) - return -EFAULT; - - /* same as skb_valid_dst */ - if (_dst->flags & DST_METADATA) - return -EINVAL; - - skb_dst_set_noref(hxdp->skb, _dst); - return 0; -} - -static const struct bpf_func_proto bpf_xdp_set_ingress_dst_proto = { - .func = bpf_xdp_set_ingress_dst, - .gpl_only = false, - .pkt_access = true, - .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_ANYTHING, -}; -#endif - -#ifdef CONFIG_HISOCK -BPF_CALL_2(bpf_xdp_change_skb_dev, struct xdp_buff *, xdp, u32, ifindex) -{ - struct hisock_xdp_buff *hxdp = (void *)xdp; - struct net_device *dev; - - WARN_ON_ONCE(!rcu_read_lock_held()); - - if (!hxdp->skb) - return -EOPNOTSUPP; - - dev = dev_get_by_index_rcu(&init_net, ifindex); - if (!dev) - return -ENODEV; - - hxdp->skb->dev = dev; - return 0; -} - -static const struct bpf_func_proto bpf_xdp_change_skb_dev_proto = { - .func = bpf_xdp_change_skb_dev, - .gpl_only = false, - .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_ANYTHING, -}; -#endif - BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { @@ -7301,34 +7221,6 @@ static const struct bpf_func_proto bpf_sock_ops_reserve_hdr_opt_proto = { .arg3_type = ARG_ANYTHING, }; -#ifdef CONFIG_HISOCK -BTF_ID_LIST_SINGLE(btf_dst_entity_ids, struct, dst_entry) -BPF_CALL_1(bpf_sock_ops_get_ingress_dst, struct bpf_sock_ops_kern *, sops) -{ - struct sock *sk = sops->sk; - struct dst_entry *dst; - - WARN_ON_ONCE(!rcu_read_lock_held()); - - if (!sk || !sk_fullsock(sk)) - return (unsigned long)NULL; - - dst = rcu_dereference(sk->sk_rx_dst); - if (dst) - dst = dst_check(dst, 0); - - return (unsigned long)dst; -} - -const struct bpf_func_proto bpf_sock_ops_get_ingress_dst_proto = { - .func = bpf_sock_ops_get_ingress_dst, - .gpl_only = false, - .ret_type = RET_PTR_TO_BTF_ID_OR_NULL, - .arg1_type = ARG_PTR_TO_CTX, - .ret_btf_id = &btf_dst_entity_ids[0], -}; -#endif - #endif /* CONFIG_INET */ bool bpf_helper_changes_pkt_data(enum bpf_func_id func_id) @@ -7569,8 +7461,6 @@ hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_skb_change_head_proto; case BPF_FUNC_skb_adjust_room: return &bpf_skb_adjust_room_proto; - case BPF_FUNC_change_skb_dev: - return &bpf_skb_change_skb_dev_proto; case BPF_FUNC_set_ingress_dst: return is_ingress ? &bpf_set_ingress_dst_proto : NULL; case BPF_FUNC_get_skb_ethhdr: @@ -7733,12 +7623,6 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_xdp_adjust_tail_proto; case BPF_FUNC_fib_lookup: return &bpf_xdp_fib_lookup_proto; -#ifdef CONFIG_HISOCK - case BPF_FUNC_set_rx_dst: - return &bpf_xdp_set_ingress_dst_proto; - case BPF_FUNC_change_skb_dev: - return &bpf_xdp_change_skb_dev_proto; -#endif #ifdef CONFIG_INET case BPF_FUNC_sk_lookup_udp: return &bpf_xdp_sk_lookup_udp_proto; @@ -7800,10 +7684,6 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_sock_ops_store_hdr_opt_proto; case BPF_FUNC_reserve_hdr_opt: return &bpf_sock_ops_reserve_hdr_opt_proto; -#ifdef CONFIG_HISOCK - case BPF_FUNC_get_rx_dst: - return &bpf_sock_ops_get_ingress_dst_proto; -#endif case BPF_FUNC_tcp_sock: return &bpf_tcp_sock_proto; #ifdef CONFIG_HISOCK diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 7729ba3a13bb..1e4cfd165ff3 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3944,37 +3944,6 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * void *bpf_get_rx_dst(struct bpf_sock_ops *skops) - * Description - * Get the ingress dst entry of the full sock. - * Return - * Valid ingress dst on success, or negative error - * in case of failure. - * - * int bpf_set_rx_dst(struct xdp_buff *xdp, void *dst) - * Description - * Set valid ingress dst entry to the skb associated - * with xdp_buff. - * Return - * 0 on success, or negative error in case of failure. - * - * int bpf_change_skb_dev(void *ctx, u32 ifindex) - * Description - * Change ingress or egress device of the associated skb. - * Supports only BPF_PROG_TYPE_HISOCK and BPF_PROG_TYPE_XDP - * program types. - * - * *ctx* is either **struct xdp_md** for XDP programs or - * **struct __sk_buff** hisock_egress programs. - * Return - * 0 on success, or negative error in case of failure. - * - * int bpf_ext_memcpy(void *dst, size_t dst_sz, const void *src, size_t src_sz) - * Description - * Copy *src_sz* bytes from *src* to *dst* if *dst_sz* >= *src_sz*. - * Return - * 0 on success, or negative error in case of failure. - * * int bpf_set_ingress_dst(struct sk_buff *skb, void *sk) * Description * Set skb ingress dst entry with valid sock rx dst entry. @@ -4190,10 +4159,6 @@ union bpf_attr { FN(get_node_stats), \ FN(sched_net_rship_submit), \ FN(sched_set_task_prefer_cpumask), \ - FN(get_rx_dst), \ - FN(set_rx_dst), \ - FN(change_skb_dev), \ - FN(ext_memcpy), \ FN(set_ingress_dst), \ FN(get_skb_ethhdr), \ FN(set_ingress_dev), \ @@ -4571,7 +4536,6 @@ enum xdp_action { XDP_PASS, XDP_TX, XDP_REDIRECT, - XDP_HISOCK_REDIRECT = 100, }; /* user accessible metadata for XDP packet hook -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/20887 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/C7H... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/20887 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/C7H...
participants (2)
-
patchwork bot -
Pu Lehui