diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0f39fdcb2273c4ca42c7a00a88ec2a34e3faa886..01f99b5289320d5a44b7869ae3846c3840180a72 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3742,6 +3742,13 @@ union bpf_attr { * Return * The helper returns **TC_ACT_REDIRECT** on success or * **TC_ACT_SHOT** on error. + * + * int bpf_sock_tcp_send_reset(struct sk_buff *skb) + * Description + * Redirect If Netfirewall intercepts socket TCP interception, + * we need to actively send a reset packet to disconnect the current TCP connection. + * Return + * The helper returns Send packet reset sucess. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3900,8 +3907,13 @@ union bpf_attr { FN(per_cpu_ptr), \ FN(this_cpu_ptr), \ FN(redirect_peer), \ + FN(sock_tcp_send_reset), \ /* */ +#ifndef BPF_SOCK_TCP_SEND_RESET_ENABLE +#define BPF_SOCK_TCP_SEND_RESET_ENABLE +#endif // BPF_SOCK_TCP_SEND_RESET_ENABLE + /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call */ diff --git a/net/core/filter.c b/net/core/filter.c index 9343a911e9e247564c93e4314b7a55f4f47db8bd..3f8253b3b1c9cc2627f44ea54842d4d3fb089cb6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -77,6 +77,9 @@ #include #include #include +#include +#include +#include static const struct bpf_func_proto * bpf_sk_base_func_proto(enum bpf_func_id func_id); @@ -4616,6 +4619,33 @@ static const struct bpf_func_proto bpf_get_socket_cookie_proto = { .arg1_type = ARG_PTR_TO_CTX, }; +BPF_CALL_1(bpf_sock_tcp_send_reset, struct sk_buff *, skb) +{ +#if IS_ENABLED(CONFIG_NF_REJECT_IPV4) + //destroy tcp + struct sock *sk = sk_to_full_sk(skb->sk); + if (sk->sk_protocol == IPPROTO_TCP) { + struct net *net = dev_net(skb->dev); + int hook = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) | (1 << NF_INET_LOCAL_OUT); + if (sk->sk_family == AF_INET) { + nf_send_reset(net, skb, hook); +#if IS_ENABLED(CONFIG_NF_REJECT_IPV6) + } else if (sk->sk_family == AF_INET6) { + nf_send_reset6(net, skb, hook); +#endif + } + } +#endif + return 0; +} + +static const struct bpf_func_proto bpf_sock_tcp_send_reset_proto = { + .func = bpf_sock_tcp_send_reset, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, +}; + BPF_CALL_1(bpf_get_socket_cookie_sock_addr, struct bpf_sock_addr_kern *, ctx) { return __sock_gen_cookie(ctx->sk); @@ -7094,6 +7124,8 @@ cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_get_local_storage_proto; case BPF_FUNC_sk_fullsock: return &bpf_sk_fullsock_proto; + case BPF_FUNC_sock_tcp_send_reset: + return &bpf_sock_tcp_send_reset_proto; case BPF_FUNC_sk_storage_get: return &bpf_sk_storage_get_proto; case BPF_FUNC_sk_storage_delete: diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 1dd4b1acbcb07f815f9e3ca1f344c4df35b3077c..02e5dfca1941ebbc2d67edce37a58a38012047d1 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3742,6 +3742,13 @@ union bpf_attr { * Return * The helper returns **TC_ACT_REDIRECT** on success or * **TC_ACT_SHOT** on error. + * + * int bpf_sock_tcp_send_reset(struct sk_buff *skb) + * Description + * Redirect If Netfirewall intercepts socket TCP interception, + * we need to actively send a reset packet to disconnect the current TCP connection. + * Return + * The helper returns Send packet reset sucess. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -3900,8 +3907,13 @@ union bpf_attr { FN(per_cpu_ptr), \ FN(this_cpu_ptr), \ FN(redirect_peer), \ + FN(sock_tcp_send_reset), \ /* */ +#ifndef BPF_SOCK_TCP_SEND_RESET_ENABLE +#define BPF_SOCK_TCP_SEND_RESET_ENABLE +#endif // BPF_SOCK_TCP_SEND_RESET_ENABLE + /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call */