From 21b61b5ad52a8b76718a0d255020a87e87659e25 Mon Sep 17 00:00:00 2001 From: superCharge Date: Sat, 7 Oct 2023 14:23:28 +0800 Subject: [PATCH 1/3] Reconstruction to decouple cgroup_conn and sockops bpf logic Signed-off-by: superCharge --- bpf/kmesh/bpf2go/bpf2go.go | 3 - bpf/kmesh/cgroup_sock.c | 15 +-- bpf/kmesh/cluster.c | 136 ----------------------- bpf/kmesh/filter.c | 166 ---------------------------- bpf/kmesh/include/cluster.h | 114 +++++++++++++++++++ bpf/kmesh/include/ctx/ctx.h | 26 +++++ bpf/kmesh/include/ctx/sock_addr.h | 37 +++++++ bpf/kmesh/include/ctx/sock_ops.h | 34 ++++++ bpf/kmesh/include/filter.h | 149 ++++++++++++++++++++++++- bpf/kmesh/include/kmesh_common.h | 4 +- bpf/kmesh/include/listener.h | 6 +- bpf/kmesh/include/route_config.h | 122 +++++++++++++++++++- bpf/kmesh/include/tail_call.h | 2 +- bpf/kmesh/include/tcp_proxy.h | 2 +- bpf/kmesh/route_config.c | 136 ----------------------- bpf/kmesh/sockops.c | 12 +- kernel/ko_src/kmesh/defer_connect.c | 3 +- pkg/bpf/bpf_kmesh.go | 104 +++++------------ 18 files changed, 526 insertions(+), 545 deletions(-) delete mode 100644 bpf/kmesh/cluster.c delete mode 100644 bpf/kmesh/filter.c create mode 100644 bpf/kmesh/include/ctx/ctx.h create mode 100644 bpf/kmesh/include/ctx/sock_addr.h create mode 100644 bpf/kmesh/include/ctx/sock_ops.h delete mode 100644 bpf/kmesh/route_config.c diff --git a/bpf/kmesh/bpf2go/bpf2go.go b/bpf/kmesh/bpf2go/bpf2go.go index e64e0b8..94b4842 100644 --- a/bpf/kmesh/bpf2go/bpf2go.go +++ b/bpf/kmesh/bpf2go/bpf2go.go @@ -22,7 +22,4 @@ package bpf2go // go run github.com/cilium/ebpf/cmd/bpf2go --help //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshCgroupSock ../cgroup_sock.c -- -I../include -I../../include -I../../../api/v2-c //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshSockops ../sockops.c -- -I../include -I../../include -I../../../api/v2-c -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshFilter ../filter.c -- -I../include -I../../include -I../../../api/v2-c -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshRouteConfig ../route_config.c -- -I../include -I../../include -I../../../api/v2-c -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshCluster ../cluster.c -- -I../include -I../../include -I../../../api/v2-c //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshTracePoint ../tracepoint.c -- -I../include -I../../include diff --git a/bpf/kmesh/cgroup_sock.c b/bpf/kmesh/cgroup_sock.c index c1d970e..3ece999 100644 --- a/bpf/kmesh/cgroup_sock.c +++ b/bpf/kmesh/cgroup_sock.c @@ -20,21 +20,16 @@ #include #include #include "bpf_log.h" +#include "ctx/sock_addr.h" #include "listener.h" #include "listener/listener.pb-c.h" +#include "filter.h" +#include "cluster.h" + #if KMESH_ENABLE_IPV4 #if KMESH_ENABLE_HTTP static const char kmesh_module_name[] = "kmesh_defer"; -#ifdef DECLARE_VAR_ADDRESS -#undef DECLARE_VAR_ADDRESS -#define DECLARE_VAR_ADDRESS(ctx, name) \ - address_t name = {0}; \ - name.ipv4 = (ctx)->user_ip4; \ - name.port = (ctx)->user_port; \ - name.protocol = ((ctx)->protocol == IPPROTO_TCP) ? \ - CORE__SOCKET_ADDRESS__PROTOCOL__TCP: CORE__SOCKET_ADDRESS__PROTOCOL__UDP -#endif static inline int sock4_traffic_control(struct bpf_sock_addr *ctx) { @@ -51,6 +46,7 @@ static inline int sock4_traffic_control(struct bpf_sock_addr *ctx) if (!listener) return -ENOENT; } + BPF_LOG(DEBUG, KMESH, "bpf find listener addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); #if KMESH_ENABLE_HTTP // defer conn @@ -80,3 +76,4 @@ int cgroup_connect4_prog(struct bpf_sock_addr *ctx) char _license[] SEC("license") = "GPL"; int _version SEC("version") = 1; + diff --git a/bpf/kmesh/cluster.c b/bpf/kmesh/cluster.c deleted file mode 100644 index 2d937b5..0000000 --- a/bpf/kmesh/cluster.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - - * Author: nlgwcy - * Create: 2022-02-17 - */ - -#include "bpf_log.h" -#include "cluster.h" -#include "cluster/cluster.pb-c.h" -#include "tail_call.h" - -static inline void *loadbalance_round_robin(struct cluster_endpoints *eps) -{ - if (!eps || eps->ep_num == 0) - return NULL; - - __u32 idx = eps->last_round_robin_idx % eps->ep_num; - if (idx >= KMESH_PER_ENDPOINT_NUM) - return NULL; - - __sync_fetch_and_add(&eps->last_round_robin_idx, 1); - return (void *)eps->ep_identity[idx]; -} - -static inline void *cluster_get_ep_identity_by_lb_policy(struct cluster_endpoints *eps, __u32 lb_policy) -{ - void *ep_identity = NULL; - - switch (lb_policy) { - case CLUSTER__CLUSTER__LB_POLICY__ROUND_ROBIN: - ep_identity = loadbalance_round_robin(eps); - break; - default: - BPF_LOG(INFO, CLUSTER, "%d lb_policy is unsupport, defaut:ROUND_ROBIN\n", lb_policy); - ep_identity = loadbalance_round_robin(eps); - break; - } - return ep_identity; -} - -static inline Core__SocketAddress *cluster_get_ep_sock_addr(const void *ep_identity) -{ - Endpoint__Endpoint *ep = NULL; - Core__SocketAddress *sock_addr = NULL; - - ep = kmesh_get_ptr_val(ep_identity); - if (!ep) { - BPF_LOG(ERR, CLUSTER, "cluster get ep failed\n"); - return NULL; - } - - sock_addr = kmesh_get_ptr_val(ep->address); - if (!sock_addr) { - BPF_LOG(ERR, CLUSTER, "ep get sock addr failed\n"); - return NULL; - } - return sock_addr; -} - -static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_t *addr, ctx_buff_t *ctx) -{ - char *name = NULL; - void *ep_identity = NULL; - Core__SocketAddress *sock_addr = NULL; - struct cluster_endpoints *eps = NULL; - - name = kmesh_get_ptr_val(cluster->name); - if (!name) { - BPF_LOG(ERR, CLUSTER, "filed to get cluster\n"); - return -EAGAIN; - } - - eps = cluster_refresh_endpoints(cluster, name); - if (!eps) { - BPF_LOG(ERR, CLUSTER, "failed to reflush cluster(%s) endpoints\n", name); - return -EAGAIN; - } - - ep_identity = cluster_get_ep_identity_by_lb_policy(eps, cluster->lb_policy); - if (!ep_identity) { - BPF_LOG(ERR, CLUSTER, "cluster=\"%s\" handle lb failed, %u\n", name); - return -EAGAIN; - } - - sock_addr = cluster_get_ep_sock_addr(ep_identity); - if (!sock_addr) { - BPF_LOG(ERR, CLUSTER, "ep get sock addr failed, %ld\n", (__s64)ep_identity); - return -EAGAIN; - } - - BPF_LOG(DEBUG, CLUSTER, "cluster=\"%s\", loadbalance to addr=[%u:%u]\n", - name, sock_addr->ipv4, sock_addr->port); - SET_CTX_ADDRESS(ctx, sock_addr); - return 0; -} - -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_CLUSTER) -int cluster_manager(ctx_buff_t *ctx) -{ - int ret = 0; - ctx_key_t ctx_key = {0}; - ctx_val_t *ctx_val = NULL; - Cluster__Cluster *cluster = NULL; - - DECLARE_VAR_ADDRESS(ctx, addr); - - ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); - - ctx_val = kmesh_tail_lookup_ctx(&ctx_key); - if (ctx_val == NULL) - return convert_sock_errno(ENOENT); - - cluster = map_lookup_cluster(ctx_val->data); - kmesh_tail_delete_ctx(&ctx_key); - if (cluster == NULL) - return convert_sock_errno(ENOENT); - - ret = cluster_handle_loadbalance(cluster, &addr, ctx); - return convert_sock_errno(ret); -} - -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = 1; diff --git a/bpf/kmesh/filter.c b/bpf/kmesh/filter.c deleted file mode 100644 index 3925ffc..0000000 --- a/bpf/kmesh/filter.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - - * Author: nlgwcy - * Create: 2022-02-17 - */ - -#include "bpf_log.h" -#include "filter.h" -#include "tail_call.h" -#include "tcp_proxy.h" - -static inline int handle_http_connection_manager( - const Filter__HttpConnectionManager *http_conn, const address_t *addr, - ctx_buff_t *ctx, struct bpf_mem_ptr *msg) -{ - int ret; - char *route_name = NULL; - ctx_key_t ctx_key = {0}; - ctx_val_t ctx_val = {0}; - - route_name = kmesh_get_ptr_val((http_conn->route_config_name)); - if (!route_name) { - BPF_LOG(ERR, FILTER, "failed to get http conn route name\n"); - return -1; - } - - if (!bpf_strncpy(ctx_val.data, BPF_DATA_MAX_LEN, route_name)) { - BPF_LOG(ERR, FILTER, "http conn: route name(%s) copy failed:%d\n", route_name, ret); - return -1; - } - - ctx_key.address = *addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_ROUTER_CONFIG + bpf_get_current_task(); - ctx_val.msg = msg; - ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); - if (ret != 0) { - return -1; - } - - kmesh_tail_call(ctx, KMESH_TAIL_CALL_ROUTER_CONFIG); - kmesh_tail_delete_ctx(&ctx_key); - return 0; -} - -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER) -int filter_manager(ctx_buff_t *ctx) -{ - int ret = 0; - ctx_key_t ctx_key = {0}; - ctx_val_t *ctx_val = NULL; - Listener__Filter *filter = NULL; - Filter__HttpConnectionManager *http_conn = NULL; - Filter__TcpProxy *tcp_proxy = NULL; - - DECLARE_VAR_ADDRESS(ctx, addr); - ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); - ctx_val = kmesh_tail_lookup_ctx(&ctx_key); - if (!ctx_val) { - BPF_LOG(ERR, FILTER, "failed to lookup tail call val\n"); - return convert_sockops_ret(-1); - } - - filter = (Listener__Filter *)kmesh_get_ptr_val((void *)ctx_val->val); - if (!filter) { - BPF_LOG(ERR, FILTER, "failed to get filter\n"); - return convert_sockops_ret(-1); - } - kmesh_tail_delete_ctx(&ctx_key); - - switch (filter->config_type_case) { - case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER: - http_conn = kmesh_get_ptr_val(filter->http_connection_manager); - ret = bpf_parse_header_msg(ctx_val->msg); - if (GET_RET_PROTO_TYPE(ret) != PROTO_HTTP_1_1) { - BPF_LOG(DEBUG, FILTER, "http filter manager,only support http1.1 this version"); - return 0; - } - if (!http_conn) { - BPF_LOG(ERR, FILTER, "get http_conn failed\n"); - ret = -1; - break; - } - ret = handle_http_connection_manager(http_conn, &addr, ctx, ctx_val->msg); - break; - case LISTENER__FILTER__CONFIG_TYPE_TCP_PROXY: - tcp_proxy = kmesh_get_ptr_val(filter->tcp_proxy); - if (!tcp_proxy) { - BPF_LOG(ERR, FILTER, "get tcp_prxoy failed\n"); - ret = -1; - break; - } - ret = tcp_proxy_manager(tcp_proxy, ctx); - break; - default: - break; - } - return convert_sockops_ret(ret); -} - -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER_CHAIN) -int filter_chain_manager(ctx_buff_t *ctx) -{ - int ret = 0; - __u64 filter_idx = 0; - ctx_key_t ctx_key = {0}; - ctx_val_t ctx_val = {0}; - ctx_val_t *ctx_val_ptr = NULL; - Listener__FilterChain *filter_chain = NULL; - Listener__Filter *filter = NULL; - - DECLARE_VAR_ADDRESS(ctx, addr); - - ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER_CHAIN + bpf_get_current_task(); - - ctx_val_ptr = kmesh_tail_lookup_ctx(&ctx_key); - if (!ctx_val_ptr) { - BPF_LOG(ERR, FILTERCHAIN, "failed to lookup tail ctx\n"); - return convert_sockops_ret(-1); - } - kmesh_tail_delete_ctx(&ctx_key); - - filter_chain = (Listener__FilterChain *)kmesh_get_ptr_val((void *)ctx_val_ptr->val); - if (filter_chain == NULL) { - return convert_sockops_ret(-1); - } - /* filter match */ - ret = filter_chain_filter_match(filter_chain, &addr, ctx, &filter, &filter_idx); - if (ret != 0) { - BPF_LOG(ERR, FILTERCHAIN, "no match filter, addr=%u\n", addr.ipv4); - return convert_sockops_ret(-1); - } - - // FIXME: when filter_manager unsuccessful, - // we should skip back and handle next filter, rather than exit. - - ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); - ctx_val.val = filter_idx; - ctx_val.msg = ctx_val_ptr->msg; - ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); - if (ret != 0) { - BPF_LOG(ERR, FILTERCHAIN, "kmesh_tail_update_ctx failed:%d\n", ret); - return convert_sockops_ret(ret); - } - - kmesh_tail_call(ctx, KMESH_TAIL_CALL_FILTER); - kmesh_tail_delete_ctx(&ctx_key); - return 0; -} - -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = 1; diff --git a/bpf/kmesh/include/cluster.h b/bpf/kmesh/include/cluster.h index 4f15c55..9d49de5 100644 --- a/bpf/kmesh/include/cluster.h +++ b/bpf/kmesh/include/cluster.h @@ -19,7 +19,9 @@ #ifndef __KMESH_CLUSTER_H__ #define __KMESH_CLUSTER_H__ +#include "bpf_log.h" #include "kmesh_common.h" +#include "ctx/ctx.h" #include "tail_call.h" #include "cluster/cluster.pb-c.h" #include "endpoint/endpoint.pb-c.h" @@ -216,4 +218,116 @@ static inline struct cluster_endpoints *cluster_refresh_endpoints(const Cluster_ return NULL; return map_lookup_cluster_eps(name); } + +static inline void *loadbalance_round_robin(struct cluster_endpoints *eps) +{ + if (!eps || eps->ep_num == 0) + return NULL; + + __u32 idx = eps->last_round_robin_idx % eps->ep_num; + if (idx >= KMESH_PER_ENDPOINT_NUM) + return NULL; + + __sync_fetch_and_add(&eps->last_round_robin_idx, 1); + return (void *)eps->ep_identity[idx]; +} + +static inline void *cluster_get_ep_identity_by_lb_policy(struct cluster_endpoints *eps, __u32 lb_policy) +{ + void *ep_identity = NULL; + + switch (lb_policy) { + case CLUSTER__CLUSTER__LB_POLICY__ROUND_ROBIN: + ep_identity = loadbalance_round_robin(eps); + break; + default: + BPF_LOG(INFO, CLUSTER, "%d lb_policy is unsupport, defaut:ROUND_ROBIN\n", lb_policy); + ep_identity = loadbalance_round_robin(eps); + break; + } + return ep_identity; +} + +static inline Core__SocketAddress *cluster_get_ep_sock_addr(const void *ep_identity) +{ + Endpoint__Endpoint *ep = NULL; + Core__SocketAddress *sock_addr = NULL; + + ep = kmesh_get_ptr_val(ep_identity); + if (!ep) { + BPF_LOG(ERR, CLUSTER, "cluster get ep failed\n"); + return NULL; + } + + sock_addr = kmesh_get_ptr_val(ep->address); + if (!sock_addr) { + BPF_LOG(ERR, CLUSTER, "ep get sock addr failed\n"); + return NULL; + } + return sock_addr; +} + +static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_t *addr, struct ctx_buff_t *ctx) +{ + char *name = NULL; + void *ep_identity = NULL; + Core__SocketAddress *sock_addr = NULL; + struct cluster_endpoints *eps = NULL; + + name = kmesh_get_ptr_val(cluster->name); + if (!name) { + BPF_LOG(ERR, CLUSTER, "filed to get cluster\n"); + return -EAGAIN; + } + + eps = cluster_refresh_endpoints(cluster, name); + if (!eps) { + BPF_LOG(ERR, CLUSTER, "failed to reflush cluster(%s) endpoints\n", name); + return -EAGAIN; + } + + ep_identity = cluster_get_ep_identity_by_lb_policy(eps, cluster->lb_policy); + if (!ep_identity) { + BPF_LOG(ERR, CLUSTER, "cluster=\"%s\" handle lb failed, %u\n", name); + return -EAGAIN; + } + + sock_addr = cluster_get_ep_sock_addr(ep_identity); + if (!sock_addr) { + BPF_LOG(ERR, CLUSTER, "ep get sock addr failed, %ld\n", (__s64)ep_identity); + return -EAGAIN; + } + + BPF_LOG(INFO, CLUSTER, "cluster=\"%s\", loadbalance to addr=[%u:%u]\n", + name, sock_addr->ipv4, sock_addr->port); + SET_CTX_ADDRESS(ctx, sock_addr); + return 0; +} + +SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_CLUSTER) +int cluster_manager(struct ctx_buff_t *ctx) +{ + int ret = 0; + ctx_key_t ctx_key = {0}; + ctx_val_t *ctx_val = NULL; + Cluster__Cluster *cluster = NULL; + + DECLARE_VAR_ADDRESS(ctx, addr); + + ctx_key.address = addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); + + ctx_val = kmesh_tail_lookup_ctx(&ctx_key); + if (ctx_val == NULL) + return convert_sock_errno(ENOENT); + + cluster = map_lookup_cluster(ctx_val->data); + kmesh_tail_delete_ctx(&ctx_key); + if (cluster == NULL) + return convert_sock_errno(ENOENT); + + ret = cluster_handle_loadbalance(cluster, &addr, ctx); + return convert_sock_errno(ret); +} + #endif diff --git a/bpf/kmesh/include/ctx/ctx.h b/bpf/kmesh/include/ctx/ctx.h new file mode 100644 index 0000000..a271cc5 --- /dev/null +++ b/bpf/kmesh/include/ctx/ctx.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + * Author: supercharge-xsy + * Create: 2023-9-20 + */ + +#ifndef __BPF_CTX_H +#define __BPF_CTX_H + +#ifndef ctx_buff_t +# error "No __ctx_buff context defined. Please either include 'bpf/ctx/skb.h' or 'bpf/ctx/xdp.h'." +#endif + +#endif //__BPF_CTX_H diff --git a/bpf/kmesh/include/ctx/sock_addr.h b/bpf/kmesh/include/ctx/sock_addr.h new file mode 100644 index 0000000..f12c6c8 --- /dev/null +++ b/bpf/kmesh/include/ctx/sock_addr.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + * Author: supercharge-xsy + * Create: 2023-9-20 + */ + +#ifndef __BPF_CTX_SOCK_ADDR_H +#define __BPF_CTX_SOCK_ADDR_H + + +#define ctx_buff_t bpf_sock_addr + +#define DECLARE_VAR_ADDRESS(ctx, name) \ + address_t name = {0}; \ + name.ipv4 = (ctx)->user_ip4; \ + name.port = (ctx)->user_port; \ + name.protocol = ((ctx)->protocol == IPPROTO_TCP) ? \ + CORE__SOCKET_ADDRESS__PROTOCOL__TCP: CORE__SOCKET_ADDRESS__PROTOCOL__UDP + +#define SET_CTX_ADDRESS(ctx, address) \ + (ctx)->user_ip4 = (address)->ipv4; \ + (ctx)->user_port = (address)->port + + +#endif //__BPF_CTX_SOCK_ADDR_H diff --git a/bpf/kmesh/include/ctx/sock_ops.h b/bpf/kmesh/include/ctx/sock_ops.h new file mode 100644 index 0000000..85e769b --- /dev/null +++ b/bpf/kmesh/include/ctx/sock_ops.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + + * Author: supercharge-xsy + * Create: 2023-9-20 + */ + +#ifndef __BPF_CTX_SOCK_OPS_H +#define __BPF_CTX_SOCK_OPS_H + + +#define ctx_buff_t bpf_sock_ops + +#define DECLARE_VAR_ADDRESS(ctx, name) \ + address_t name = {0}; \ + bpf_memset(&name, 0, sizeof(name)); \ + name.ipv4 = (ctx)->remote_ip4; \ + name.port = (ctx)->remote_port +#define SET_CTX_ADDRESS(ctx, address) \ + (ctx)->remote_ip4 = (address)->ipv4; \ + (ctx)->remote_port = (address)->port + +#endif //__BPF_CTX_SOCK_OPS_H diff --git a/bpf/kmesh/include/filter.h b/bpf/kmesh/include/filter.h index 6bb1640..7166d85 100644 --- a/bpf/kmesh/include/filter.h +++ b/bpf/kmesh/include/filter.h @@ -18,13 +18,17 @@ #ifndef __KMESH_FILTER_H__ #define __KMESH_FILTER_H__ +#include "ctx/ctx.h" +#include "tcp_proxy.h" +#include "tail_call.h" +#include "bpf_log.h" #include "kmesh_common.h" #include "listener/listener.pb-c.h" #include "filter/tcp_proxy.pb-c.h" #include "filter/http_connection_manager.pb-c.h" -static inline int filter_match_check(const Listener__Filter *filter, const address_t *addr, const ctx_buff_t *ctx) +static inline int filter_match_check(const Listener__Filter *filter, const address_t *addr, const struct ctx_buff_t *ctx) { int match = 0; switch (filter->config_type_case) { @@ -42,7 +46,7 @@ static inline int filter_match_check(const Listener__Filter *filter, const addre static inline int filter_chain_filter_match(const Listener__FilterChain *filter_chain, const address_t *addr, - const ctx_buff_t *ctx, + const struct ctx_buff_t *ctx, Listener__Filter **filter_ptr, __u64 *filter_ptr_idx) { @@ -86,4 +90,145 @@ static inline int filter_chain_filter_match(const Listener__FilterChain *filter_ } return -1; } + +static inline int handle_http_connection_manager( + const Filter__HttpConnectionManager *http_conn, const address_t *addr, + struct ctx_buff_t *ctx, struct bpf_mem_ptr *msg) +{ + int ret; + char *route_name = NULL; + ctx_key_t ctx_key = {0}; + ctx_val_t ctx_val = {0}; + + route_name = kmesh_get_ptr_val((http_conn->route_config_name)); + if (!route_name) { + BPF_LOG(ERR, FILTER, "failed to get http conn route name\n"); + return -1; + } + + if (!bpf_strncpy(ctx_val.data, BPF_DATA_MAX_LEN, route_name)) { + BPF_LOG(ERR, FILTER, "http conn: route name(%s) copy failed:%d\n", route_name, ret); + return -1; + } + + ctx_key.address = *addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_ROUTER_CONFIG + bpf_get_current_task(); + ctx_val.msg = msg; + ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); + if (ret != 0) { + return -1; + } + + kmesh_tail_call(ctx, KMESH_TAIL_CALL_ROUTER_CONFIG); + kmesh_tail_delete_ctx(&ctx_key); + return 0; +} + +SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER) +int filter_manager(struct ctx_buff_t *ctx) +{ + int ret = 0; + ctx_key_t ctx_key = {0}; + ctx_val_t *ctx_val = NULL; + Listener__Filter *filter = NULL; + Filter__HttpConnectionManager *http_conn = NULL; + Filter__TcpProxy *tcp_proxy = NULL; + + DECLARE_VAR_ADDRESS(ctx, addr); + ctx_key.address = addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); + ctx_val = kmesh_tail_lookup_ctx(&ctx_key); + if (!ctx_val) { + BPF_LOG(ERR, FILTER, "failed to lookup tail call val\n"); + return convert_sockops_ret(-1); + } + + filter = (Listener__Filter *)kmesh_get_ptr_val((void *)ctx_val->val); + if (!filter) { + BPF_LOG(ERR, FILTER, "failed to get filter\n"); + return convert_sockops_ret(-1); + } + kmesh_tail_delete_ctx(&ctx_key); + + switch (filter->config_type_case) { + case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER: + http_conn = kmesh_get_ptr_val(filter->http_connection_manager); + ret = bpf_parse_header_msg(ctx_val->msg); + if (GET_RET_PROTO_TYPE(ret) != PROTO_HTTP_1_1) { + BPF_LOG(DEBUG, FILTER, "http filter manager,only support http1.1 this version"); + return 0; + } + if (!http_conn) { + BPF_LOG(ERR, FILTER, "get http_conn failed\n"); + ret = -1; + break; + } + ret = handle_http_connection_manager(http_conn, &addr, ctx, ctx_val->msg); + break; + case LISTENER__FILTER__CONFIG_TYPE_TCP_PROXY: + tcp_proxy = kmesh_get_ptr_val(filter->tcp_proxy); + if (!tcp_proxy) { + BPF_LOG(ERR, FILTER, "get tcp_prxoy failed\n"); + ret = -1; + break; + } + ret = tcp_proxy_manager(tcp_proxy, ctx); + break; + default: + break; + } + return convert_sockops_ret(ret); +} + +SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER_CHAIN) +int filter_chain_manager(struct ctx_buff_t *ctx) +{ + int ret = 0; + __u64 filter_idx = 0; + ctx_key_t ctx_key = {0}; + ctx_val_t ctx_val = {0}; + ctx_val_t *ctx_val_ptr = NULL; + Listener__FilterChain *filter_chain = NULL; + Listener__Filter *filter = NULL; + + DECLARE_VAR_ADDRESS(ctx, addr); + + ctx_key.address = addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER_CHAIN + bpf_get_current_task(); + + ctx_val_ptr = kmesh_tail_lookup_ctx(&ctx_key); + if (!ctx_val_ptr) { + BPF_LOG(ERR, FILTERCHAIN, "failed to lookup tail ctx\n"); + return convert_sockops_ret(-1); + } + kmesh_tail_delete_ctx(&ctx_key); + + filter_chain = (Listener__FilterChain *)kmesh_get_ptr_val((void *)ctx_val_ptr->val); + if (filter_chain == NULL) { + return convert_sockops_ret(-1); + } + /* filter match */ + ret = filter_chain_filter_match(filter_chain, &addr, ctx, &filter, &filter_idx); + if (ret != 0) { + BPF_LOG(ERR, FILTERCHAIN, "no match filter, addr=%u\n", addr.ipv4); + return convert_sockops_ret(-1); + } + + // FIXME: when filter_manager unsuccessful, + // we should skip back and handle next filter, rather than exit. + + ctx_key.address = addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); + ctx_val.val = filter_idx; + ctx_val.msg = ctx_val_ptr->msg; + ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); + if (ret != 0) { + BPF_LOG(ERR, FILTERCHAIN, "kmesh_tail_update_ctx failed:%d\n", ret); + return convert_sockops_ret(ret); + } + + kmesh_tail_call(ctx, KMESH_TAIL_CALL_FILTER); + kmesh_tail_delete_ctx(&ctx_key); + return 0; +} #endif diff --git a/bpf/kmesh/include/kmesh_common.h b/bpf/kmesh/include/kmesh_common.h index 2f495a8..fc4dde3 100644 --- a/bpf/kmesh/include/kmesh_common.h +++ b/bpf/kmesh/include/kmesh_common.h @@ -62,7 +62,7 @@ struct { __uint(map_flags, 0); } inner_map SEC(".maps"); -#if 1 +/*#if 1 typedef struct bpf_sock_ops ctx_buff_t; #define DECLARE_VAR_ADDRESS(ctx, name) \ address_t name = {0}; \ @@ -83,7 +83,7 @@ typedef struct bpf_sock_addr ctx_buff_t; (ctx)->user_ip4 = (address)->ipv4; \ (ctx)->user_port = (address)->port; \ (ctx)->protocol = (address)->protocol -#endif +#endif*/ typedef Core__SocketAddress address_t; diff --git a/bpf/kmesh/include/listener.h b/bpf/kmesh/include/listener.h index f853424..c50ba64 100644 --- a/bpf/kmesh/include/listener.h +++ b/bpf/kmesh/include/listener.h @@ -37,7 +37,7 @@ static inline Listener__Listener *map_lookup_listener(const address_t *addr) static inline bool listener_filter_chain_match_check(const Listener__FilterChain *filter_chain, const address_t *addr, - const ctx_buff_t *ctx) + const struct ctx_buff_t *ctx) { char *transport_protocol; const char buf[] = "raw_buffer"; @@ -69,7 +69,7 @@ static inline bool listener_filter_chain_match_check(const Listener__FilterChain static inline int listener_filter_chain_match(const Listener__Listener *listener, const address_t *addr, - const ctx_buff_t *ctx, + const struct ctx_buff_t *ctx, Listener__FilterChain **filter_chain_ptr, __u64 *filter_chain_idx) { @@ -107,7 +107,7 @@ static inline int listener_filter_chain_match(const Listener__Listener *listener return -1; } -static inline int listener_manager(ctx_buff_t *ctx, Listener__Listener *listener, struct bpf_mem_ptr *msg) +static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *listener, struct bpf_mem_ptr *msg) { int ret = 0; __u64 filter_chain_idx = 0; diff --git a/bpf/kmesh/include/route_config.h b/bpf/kmesh/include/route_config.h index f9aa37c..43125e2 100644 --- a/bpf/kmesh/include/route_config.h +++ b/bpf/kmesh/include/route_config.h @@ -18,9 +18,11 @@ #ifndef __ROUTE_CONFIG_H__ #define __ROUTE_CONFIG_H__ +#include "bpf_log.h" #include "kmesh_common.h" #include "tail_call.h" #include "route/route.pb-c.h" +#include "ctx/ctx.h" #define ROUTER_NAME_MAX_LEN BPF_DATA_MAX_LEN @@ -41,7 +43,7 @@ static inline Route__RouteConfiguration *map_lookup_route_config(const char *rou } static inline int virtual_host_match_check(Route__VirtualHost *virt_host, - address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *uri) + address_t *addr, struct ctx_buff_t *ctx, struct bpf_mem_ptr *uri) { int i; void *domains = NULL; @@ -97,7 +99,7 @@ static inline bool VirtualHost_check_allow_any(char *name) { static inline Route__VirtualHost *virtual_host_match(Route__RouteConfiguration *route_config, address_t *addr, - ctx_buff_t *ctx) + struct ctx_buff_t *ctx) { int i; void *ptrs = NULL; @@ -225,7 +227,7 @@ static inline bool check_headers_match(Route__RouteMatch *match) { } static inline int virtual_host_route_match_check(Route__Route *route, - address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) + address_t *addr, struct ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { Route__RouteMatch *match; char *prefix; @@ -258,7 +260,7 @@ static inline int virtual_host_route_match_check(Route__Route *route, } static inline Route__Route *virtual_host_route_match(Route__VirtualHost *virt_host, - address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) + address_t *addr, struct ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { int i; void *ptrs = NULL; @@ -289,4 +291,116 @@ static inline Route__Route *virtual_host_route_match(Route__VirtualHost *virt_ho } return NULL; } + +static inline char *select_weight_cluster(Route__RouteAction *route_act) { + void *ptr = NULL; + Route__WeightedCluster *weightedCluster = NULL; + Route__ClusterWeight *route_cluster_weight = NULL; + int32_t select_value; + void *cluster_name = NULL; + + weightedCluster = kmesh_get_ptr_val((route_act->weighted_clusters)); + if (!weightedCluster) { + return NULL; + } + ptr = kmesh_get_ptr_val(weightedCluster->clusters); + if (!ptr) { + return NULL; + } + select_value = (int)(bpf_get_prandom_u32() % 100); + for (int i = 0; i < KMESH_PER_WEIGHT_CLUSTER_NUM; i ++) { + if (i >= weightedCluster->n_clusters) { + break; + } + route_cluster_weight = (Route__ClusterWeight *) kmesh_get_ptr_val( + (void *) *((__u64 *) ptr + i)); + if (!route_cluster_weight) { + return NULL; + } + select_value = select_value - (int)route_cluster_weight->weight; + if (select_value <= 0) { + cluster_name = kmesh_get_ptr_val(route_cluster_weight->name); + BPF_LOG(DEBUG, ROUTER_CONFIG, "select cluster, name:weight %s:%d\n", + cluster_name, route_cluster_weight->weight); + return cluster_name; + } + } + return NULL; +} + +static inline char *route_get_cluster(const Route__Route *route) +{ + Route__RouteAction *route_act = NULL; + route_act = kmesh_get_ptr_val(_(route->route)); + if (!route_act) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get route action ptr\n"); + return NULL; + } + + if (route_act->cluster_specifier_case == ROUTE__ROUTE_ACTION__CLUSTER_SPECIFIER_WEIGHTED_CLUSTERS) { + return select_weight_cluster(route_act); + } + + return kmesh_get_ptr_val(_(route_act->cluster)); +} + +SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_ROUTER_CONFIG) +int route_config_manager(struct ctx_buff_t *ctx) +{ + int ret; + char *cluster = NULL; + ctx_key_t ctx_key = {0}; + ctx_val_t *ctx_val = NULL; + ctx_val_t ctx_val_1 = {0}; + Route__RouteConfiguration *route_config = NULL; + Route__VirtualHost *virt_host = NULL; + Route__Route *route = NULL; + + DECLARE_VAR_ADDRESS(ctx, addr); + ctx_key.address = addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_ROUTER_CONFIG + bpf_get_current_task(); + ctx_val = kmesh_tail_lookup_ctx(&ctx_key); + if (!ctx_val) + return convert_sockops_ret(-1); + + route_config = map_lookup_route_config(ctx_val->data); + kmesh_tail_delete_ctx(&ctx_key); + if (!route_config) { + BPF_LOG(WARN, ROUTER_CONFIG, "failed to lookup route config, route_name=\"%s\"\n", ctx_val->data); + return convert_sockops_ret(-1); + } + + virt_host = virtual_host_match(route_config, &addr, ctx); + if (!virt_host) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to match virtual host, addr=%u\n", addr.ipv4); + return convert_sockops_ret(-1); + } + + route = virtual_host_route_match(virt_host, &addr, ctx, (struct bpf_mem_ptr *)ctx_val->msg); + if (!route) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to match route action, addr=%u\n", addr.ipv4); + return convert_sockops_ret(-1); + } + + cluster = route_get_cluster(route); + if (!cluster) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get cluster\n"); + return convert_sockops_ret(-1); + } + + ctx_key.address = addr; + ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); + if (!bpf_strncpy(ctx_val_1.data, BPF_DATA_MAX_LEN, cluster)) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to copy cluster %s\n", cluster); + return convert_sockops_ret(-1); + } + + ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val_1); + if (ret != 0) + return convert_sockops_ret(ret); + + kmesh_tail_call(ctx, KMESH_TAIL_CALL_CLUSTER); + kmesh_tail_delete_ctx(&ctx_key); + return 0; +} #endif diff --git a/bpf/kmesh/include/tail_call.h b/bpf/kmesh/include/tail_call.h index 4fa1bf5..bec5901 100644 --- a/bpf/kmesh/include/tail_call.h +++ b/bpf/kmesh/include/tail_call.h @@ -44,7 +44,7 @@ struct { __uint(map_flags, 0); } map_of_tail_call_prog SEC(".maps"); -static inline void kmesh_tail_call(ctx_buff_t *ctx, const __u32 index) +static inline void kmesh_tail_call(struct ctx_buff_t *ctx, const __u32 index) { bpf_tail_call(ctx, &map_of_tail_call_prog, index); } diff --git a/bpf/kmesh/include/tcp_proxy.h b/bpf/kmesh/include/tcp_proxy.h index 4342b7e..9e920df 100644 --- a/bpf/kmesh/include/tcp_proxy.h +++ b/bpf/kmesh/include/tcp_proxy.h @@ -70,7 +70,7 @@ static inline char *tcp_proxy_get_cluster(const Filter__TcpProxy *tcpProxy) return (char*)kmesh_get_ptr_val(tcpProxy->cluster); } -static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, ctx_buff_t *ctx) +static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, struct ctx_buff_t *ctx) { int ret; char *cluster = NULL; diff --git a/bpf/kmesh/route_config.c b/bpf/kmesh/route_config.c deleted file mode 100644 index 86c0039..0000000 --- a/bpf/kmesh/route_config.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - - * Author: nlgwcy - * Create: 2022-02-15 - */ - -#include "bpf_log.h" -#include "route_config.h" -#include "tail_call.h" - -static inline char *select_weight_cluster(Route__RouteAction *route_act) { - void *ptr = NULL; - Route__WeightedCluster *weightedCluster = NULL; - Route__ClusterWeight *route_cluster_weight = NULL; - int32_t select_value; - void *cluster_name = NULL; - - weightedCluster = kmesh_get_ptr_val((route_act->weighted_clusters)); - if (!weightedCluster) { - return NULL; - } - ptr = kmesh_get_ptr_val(weightedCluster->clusters); - if (!ptr) { - return NULL; - } - select_value = (int)(bpf_get_prandom_u32() % 100); - for (int i = 0; i < KMESH_PER_WEIGHT_CLUSTER_NUM; i ++) { - if (i >= weightedCluster->n_clusters) { - break; - } - route_cluster_weight = (Route__ClusterWeight *) kmesh_get_ptr_val( - (void *) *((__u64 *) ptr + i)); - if (!route_cluster_weight) { - return NULL; - } - select_value = select_value - (int)route_cluster_weight->weight; - if (select_value <= 0) { - cluster_name = kmesh_get_ptr_val(route_cluster_weight->name); - BPF_LOG(DEBUG, ROUTER_CONFIG, "select cluster, name:weight %s:%d\n", - cluster_name, route_cluster_weight->weight); - return cluster_name; - } - } - return NULL; -} - -static inline char *route_get_cluster(const Route__Route *route) -{ - Route__RouteAction *route_act = NULL; - route_act = kmesh_get_ptr_val(_(route->route)); - if (!route_act) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get route action ptr\n"); - return NULL; - } - - if (route_act->cluster_specifier_case == ROUTE__ROUTE_ACTION__CLUSTER_SPECIFIER_WEIGHTED_CLUSTERS) { - return select_weight_cluster(route_act); - } - - return kmesh_get_ptr_val(_(route_act->cluster)); -} - -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_ROUTER_CONFIG) -int route_config_manager(ctx_buff_t *ctx) -{ - int ret; - char *cluster = NULL; - ctx_key_t ctx_key = {0}; - ctx_val_t *ctx_val = NULL; - ctx_val_t ctx_val_1 = {0}; - Route__RouteConfiguration *route_config = NULL; - Route__VirtualHost *virt_host = NULL; - Route__Route *route = NULL; - - DECLARE_VAR_ADDRESS(ctx, addr); - ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_ROUTER_CONFIG + bpf_get_current_task(); - ctx_val = kmesh_tail_lookup_ctx(&ctx_key); - if (!ctx_val) - return convert_sockops_ret(-1); - - route_config = map_lookup_route_config(ctx_val->data); - kmesh_tail_delete_ctx(&ctx_key); - if (!route_config) { - BPF_LOG(WARN, ROUTER_CONFIG, "failed to lookup route config, route_name=\"%s\"\n", ctx_val->data); - return convert_sockops_ret(-1); - } - - virt_host = virtual_host_match(route_config, &addr, ctx); - if (!virt_host) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to match virtual host, addr=%u\n", addr.ipv4); - return convert_sockops_ret(-1); - } - - route = virtual_host_route_match(virt_host, &addr, ctx, (struct bpf_mem_ptr *)ctx_val->msg); - if (!route) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to match route action, addr=%u\n", addr.ipv4); - return convert_sockops_ret(-1); - } - - cluster = route_get_cluster(route); - if (!cluster) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get cluster\n"); - return convert_sockops_ret(-1); - } - - ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); - if (!bpf_strncpy(ctx_val_1.data, BPF_DATA_MAX_LEN, cluster)) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to copy cluster %s\n", cluster); - return convert_sockops_ret(-1); - } - - ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val_1); - if (ret != 0) - return convert_sockops_ret(ret); - - kmesh_tail_call(ctx, KMESH_TAIL_CALL_CLUSTER); - kmesh_tail_delete_ctx(&ctx_key); - return 0; -} - -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = 1; diff --git a/bpf/kmesh/sockops.c b/bpf/kmesh/sockops.c index 96e1fa5..cd1f402 100644 --- a/bpf/kmesh/sockops.c +++ b/bpf/kmesh/sockops.c @@ -17,8 +17,12 @@ */ #include #include "bpf_log.h" +#include "ctx/sock_ops.h" #include "listener.h" #include "listener/listener.pb-c.h" +#include "filter.h" +#include "route_config.h" +#include "cluster.h" #if KMESH_ENABLE_IPV4 #if KMESH_ENABLE_HTTP @@ -39,22 +43,21 @@ static int sockops_traffic_control(struct bpf_sock_ops *skops, struct bpf_mem_pt } } - BPF_LOG(DEBUG, SOCKOPS, "sockops_traffic_control listener=\"%s\", addr=[%u:%u]\n", - (char *)kmesh_get_ptr_val(listener->name), skops->remote_ip4, skops->remote_port); return listener_manager(skops, listener, msg); } SEC("sockops") int sockops_prog(struct bpf_sock_ops *skops) { + #define BPF_CONSTRUCT_PTR(low_32, high_32) \ (unsigned long long)(((unsigned long long)(high_32) << 32) + (low_32)) struct bpf_mem_ptr *msg = NULL; - + if (skops->family != AF_INET) return 0; - + switch (skops->op) { case BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB: msg = (struct bpf_mem_ptr *)BPF_CONSTRUCT_PTR(skops->args[0], skops->args[1]); @@ -67,3 +70,4 @@ int sockops_prog(struct bpf_sock_ops *skops) #endif char _license[] SEC("license") = "GPL"; int _version SEC("version") = 1; + diff --git a/kernel/ko_src/kmesh/defer_connect.c b/kernel/ko_src/kmesh/defer_connect.c index 511ebf1..23e1853 100644 --- a/kernel/ko_src/kmesh/defer_connect.c +++ b/kernel/ko_src/kmesh/defer_connect.c @@ -123,7 +123,8 @@ static int defer_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) static int defer_tcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { - /* Kmesh is not compatible with defer_connect, so we + +/* Kmesh is not compatible with defer_connect, so we * need to check whether defer_connect is set to 1. * Kmesh reuses the defer_connect flag to enable the * epoll to be triggered normally. diff --git a/pkg/bpf/bpf_kmesh.go b/pkg/bpf/bpf_kmesh.go index e30c36c..b4b9b87 100644 --- a/pkg/bpf/bpf_kmesh.go +++ b/pkg/bpf/bpf_kmesh.go @@ -48,9 +48,6 @@ type BpfSockOps struct { Info BpfInfo Link link.Link bpf2go.KmeshSockopsObjects - bpf2go.KmeshFilterObjects - bpf2go.KmeshRouteConfigObjects - bpf2go.KmeshClusterObjects } type BpfKmesh struct { @@ -65,27 +62,41 @@ func (sc *BpfTracePoint) NewBpf(cfg *Config) { func (sc *BpfSockOps) NewBpf(cfg *Config) error { sc.Info.Config = *cfg - sc.Info.BpfFsPath += "/bpf_kmesh/" - sc.Info.MapPath = sc.Info.BpfFsPath + "map/" + sc.Info.MapPath = sc.Info.BpfFsPath + "/bpf_kmesh/map/" + sc.Info.BpfFsPath += "/bpf_kmesh/sockops/" if err := os.MkdirAll(sc.Info.MapPath, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR| syscall.S_IRGRP|syscall.S_IXGRP); err != nil && !os.IsExist(err) { return err } + + if err := os.MkdirAll(sc.Info.BpfFsPath, + syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR| + syscall.S_IRGRP|syscall.S_IXGRP); err != nil && !os.IsExist(err) { + return err + } + return nil } func (sc *BpfSockConn) NewBpf(cfg *Config) error { sc.Info.Config = *cfg - sc.Info.BpfFsPath += "/bpf_kmesh/" - sc.Info.MapPath = sc.Info.BpfFsPath + "map/" + sc.Info.MapPath = sc.Info.BpfFsPath + "/bpf_kmesh/map/" + sc.Info.BpfFsPath += "/bpf_kmesh/sockconn/" if err := os.MkdirAll(sc.Info.MapPath, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR| syscall.S_IRGRP|syscall.S_IXGRP); err != nil && !os.IsExist(err) { return err } + + if err := os.MkdirAll(sc.Info.BpfFsPath, + syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR| + syscall.S_IRGRP|syscall.S_IXGRP); err != nil && !os.IsExist(err) { + return err + } + return nil } @@ -143,7 +154,7 @@ func (sc *BpfTracePoint) loadKmeshTracePointObjects() (*ebpf.CollectionSpec, err } } - if err = spec.LoadAndAssign(&sc.KmeshTracePointObjects, &opts); err !=nil { + if err = spec.LoadAndAssign(&sc.KmeshTracePointObjects, &opts); err != nil { return nil, err } @@ -195,34 +206,17 @@ func (sc *BpfSockOps) loadKmeshFilterObjects() (*ebpf.CollectionSpec, error) { opts.Maps.PinPath = sc.Info.MapPath opts.Programs.LogSize = sc.Info.BpfVerifyLogSize - spec, err = bpf2go.LoadKmeshFilter() - - if err != nil || spec == nil { - return nil, err - } - - setMapPinType(spec, ebpf.PinByName) - setProgBpfType(spec, sc.Info.Type, sc.Info.AttachType) - if err = spec.LoadAndAssign(&sc.KmeshFilterObjects, &opts); err != nil { - return nil, err - } - - value := reflect.ValueOf(sc.KmeshFilterObjects.KmeshFilterPrograms) - if err = pinPrograms(&value, sc.Info.BpfFsPath); err != nil { - return nil, err - } - - err = sc.KmeshFilterObjects.KmeshFilterMaps.KmeshTailCallProg.Update( + err = sc.KmeshTailCallProg.Update( uint32(C.KMESH_TAIL_CALL_FILTER_CHAIN), - uint32(sc.KmeshFilterObjects.KmeshFilterPrograms.FilterChainManager.FD()), + uint32(sc.FilterChainManager.FD()), ebpf.UpdateAny) if err != nil { return nil, err } - err = sc.KmeshFilterObjects.KmeshFilterMaps.KmeshTailCallProg.Update( + err = sc.KmeshTailCallProg.Update( uint32(C.KMESH_TAIL_CALL_FILTER), - uint32(sc.KmeshFilterObjects.KmeshFilterPrograms.FilterManager.FD()), + uint32(sc.FilterManager.FD()), ebpf.UpdateAny) if err != nil { return nil, err @@ -240,26 +234,9 @@ func (sc *BpfSockOps) loadRouteConfigObjects() (*ebpf.CollectionSpec, error) { opts.Maps.PinPath = sc.Info.MapPath opts.Programs.LogSize = sc.Info.BpfVerifyLogSize - spec, err = bpf2go.LoadKmeshRouteConfig() - - if err != nil || spec == nil { - return nil, err - } - - setMapPinType(spec, ebpf.PinByName) - setProgBpfType(spec, sc.Info.Type, sc.Info.AttachType) - if err = spec.LoadAndAssign(&sc.KmeshRouteConfigObjects, &opts); err != nil { - return nil, err - } - - value := reflect.ValueOf(sc.KmeshRouteConfigObjects.KmeshRouteConfigPrograms) - if err = pinPrograms(&value, sc.Info.BpfFsPath); err != nil { - return nil, err - } - - err = sc.KmeshRouteConfigObjects.KmeshRouteConfigMaps.KmeshTailCallProg.Update( + err = sc.KmeshTailCallProg.Update( uint32(C.KMESH_TAIL_CALL_ROUTER_CONFIG), - uint32(sc.KmeshRouteConfigObjects.KmeshRouteConfigPrograms.RouteConfigManager.FD()), + uint32(sc.RouteConfigManager.FD()), ebpf.UpdateAny) if err != nil { return nil, err @@ -277,26 +254,9 @@ func (sc *BpfSockOps) loadKmeshClusterObjects() (*ebpf.CollectionSpec, error) { opts.Maps.PinPath = sc.Info.MapPath opts.Programs.LogSize = sc.Info.BpfVerifyLogSize - spec, err = bpf2go.LoadKmeshCluster() - - if err != nil || spec == nil { - return nil, err - } - - setMapPinType(spec, ebpf.PinByName) - setProgBpfType(spec, sc.Info.Type, sc.Info.AttachType) - if err = spec.LoadAndAssign(&sc.KmeshClusterObjects, &opts); err != nil { - return nil, err - } - - value := reflect.ValueOf(sc.KmeshClusterObjects.KmeshClusterPrograms) - if err = pinPrograms(&value, sc.Info.BpfFsPath); err != nil { - return nil, err - } - - err = sc.KmeshClusterObjects.KmeshClusterMaps.KmeshTailCallProg.Update( + err = sc.KmeshTailCallProg.Update( uint32(C.KMESH_TAIL_CALL_CLUSTER), - uint32(sc.KmeshClusterObjects.KmeshClusterPrograms.ClusterManager.FD()), + uint32(sc.ClusterManager.FD()), ebpf.UpdateAny) if err != nil { return nil, err @@ -512,16 +472,6 @@ func (sc *BpfSockOps) close() error { if err := sc.KmeshSockopsObjects.Close(); err != nil { return err } - if err := sc.KmeshFilterObjects.Close(); err != nil { - return err - } - if err := sc.KmeshRouteConfigObjects.Close(); err != nil { - return err - } - if err := sc.KmeshClusterObjects.Close(); err != nil { - return err - } - return nil } -- Gitee From d7f3534d218d11bc2c0a7ddb3a501bbc1c836681 Mon Sep 17 00:00:00 2001 From: superCharge Date: Tue, 10 Oct 2023 11:01:49 +0800 Subject: [PATCH 2/3] add -DCGROUP_SOCK_MANAGE for cgroup L4 bpf Signed-off-by: superCharge --- bpf/kmesh/bpf2go/bpf2go.go | 2 +- bpf/kmesh/cgroup_sock.c | 2 +- bpf/kmesh/include/cluster.h | 13 +++++++++++- bpf/kmesh/include/filter.h | 38 ++++++++++++++++++++++++++++++----- bpf/kmesh/include/listener.h | 13 +++++++++--- bpf/kmesh/include/tail_call.h | 10 +++++++++ bpf/kmesh/include/tcp_proxy.h | 11 ++++++++-- 7 files changed, 76 insertions(+), 13 deletions(-) diff --git a/bpf/kmesh/bpf2go/bpf2go.go b/bpf/kmesh/bpf2go/bpf2go.go index 94b4842..307eee7 100644 --- a/bpf/kmesh/bpf2go/bpf2go.go +++ b/bpf/kmesh/bpf2go/bpf2go.go @@ -20,6 +20,6 @@ package bpf2go // go run github.com/cilium/ebpf/cmd/bpf2go --help -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshCgroupSock ../cgroup_sock.c -- -I../include -I../../include -I../../../api/v2-c +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshCgroupSock ../cgroup_sock.c -- -I../include -I../../include -I../../../api/v2-c -DCGROUP_SOCK_MANAGE //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshSockops ../sockops.c -- -I../include -I../../include -I../../../api/v2-c //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang --cflags $EXTRA_CFLAGS --cflags $EXTRA_CDEFINE KmeshTracePoint ../tracepoint.c -- -I../include -I../../include diff --git a/bpf/kmesh/cgroup_sock.c b/bpf/kmesh/cgroup_sock.c index 3ece999..807d41c 100644 --- a/bpf/kmesh/cgroup_sock.c +++ b/bpf/kmesh/cgroup_sock.c @@ -54,7 +54,7 @@ static inline int sock4_traffic_control(struct bpf_sock_addr *ctx) if (ret) BPF_LOG(ERR, KMESH, "bpf set sockopt failed! ret:%d\n", ret); #else // KMESH_ENABLE_HTTP - ret = l4_listener_manager(ctx, lisdemotener); + ret = listener_manager(ctx, listener, NULL); if (ret != 0) { BPF_LOG(ERR, KMESH, "listener_manager failed, ret %d\n", ret); return ret; diff --git a/bpf/kmesh/include/cluster.h b/bpf/kmesh/include/cluster.h index 9d49de5..0bcc30e 100644 --- a/bpf/kmesh/include/cluster.h +++ b/bpf/kmesh/include/cluster.h @@ -304,18 +304,29 @@ static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_ return 0; } +#ifdef CGROUP_SOCK_MANAGE +SEC_TAIL(KMESH_CGROUP_CALLS, KMESH_CGROUP_TAIL_CALL_CLUSTER) +#else SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_CLUSTER) +#endif int cluster_manager(struct ctx_buff_t *ctx) { int ret = 0; ctx_key_t ctx_key = {0}; ctx_val_t *ctx_val = NULL; Cluster__Cluster *cluster = NULL; + tail_call_index_t current_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); +#ifdef CGROUP_SOCK_MANAGE + current_call_index = KMESH_CGROUP_TAIL_CALL_CLUSTER; +#else + current_call_index = KMESH_TAIL_CALL_CLUSTER; +#endif + ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); + ctx_key.tail_call_index = current_call_index + bpf_get_current_task(); ctx_val = kmesh_tail_lookup_ctx(&ctx_key); if (ctx_val == NULL) diff --git a/bpf/kmesh/include/filter.h b/bpf/kmesh/include/filter.h index 7166d85..244d001 100644 --- a/bpf/kmesh/include/filter.h +++ b/bpf/kmesh/include/filter.h @@ -123,8 +123,11 @@ static inline int handle_http_connection_manager( kmesh_tail_delete_ctx(&ctx_key); return 0; } - +#ifdef CGROUP_SOCK_MANAGE +SEC_TAIL(KMESH_CGROUP_CALLS, KMESH_CGROUP_TAIL_CALL_FILTER) +#else SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER) +#endif int filter_manager(struct ctx_buff_t *ctx) { int ret = 0; @@ -133,10 +136,18 @@ int filter_manager(struct ctx_buff_t *ctx) Listener__Filter *filter = NULL; Filter__HttpConnectionManager *http_conn = NULL; Filter__TcpProxy *tcp_proxy = NULL; + tail_call_index_t current_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); + +#ifdef CGROUP_SOCK_MANAGE + current_call_index = KMESH_CGROUP_TAIL_CALL_FILTER; +#else + current_call_index = KMESH_TAIL_CALL_FILTER; +#endif + ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); + ctx_key.tail_call_index = current_call_index + bpf_get_current_task(); ctx_val = kmesh_tail_lookup_ctx(&ctx_key); if (!ctx_val) { BPF_LOG(ERR, FILTER, "failed to lookup tail call val\n"); @@ -151,6 +162,7 @@ int filter_manager(struct ctx_buff_t *ctx) kmesh_tail_delete_ctx(&ctx_key); switch (filter->config_type_case) { +#ifndef CGROUP_SOCK_MANAGE case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER: http_conn = kmesh_get_ptr_val(filter->http_connection_manager); ret = bpf_parse_header_msg(ctx_val->msg); @@ -165,6 +177,7 @@ int filter_manager(struct ctx_buff_t *ctx) } ret = handle_http_connection_manager(http_conn, &addr, ctx, ctx_val->msg); break; +#endif case LISTENER__FILTER__CONFIG_TYPE_TCP_PROXY: tcp_proxy = kmesh_get_ptr_val(filter->tcp_proxy); if (!tcp_proxy) { @@ -180,7 +193,11 @@ int filter_manager(struct ctx_buff_t *ctx) return convert_sockops_ret(ret); } +#ifdef CGROUP_SOCK_MANAGE +SEC_TAIL(KMESH_CGROUP_CALLS, KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN) +#else SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER_CHAIN) +#endif int filter_chain_manager(struct ctx_buff_t *ctx) { int ret = 0; @@ -190,11 +207,22 @@ int filter_chain_manager(struct ctx_buff_t *ctx) ctx_val_t *ctx_val_ptr = NULL; Listener__FilterChain *filter_chain = NULL; Listener__Filter *filter = NULL; + tail_call_index_t current_call_index = 0; + tail_call_index_t next_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); + +#ifdef CGROUP_SOCK_MANAGE + current_call_index = KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN; + next_call_index = KMESH_CGROUP_TAIL_CALL_FILTER; +#else + current_call_index = KMESH_TAIL_CALL_FILTER_CHAIN; + next_call_index = KMESH_TAIL_CALL_FILTER; +#endif + ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER_CHAIN + bpf_get_current_task(); + ctx_key.tail_call_index = current_call_index + bpf_get_current_task(); ctx_val_ptr = kmesh_tail_lookup_ctx(&ctx_key); if (!ctx_val_ptr) { @@ -218,7 +246,7 @@ int filter_chain_manager(struct ctx_buff_t *ctx) // we should skip back and handle next filter, rather than exit. ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); + ctx_key.tail_call_index = next_call_index + bpf_get_current_task(); ctx_val.val = filter_idx; ctx_val.msg = ctx_val_ptr->msg; ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); @@ -227,7 +255,7 @@ int filter_chain_manager(struct ctx_buff_t *ctx) return convert_sockops_ret(ret); } - kmesh_tail_call(ctx, KMESH_TAIL_CALL_FILTER); + kmesh_tail_call(ctx, next_call_index); kmesh_tail_delete_ctx(&ctx_key); return 0; } diff --git a/bpf/kmesh/include/listener.h b/bpf/kmesh/include/listener.h index c50ba64..f683d66 100644 --- a/bpf/kmesh/include/listener.h +++ b/bpf/kmesh/include/listener.h @@ -114,6 +114,7 @@ static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *l Listener__FilterChain *filter_chain = NULL; ctx_key_t ctx_key = {0}; ctx_val_t ctx_val = {0}; + tail_call_index_t next_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); /* filter chain match */ @@ -122,10 +123,16 @@ static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *l BPF_LOG(WARN, LISTENER, "filterchain mismatch, un support addr=%u:%u\n", addr.ipv4, addr.port); return -1; } - + + /* exec filter chain */ +#ifdef CGROUP_SOCK_MANAGE + next_call_index = KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN; +#else + next_call_index = KMESH_TAIL_CALL_FILTER_CHAIN; +#endif ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER_CHAIN + bpf_get_current_task(); + ctx_key.tail_call_index = next_call_index + bpf_get_current_task(); ctx_val.val = filter_chain_idx; ctx_val.msg = msg; ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); @@ -134,7 +141,7 @@ static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *l return ret; } - kmesh_tail_call(ctx, KMESH_TAIL_CALL_FILTER_CHAIN); + kmesh_tail_call(ctx, next_call_index); (void)kmesh_tail_delete_ctx(&ctx_key); BPF_LOG(ERR, LISTENER, "listener_manager exit\n"); diff --git a/bpf/kmesh/include/tail_call.h b/bpf/kmesh/include/tail_call.h index bec5901..63cc792 100644 --- a/bpf/kmesh/include/tail_call.h +++ b/bpf/kmesh/include/tail_call.h @@ -25,7 +25,14 @@ #define MAP_SIZE_OF_TAIL_CALL_PROG 32 #define MAP_SIZE_OF_TAIL_CALL_CTX 256 +/*#ifdef CGROUP_SOCK_MANAGE + #define KMESH_PROG_CALLS cgroup +#else + #define KMESH_PROG_CALLS sockops +#endif*/ + #define KMESH_SOCKOPS_CALLS sockops +#define KMESH_CGROUP_CALLS cgroup/connect4 typedef enum { KMESH_TAIL_CALL_LISTENER = 1, @@ -34,6 +41,9 @@ typedef enum { KMESH_TAIL_CALL_ROUTER, KMESH_TAIL_CALL_CLUSTER, KMESH_TAIL_CALL_ROUTER_CONFIG, + KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN, + KMESH_CGROUP_TAIL_CALL_FILTER, + KMESH_CGROUP_TAIL_CALL_CLUSTER, } tail_call_index_t; struct { diff --git a/bpf/kmesh/include/tcp_proxy.h b/bpf/kmesh/include/tcp_proxy.h index 9e920df..715b2a8 100644 --- a/bpf/kmesh/include/tcp_proxy.h +++ b/bpf/kmesh/include/tcp_proxy.h @@ -77,12 +77,19 @@ static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, struct ctx DECLARE_VAR_ADDRESS(ctx, addr); ctx_key_t ctx_key = {0}; ctx_val_t ctx_val = {0}; + tail_call_index_t next_call_index = 0; if (NULL == tcpProxy) return convert_sock_errno(-EINVAL); cluster = tcp_proxy_get_cluster(tcpProxy); + +#ifdef CGROUP_SOCK_MANAGE + next_call_index = KMESH_CGROUP_TAIL_CALL_CLUSTER; +#else + next_call_index = KMESH_TAIL_CALL_CLUSTER; +#endif ctx_key.address = addr; - ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); + ctx_key.tail_call_index = next_call_index + bpf_get_current_task(); if (!bpf_strncpy(ctx_val.data, BPF_DATA_MAX_LEN, cluster)) { BPF_LOG(ERR, FILTER, "failed to copy cluster %s\n", cluster); return convert_sock_errno(ret); @@ -92,7 +99,7 @@ static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, struct ctx if (ret != 0) return convert_sock_errno(ret); BPF_LOG(DEBUG, FILTER, "tcp_proxy_manager cluster %s\n", cluster); - kmesh_tail_call(ctx, KMESH_TAIL_CALL_CLUSTER); + kmesh_tail_call(ctx, next_call_index); kmesh_tail_delete_ctx(&ctx_key); return 0; } -- Gitee From a5d30621b7130876324d4fe4e214c576f97fd299 Mon Sep 17 00:00:00 2001 From: superCharge Date: Fri, 13 Oct 2023 11:43:27 +0800 Subject: [PATCH 3/3] support L4 traffic manager Signed-off-by: superCharge --- bpf/kmesh/cgroup_sock.c | 1 + bpf/kmesh/include/cluster.h | 20 +++-------- bpf/kmesh/include/ctx/ctx.h | 26 --------------- bpf/kmesh/include/ctx/sock_addr.h | 3 +- bpf/kmesh/include/ctx/sock_ops.h | 3 +- bpf/kmesh/include/filter.h | 51 +++++++---------------------- bpf/kmesh/include/kmesh_common.h | 30 +++++------------ bpf/kmesh/include/listener.h | 19 ++++------- bpf/kmesh/include/route_config.h | 13 ++++---- bpf/kmesh/include/tail_call.h | 24 ++------------ bpf/kmesh/include/tcp_proxy.h | 13 ++------ bpf/kmesh/sockops.c | 2 ++ kernel/ko_src/kmesh/defer_connect.c | 2 +- pkg/bpf/bpf_kmesh.go | 35 +++++++++++++++++--- pkg/bpf/pin.go | 4 ++- 15 files changed, 82 insertions(+), 164 deletions(-) delete mode 100644 bpf/kmesh/include/ctx/ctx.h diff --git a/bpf/kmesh/cgroup_sock.c b/bpf/kmesh/cgroup_sock.c index 807d41c..88e682f 100644 --- a/bpf/kmesh/cgroup_sock.c +++ b/bpf/kmesh/cgroup_sock.c @@ -49,6 +49,7 @@ static inline int sock4_traffic_control(struct bpf_sock_addr *ctx) BPF_LOG(DEBUG, KMESH, "bpf find listener addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); #if KMESH_ENABLE_HTTP + // todo build when kernel support http parse and route // defer conn ret = bpf_setsockopt(ctx, IPPROTO_TCP, TCP_ULP, (void *)kmesh_module_name, sizeof(kmesh_module_name)); if (ret) diff --git a/bpf/kmesh/include/cluster.h b/bpf/kmesh/include/cluster.h index 0bcc30e..0495e33 100644 --- a/bpf/kmesh/include/cluster.h +++ b/bpf/kmesh/include/cluster.h @@ -21,7 +21,6 @@ #include "bpf_log.h" #include "kmesh_common.h" -#include "ctx/ctx.h" #include "tail_call.h" #include "cluster/cluster.pb-c.h" #include "endpoint/endpoint.pb-c.h" @@ -267,7 +266,7 @@ static inline Core__SocketAddress *cluster_get_ep_sock_addr(const void *ep_ident return sock_addr; } -static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_t *addr, struct ctx_buff_t *ctx) +static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_t *addr, ctx_buff_t *ctx) { char *name = NULL; void *ep_identity = NULL; @@ -304,29 +303,18 @@ static inline int cluster_handle_loadbalance(Cluster__Cluster *cluster, address_ return 0; } -#ifdef CGROUP_SOCK_MANAGE -SEC_TAIL(KMESH_CGROUP_CALLS, KMESH_CGROUP_TAIL_CALL_CLUSTER) -#else -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_CLUSTER) -#endif -int cluster_manager(struct ctx_buff_t *ctx) +SEC_TAIL(KMESH_PORG_CALLS, KMESH_TAIL_CALL_CLUSTER) +int cluster_manager(ctx_buff_t *ctx) { int ret = 0; ctx_key_t ctx_key = {0}; ctx_val_t *ctx_val = NULL; Cluster__Cluster *cluster = NULL; - tail_call_index_t current_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); -#ifdef CGROUP_SOCK_MANAGE - current_call_index = KMESH_CGROUP_TAIL_CALL_CLUSTER; -#else - current_call_index = KMESH_TAIL_CALL_CLUSTER; -#endif - ctx_key.address = addr; - ctx_key.tail_call_index = current_call_index + bpf_get_current_task(); + ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); ctx_val = kmesh_tail_lookup_ctx(&ctx_key); if (ctx_val == NULL) diff --git a/bpf/kmesh/include/ctx/ctx.h b/bpf/kmesh/include/ctx/ctx.h deleted file mode 100644 index a271cc5..0000000 --- a/bpf/kmesh/include/ctx/ctx.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - - * Author: supercharge-xsy - * Create: 2023-9-20 - */ - -#ifndef __BPF_CTX_H -#define __BPF_CTX_H - -#ifndef ctx_buff_t -# error "No __ctx_buff context defined. Please either include 'bpf/ctx/skb.h' or 'bpf/ctx/xdp.h'." -#endif - -#endif //__BPF_CTX_H diff --git a/bpf/kmesh/include/ctx/sock_addr.h b/bpf/kmesh/include/ctx/sock_addr.h index f12c6c8..d009b46 100644 --- a/bpf/kmesh/include/ctx/sock_addr.h +++ b/bpf/kmesh/include/ctx/sock_addr.h @@ -19,8 +19,9 @@ #ifndef __BPF_CTX_SOCK_ADDR_H #define __BPF_CTX_SOCK_ADDR_H +typedef struct bpf_sock_addr ctx_buff_t; -#define ctx_buff_t bpf_sock_addr +#define KMESH_PORG_CALLS cgroup/connect4 #define DECLARE_VAR_ADDRESS(ctx, name) \ address_t name = {0}; \ diff --git a/bpf/kmesh/include/ctx/sock_ops.h b/bpf/kmesh/include/ctx/sock_ops.h index 85e769b..7726ba8 100644 --- a/bpf/kmesh/include/ctx/sock_ops.h +++ b/bpf/kmesh/include/ctx/sock_ops.h @@ -19,8 +19,9 @@ #ifndef __BPF_CTX_SOCK_OPS_H #define __BPF_CTX_SOCK_OPS_H +typedef struct bpf_sock_ops ctx_buff_t; -#define ctx_buff_t bpf_sock_ops +#define KMESH_PORG_CALLS sockops #define DECLARE_VAR_ADDRESS(ctx, name) \ address_t name = {0}; \ diff --git a/bpf/kmesh/include/filter.h b/bpf/kmesh/include/filter.h index 244d001..6dbb807 100644 --- a/bpf/kmesh/include/filter.h +++ b/bpf/kmesh/include/filter.h @@ -18,7 +18,6 @@ #ifndef __KMESH_FILTER_H__ #define __KMESH_FILTER_H__ -#include "ctx/ctx.h" #include "tcp_proxy.h" #include "tail_call.h" #include "bpf_log.h" @@ -28,7 +27,7 @@ #include "filter/http_connection_manager.pb-c.h" -static inline int filter_match_check(const Listener__Filter *filter, const address_t *addr, const struct ctx_buff_t *ctx) +static inline int filter_match_check(const Listener__Filter *filter, const address_t *addr, const ctx_buff_t *ctx) { int match = 0; switch (filter->config_type_case) { @@ -46,7 +45,7 @@ static inline int filter_match_check(const Listener__Filter *filter, const addre static inline int filter_chain_filter_match(const Listener__FilterChain *filter_chain, const address_t *addr, - const struct ctx_buff_t *ctx, + const ctx_buff_t *ctx, Listener__Filter **filter_ptr, __u64 *filter_ptr_idx) { @@ -93,7 +92,7 @@ static inline int filter_chain_filter_match(const Listener__FilterChain *filter_ static inline int handle_http_connection_manager( const Filter__HttpConnectionManager *http_conn, const address_t *addr, - struct ctx_buff_t *ctx, struct bpf_mem_ptr *msg) + ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { int ret; char *route_name = NULL; @@ -123,12 +122,9 @@ static inline int handle_http_connection_manager( kmesh_tail_delete_ctx(&ctx_key); return 0; } -#ifdef CGROUP_SOCK_MANAGE -SEC_TAIL(KMESH_CGROUP_CALLS, KMESH_CGROUP_TAIL_CALL_FILTER) -#else -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER) -#endif -int filter_manager(struct ctx_buff_t *ctx) + +SEC_TAIL(KMESH_PORG_CALLS, KMESH_TAIL_CALL_FILTER) +int filter_manager(ctx_buff_t *ctx) { int ret = 0; ctx_key_t ctx_key = {0}; @@ -136,18 +132,10 @@ int filter_manager(struct ctx_buff_t *ctx) Listener__Filter *filter = NULL; Filter__HttpConnectionManager *http_conn = NULL; Filter__TcpProxy *tcp_proxy = NULL; - tail_call_index_t current_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); - -#ifdef CGROUP_SOCK_MANAGE - current_call_index = KMESH_CGROUP_TAIL_CALL_FILTER; -#else - current_call_index = KMESH_TAIL_CALL_FILTER; -#endif - ctx_key.address = addr; - ctx_key.tail_call_index = current_call_index + bpf_get_current_task(); + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); ctx_val = kmesh_tail_lookup_ctx(&ctx_key); if (!ctx_val) { BPF_LOG(ERR, FILTER, "failed to lookup tail call val\n"); @@ -193,12 +181,8 @@ int filter_manager(struct ctx_buff_t *ctx) return convert_sockops_ret(ret); } -#ifdef CGROUP_SOCK_MANAGE -SEC_TAIL(KMESH_CGROUP_CALLS, KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN) -#else -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_FILTER_CHAIN) -#endif -int filter_chain_manager(struct ctx_buff_t *ctx) +SEC_TAIL(KMESH_PORG_CALLS, KMESH_TAIL_CALL_FILTER_CHAIN) +int filter_chain_manager(ctx_buff_t *ctx) { int ret = 0; __u64 filter_idx = 0; @@ -207,22 +191,11 @@ int filter_chain_manager(struct ctx_buff_t *ctx) ctx_val_t *ctx_val_ptr = NULL; Listener__FilterChain *filter_chain = NULL; Listener__Filter *filter = NULL; - tail_call_index_t current_call_index = 0; - tail_call_index_t next_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); - -#ifdef CGROUP_SOCK_MANAGE - current_call_index = KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN; - next_call_index = KMESH_CGROUP_TAIL_CALL_FILTER; -#else - current_call_index = KMESH_TAIL_CALL_FILTER_CHAIN; - next_call_index = KMESH_TAIL_CALL_FILTER; -#endif - ctx_key.address = addr; - ctx_key.tail_call_index = current_call_index + bpf_get_current_task(); + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER_CHAIN + bpf_get_current_task(); ctx_val_ptr = kmesh_tail_lookup_ctx(&ctx_key); if (!ctx_val_ptr) { @@ -246,7 +219,7 @@ int filter_chain_manager(struct ctx_buff_t *ctx) // we should skip back and handle next filter, rather than exit. ctx_key.address = addr; - ctx_key.tail_call_index = next_call_index + bpf_get_current_task(); + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER + bpf_get_current_task(); ctx_val.val = filter_idx; ctx_val.msg = ctx_val_ptr->msg; ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); @@ -255,7 +228,7 @@ int filter_chain_manager(struct ctx_buff_t *ctx) return convert_sockops_ret(ret); } - kmesh_tail_call(ctx, next_call_index); + kmesh_tail_call(ctx, KMESH_TAIL_CALL_FILTER); kmesh_tail_delete_ctx(&ctx_key); return 0; } diff --git a/bpf/kmesh/include/kmesh_common.h b/bpf/kmesh/include/kmesh_common.h index fc4dde3..cc3ac32 100644 --- a/bpf/kmesh/include/kmesh_common.h +++ b/bpf/kmesh/include/kmesh_common.h @@ -62,28 +62,14 @@ struct { __uint(map_flags, 0); } inner_map SEC(".maps"); -/*#if 1 -typedef struct bpf_sock_ops ctx_buff_t; -#define DECLARE_VAR_ADDRESS(ctx, name) \ - address_t name = {0}; \ - bpf_memset(&name, 0, sizeof(name)); \ - name.ipv4 = (ctx)->remote_ip4; \ - name.port = (ctx)->remote_port -#define SET_CTX_ADDRESS(ctx, address) \ - (ctx)->remote_ip4 = (address)->ipv4; \ - (ctx)->remote_port = (address)->port -#else -typedef struct bpf_sock_addr ctx_buff_t; -#define DECLARE_VAR_ADDRESS(ctx, name) \ - address_t name = {0}; \ - name.ipv4 = (ctx)->user_ip4; \ - name.port = (ctx)->user_port; \ - name.protocol = (ctx)->protocol -#define SET_CTX_ADDRESS(ctx, address) \ - (ctx)->user_ip4 = (address)->ipv4; \ - (ctx)->user_port = (address)->port; \ - (ctx)->protocol = (address)->protocol -#endif*/ +typedef enum { + KMESH_TAIL_CALL_LISTENER = 1, + KMESH_TAIL_CALL_FILTER_CHAIN, + KMESH_TAIL_CALL_FILTER, + KMESH_TAIL_CALL_ROUTER, + KMESH_TAIL_CALL_CLUSTER, + KMESH_TAIL_CALL_ROUTER_CONFIG, +} tail_call_index_t; typedef Core__SocketAddress address_t; diff --git a/bpf/kmesh/include/listener.h b/bpf/kmesh/include/listener.h index f683d66..f853424 100644 --- a/bpf/kmesh/include/listener.h +++ b/bpf/kmesh/include/listener.h @@ -37,7 +37,7 @@ static inline Listener__Listener *map_lookup_listener(const address_t *addr) static inline bool listener_filter_chain_match_check(const Listener__FilterChain *filter_chain, const address_t *addr, - const struct ctx_buff_t *ctx) + const ctx_buff_t *ctx) { char *transport_protocol; const char buf[] = "raw_buffer"; @@ -69,7 +69,7 @@ static inline bool listener_filter_chain_match_check(const Listener__FilterChain static inline int listener_filter_chain_match(const Listener__Listener *listener, const address_t *addr, - const struct ctx_buff_t *ctx, + const ctx_buff_t *ctx, Listener__FilterChain **filter_chain_ptr, __u64 *filter_chain_idx) { @@ -107,14 +107,13 @@ static inline int listener_filter_chain_match(const Listener__Listener *listener return -1; } -static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *listener, struct bpf_mem_ptr *msg) +static inline int listener_manager(ctx_buff_t *ctx, Listener__Listener *listener, struct bpf_mem_ptr *msg) { int ret = 0; __u64 filter_chain_idx = 0; Listener__FilterChain *filter_chain = NULL; ctx_key_t ctx_key = {0}; ctx_val_t ctx_val = {0}; - tail_call_index_t next_call_index = 0; DECLARE_VAR_ADDRESS(ctx, addr); /* filter chain match */ @@ -123,16 +122,10 @@ static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *l BPF_LOG(WARN, LISTENER, "filterchain mismatch, un support addr=%u:%u\n", addr.ipv4, addr.port); return -1; } - - + /* exec filter chain */ -#ifdef CGROUP_SOCK_MANAGE - next_call_index = KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN; -#else - next_call_index = KMESH_TAIL_CALL_FILTER_CHAIN; -#endif ctx_key.address = addr; - ctx_key.tail_call_index = next_call_index + bpf_get_current_task(); + ctx_key.tail_call_index = KMESH_TAIL_CALL_FILTER_CHAIN + bpf_get_current_task(); ctx_val.val = filter_chain_idx; ctx_val.msg = msg; ret = kmesh_tail_update_ctx(&ctx_key, &ctx_val); @@ -141,7 +134,7 @@ static inline int listener_manager(struct ctx_buff_t *ctx, Listener__Listener *l return ret; } - kmesh_tail_call(ctx, next_call_index); + kmesh_tail_call(ctx, KMESH_TAIL_CALL_FILTER_CHAIN); (void)kmesh_tail_delete_ctx(&ctx_key); BPF_LOG(ERR, LISTENER, "listener_manager exit\n"); diff --git a/bpf/kmesh/include/route_config.h b/bpf/kmesh/include/route_config.h index 43125e2..f6549d8 100644 --- a/bpf/kmesh/include/route_config.h +++ b/bpf/kmesh/include/route_config.h @@ -22,7 +22,6 @@ #include "kmesh_common.h" #include "tail_call.h" #include "route/route.pb-c.h" -#include "ctx/ctx.h" #define ROUTER_NAME_MAX_LEN BPF_DATA_MAX_LEN @@ -43,7 +42,7 @@ static inline Route__RouteConfiguration *map_lookup_route_config(const char *rou } static inline int virtual_host_match_check(Route__VirtualHost *virt_host, - address_t *addr, struct ctx_buff_t *ctx, struct bpf_mem_ptr *uri) + address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *uri) { int i; void *domains = NULL; @@ -99,7 +98,7 @@ static inline bool VirtualHost_check_allow_any(char *name) { static inline Route__VirtualHost *virtual_host_match(Route__RouteConfiguration *route_config, address_t *addr, - struct ctx_buff_t *ctx) + ctx_buff_t *ctx) { int i; void *ptrs = NULL; @@ -227,7 +226,7 @@ static inline bool check_headers_match(Route__RouteMatch *match) { } static inline int virtual_host_route_match_check(Route__Route *route, - address_t *addr, struct ctx_buff_t *ctx, struct bpf_mem_ptr *msg) + address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { Route__RouteMatch *match; char *prefix; @@ -260,7 +259,7 @@ static inline int virtual_host_route_match_check(Route__Route *route, } static inline Route__Route *virtual_host_route_match(Route__VirtualHost *virt_host, - address_t *addr, struct ctx_buff_t *ctx, struct bpf_mem_ptr *msg) + address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { int i; void *ptrs = NULL; @@ -344,8 +343,8 @@ static inline char *route_get_cluster(const Route__Route *route) return kmesh_get_ptr_val(_(route_act->cluster)); } -SEC_TAIL(KMESH_SOCKOPS_CALLS, KMESH_TAIL_CALL_ROUTER_CONFIG) -int route_config_manager(struct ctx_buff_t *ctx) +SEC_TAIL(KMESH_PORG_CALLS, KMESH_TAIL_CALL_ROUTER_CONFIG) +int route_config_manager(ctx_buff_t *ctx) { int ret; char *cluster = NULL; diff --git a/bpf/kmesh/include/tail_call.h b/bpf/kmesh/include/tail_call.h index 63cc792..84e04f3 100644 --- a/bpf/kmesh/include/tail_call.h +++ b/bpf/kmesh/include/tail_call.h @@ -21,31 +21,11 @@ #include "kmesh_common.h" + // same as linux/bpf.h MAX_TAIL_CALL_CNT #define MAP_SIZE_OF_TAIL_CALL_PROG 32 #define MAP_SIZE_OF_TAIL_CALL_CTX 256 -/*#ifdef CGROUP_SOCK_MANAGE - #define KMESH_PROG_CALLS cgroup -#else - #define KMESH_PROG_CALLS sockops -#endif*/ - -#define KMESH_SOCKOPS_CALLS sockops -#define KMESH_CGROUP_CALLS cgroup/connect4 - -typedef enum { - KMESH_TAIL_CALL_LISTENER = 1, - KMESH_TAIL_CALL_FILTER_CHAIN, - KMESH_TAIL_CALL_FILTER, - KMESH_TAIL_CALL_ROUTER, - KMESH_TAIL_CALL_CLUSTER, - KMESH_TAIL_CALL_ROUTER_CONFIG, - KMESH_CGROUP_TAIL_CALL_FILTER_CHAIN, - KMESH_CGROUP_TAIL_CALL_FILTER, - KMESH_CGROUP_TAIL_CALL_CLUSTER, -} tail_call_index_t; - struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(key_size, sizeof(__u32)); @@ -54,7 +34,7 @@ struct { __uint(map_flags, 0); } map_of_tail_call_prog SEC(".maps"); -static inline void kmesh_tail_call(struct ctx_buff_t *ctx, const __u32 index) +static inline void kmesh_tail_call(ctx_buff_t *ctx, const __u32 index) { bpf_tail_call(ctx, &map_of_tail_call_prog, index); } diff --git a/bpf/kmesh/include/tcp_proxy.h b/bpf/kmesh/include/tcp_proxy.h index 715b2a8..4342b7e 100644 --- a/bpf/kmesh/include/tcp_proxy.h +++ b/bpf/kmesh/include/tcp_proxy.h @@ -70,26 +70,19 @@ static inline char *tcp_proxy_get_cluster(const Filter__TcpProxy *tcpProxy) return (char*)kmesh_get_ptr_val(tcpProxy->cluster); } -static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, struct ctx_buff_t *ctx) +static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, ctx_buff_t *ctx) { int ret; char *cluster = NULL; DECLARE_VAR_ADDRESS(ctx, addr); ctx_key_t ctx_key = {0}; ctx_val_t ctx_val = {0}; - tail_call_index_t next_call_index = 0; if (NULL == tcpProxy) return convert_sock_errno(-EINVAL); cluster = tcp_proxy_get_cluster(tcpProxy); - -#ifdef CGROUP_SOCK_MANAGE - next_call_index = KMESH_CGROUP_TAIL_CALL_CLUSTER; -#else - next_call_index = KMESH_TAIL_CALL_CLUSTER; -#endif ctx_key.address = addr; - ctx_key.tail_call_index = next_call_index + bpf_get_current_task(); + ctx_key.tail_call_index = KMESH_TAIL_CALL_CLUSTER + bpf_get_current_task(); if (!bpf_strncpy(ctx_val.data, BPF_DATA_MAX_LEN, cluster)) { BPF_LOG(ERR, FILTER, "failed to copy cluster %s\n", cluster); return convert_sock_errno(ret); @@ -99,7 +92,7 @@ static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, struct ctx if (ret != 0) return convert_sock_errno(ret); BPF_LOG(DEBUG, FILTER, "tcp_proxy_manager cluster %s\n", cluster); - kmesh_tail_call(ctx, next_call_index); + kmesh_tail_call(ctx, KMESH_TAIL_CALL_CLUSTER); kmesh_tail_delete_ctx(&ctx_key); return 0; } diff --git a/bpf/kmesh/sockops.c b/bpf/kmesh/sockops.c index cd1f402..ca02f8f 100644 --- a/bpf/kmesh/sockops.c +++ b/bpf/kmesh/sockops.c @@ -43,6 +43,8 @@ static int sockops_traffic_control(struct bpf_sock_ops *skops, struct bpf_mem_pt } } + BPF_LOG(DEBUG, SOCKOPS, "sockops_traffic_control listener=\"%s\", addr=[%u:%u]\n", + (char *)kmesh_get_ptr_val(listener->name), skops->remote_ip4, skops->remote_port); return listener_manager(skops, listener, msg); } diff --git a/kernel/ko_src/kmesh/defer_connect.c b/kernel/ko_src/kmesh/defer_connect.c index 23e1853..3f46779 100644 --- a/kernel/ko_src/kmesh/defer_connect.c +++ b/kernel/ko_src/kmesh/defer_connect.c @@ -124,7 +124,7 @@ static int defer_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) static int defer_tcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { -/* Kmesh is not compatible with defer_connect, so we + /* Kmesh is not compatible with defer_connect, so we * need to check whether defer_connect is set to 1. * Kmesh reuses the defer_connect flag to enable the * epoll to be triggered normally. diff --git a/pkg/bpf/bpf_kmesh.go b/pkg/bpf/bpf_kmesh.go index b4b9b87..5fbccd5 100644 --- a/pkg/bpf/bpf_kmesh.go +++ b/pkg/bpf/bpf_kmesh.go @@ -19,7 +19,7 @@ package bpf // #cgo pkg-config: bpf api-v2-c -// #include "kmesh/include/tail_call.h" +// #include "kmesh/include/kmesh_common.h" import "C" import ( "os" @@ -52,8 +52,8 @@ type BpfSockOps struct { type BpfKmesh struct { TracePoint BpfTracePoint - SockConn BpfSockConn - SockOps BpfSockOps + SockConn BpfSockConn + SockOps BpfSockOps } func (sc *BpfTracePoint) NewBpf(cfg *Config) { @@ -137,7 +137,7 @@ func setInnerMap(spec *ebpf.CollectionSpec) { func (sc *BpfTracePoint) loadKmeshTracePointObjects() (*ebpf.CollectionSpec, error) { var ( - err error + err error spec *ebpf.CollectionSpec opts ebpf.CollectionOptions ) @@ -332,6 +332,31 @@ func (sc *BpfSockConn) LoadSockConn() error { sc.Info.Type = prog.Type sc.Info.AttachType = prog.AttachType + // update tail call prog + err = sc.KmeshTailCallProg.Update( + uint32(C.KMESH_TAIL_CALL_FILTER_CHAIN), + uint32(sc.FilterChainManager.FD()), + ebpf.UpdateAny) + if err != nil { + return err + } + + err = sc.KmeshTailCallProg.Update( + uint32(C.KMESH_TAIL_CALL_FILTER), + uint32(sc.FilterManager.FD()), + ebpf.UpdateAny) + if err != nil { + return err + } + + err = sc.KmeshTailCallProg.Update( + uint32(C.KMESH_TAIL_CALL_CLUSTER), + uint32(sc.ClusterManager.FD()), + ebpf.UpdateAny) + if err != nil { + return err + } + return nil } @@ -401,7 +426,7 @@ func (sc *BpfKmesh) ApiEnvCfg() error { } func (sc *BpfTracePoint) Attach() error { - tpopt := link.RawTracepointOptions { + tpopt := link.RawTracepointOptions{ Name: "connect_ret", Program: sc.KmeshTracePointObjects.ConnectRet, } diff --git a/pkg/bpf/pin.go b/pkg/bpf/pin.go index 01852a9..ea9f792 100644 --- a/pkg/bpf/pin.go +++ b/pkg/bpf/pin.go @@ -93,7 +93,9 @@ func unpinMaps(value *reflect.Value) error { func setMapPinType(spec *ebpf.CollectionSpec, pinType ebpf.PinType) { for key, v := range spec.Maps { - if key == ".rodata" || key == ".bss" { + // tail_call map dont support pinning when shared by different bpf types + if key == ".rodata" || key == ".bss" || key == "kmesh_tail_call_prog" || + key == "kmesh_tail_call_ctx" { continue } v.Pinning = pinType -- Gitee