diff --git a/bpf/kmesh/bpf2go/bpf2go.go b/bpf/kmesh/bpf2go/bpf2go.go index e64e0b861bb2b5c1ffc9bb5ccda677fa90e0328f..307eee757965273c18da8fb72f16c9009b984f66 100644 --- a/bpf/kmesh/bpf2go/bpf2go.go +++ b/bpf/kmesh/bpf2go/bpf2go.go @@ -20,9 +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 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 c1d970e7926922ea66646af81f8d23172c2be178..88e682f80ba06f04f9d8c579a8d278b5bb270a6f 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,14 +46,16 @@ 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 + // 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) 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; @@ -80,3 +77,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 2d937b5556f9430eabca8914fef5bbe8b2a8803f..0000000000000000000000000000000000000000 --- 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 3925ffc29c818d98844dd38b59d65a8935f2b207..0000000000000000000000000000000000000000 --- 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 4f15c55a40ec0414d27d6f82153c0508c359d05b..0495e3385588b007b2f257f11a888c61a81a6333 100644 --- a/bpf/kmesh/include/cluster.h +++ b/bpf/kmesh/include/cluster.h @@ -19,6 +19,7 @@ #ifndef __KMESH_CLUSTER_H__ #define __KMESH_CLUSTER_H__ +#include "bpf_log.h" #include "kmesh_common.h" #include "tail_call.h" #include "cluster/cluster.pb-c.h" @@ -216,4 +217,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, 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_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; + + 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/sock_addr.h b/bpf/kmesh/include/ctx/sock_addr.h new file mode 100644 index 0000000000000000000000000000000000000000..d009b46db0f71dbbc717f97cfb437f4fbcb6b175 --- /dev/null +++ b/bpf/kmesh/include/ctx/sock_addr.h @@ -0,0 +1,38 @@ +/* + * 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 + +typedef struct bpf_sock_addr ctx_buff_t; + +#define KMESH_PORG_CALLS cgroup/connect4 + +#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 0000000000000000000000000000000000000000..7726ba888103b0fa7306d95387db57d9a5332a18 --- /dev/null +++ b/bpf/kmesh/include/ctx/sock_ops.h @@ -0,0 +1,35 @@ +/* + * 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 + +typedef struct bpf_sock_ops ctx_buff_t; + +#define KMESH_PORG_CALLS sockops + +#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 6bb1640af9f389144ed9f06a06971b5eb2c9af5d..6dbb8072788af8804d0c39a29c766e7839ec097b 100644 --- a/bpf/kmesh/include/filter.h +++ b/bpf/kmesh/include/filter.h @@ -18,6 +18,9 @@ #ifndef __KMESH_FILTER_H__ #define __KMESH_FILTER_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" @@ -86,4 +89,147 @@ 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, + 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_PORG_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) { +#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); + 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; +#endif + 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_PORG_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; +} #endif diff --git a/bpf/kmesh/include/kmesh_common.h b/bpf/kmesh/include/kmesh_common.h index 2f495a8347c3d5111d500ec1e2b23b6a2d39c2eb..cc3ac3274e9e8e7423393dc6ab84f5d5701374aa 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/route_config.h b/bpf/kmesh/include/route_config.h index f9aa37ce58bac2e1a2087011a994034babd8ec7c..f6549d8a1380638e2fa24d286ef67502d3567fec 100644 --- a/bpf/kmesh/include/route_config.h +++ b/bpf/kmesh/include/route_config.h @@ -18,6 +18,7 @@ #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" @@ -289,4 +290,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_PORG_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; +} #endif diff --git a/bpf/kmesh/include/tail_call.h b/bpf/kmesh/include/tail_call.h index 4fa1bf5b115b7706fdf69f328db8f155b4631eda..84e04f3d96fe0baba5ca8997502f450b85fa80c6 100644 --- a/bpf/kmesh/include/tail_call.h +++ b/bpf/kmesh/include/tail_call.h @@ -21,21 +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 -#define KMESH_SOCKOPS_CALLS sockops - -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; - struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(key_size, sizeof(__u32)); diff --git a/bpf/kmesh/route_config.c b/bpf/kmesh/route_config.c deleted file mode 100644 index 86c0039869727b08750f9166551fd055b4ebf288..0000000000000000000000000000000000000000 --- 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 96e1fa5a890234c9b156cda11dcb4682cc7f3362..ca02f8f5665ac92fcf714f50c8253b6187460b35 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 @@ -47,14 +51,15 @@ static int sockops_traffic_control(struct bpf_sock_ops *skops, struct bpf_mem_pt 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 +72,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 511ebf1abe0147d5d74e777c84c56ae18f71b6ba..3f467795ac13623cff03378f97e92b33a93d9bc0 100644 --- a/kernel/ko_src/kmesh/defer_connect.c +++ b/kernel/ko_src/kmesh/defer_connect.c @@ -123,6 +123,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 * need to check whether defer_connect is set to 1. * Kmesh reuses the defer_connect flag to enable the diff --git a/pkg/bpf/bpf_kmesh.go b/pkg/bpf/bpf_kmesh.go index e30c36c47ae129b5d19a6477035fedfc8db44914..5fbccd57e8ac6c393d11544f33b6015500547e76 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" @@ -48,15 +48,12 @@ type BpfSockOps struct { Info BpfInfo Link link.Link bpf2go.KmeshSockopsObjects - bpf2go.KmeshFilterObjects - bpf2go.KmeshRouteConfigObjects - bpf2go.KmeshClusterObjects } type BpfKmesh struct { TracePoint BpfTracePoint - SockConn BpfSockConn - SockOps BpfSockOps + SockConn BpfSockConn + SockOps BpfSockOps } func (sc *BpfTracePoint) NewBpf(cfg *Config) { @@ -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 } @@ -126,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 ) @@ -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 @@ -372,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 } @@ -441,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, } @@ -512,16 +497,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 } diff --git a/pkg/bpf/pin.go b/pkg/bpf/pin.go index 01852a92d9005fcb072df9f76e1d2f9569649e3a..ea9f7924bc1bee06486550ed815fdd3c5c81e05d 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