Skip to content

Commit

Permalink
new kernel adapt
Browse files Browse the repository at this point in the history
Signed-off-by: lec-bit <[email protected]>
  • Loading branch information
lec-bit committed Jan 18, 2025
1 parent a50ea6d commit 8423b77
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 233 deletions.
11 changes: 5 additions & 6 deletions bpf/include/bpf_helper_defs_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
* By default, these IDs are in the 5.10 kernel with kmesh kernel patches.
*/

static void *(*bpf_strncpy)(char *dst, __u32 dst_size, char *src) = (void *)171;
static void *(*bpf_strnstr)(void *s1, void *s2, __u32 size) = (void *)172;
static __u64 (*bpf_strnlen)(char *buff, __u32 size) = (void *)173;
static __u64 (*bpf__strncmp)(const char *s1, __u32 s1_size, const char *s2) = (void *)174;
static long (*bpf_parse_header_msg)(struct bpf_mem_ptr *msg) = (void *)175;
static void *(*bpf_get_msg_header_element)(void *name) = (void *)176;
static int (*bpf_km_strnstr)(
struct bpf_sock_addr *ctx, const char *key, int key_sz, const char *subptr, int subptr_sz) = (void *)163;
static int (*bpf_km_strncmp)(
struct bpf_sock_addr *ctx, const char *key, int key_sz, const char *subptr, int subptr_sz) = (void *)164;
static long (*bpf_parse_header_msg)(struct bpf_sock_addr *ctx) = (void *)165;
24 changes: 14 additions & 10 deletions bpf/kmesh/ads/cgroup_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
#include "cluster.h"
#include "bpf_common.h"

#if ENHANCED_KERNEL
#include "route_config.h"
#endif
#if KMESH_ENABLE_IPV4
#if KMESH_ENABLE_HTTP

static const char kmesh_module_name[] = "kmesh_defer";

static char kmesh_module_name_get[16];
static inline int sock4_traffic_control(struct bpf_sock_addr *ctx)
{
int ret;
Expand All @@ -39,18 +42,19 @@ static inline int sock4_traffic_control(struct bpf_sock_addr *ctx)
BPF_LOG(DEBUG, KMESH, "bpf find listener addr=[%s:%u]\n", ip2str(&ip, 1), bpf_ntohs(ctx->user_port));

#if ENHANCED_KERNEL
// 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 = listener_manager(ctx, listener, NULL);
ret = bpf_getsockopt(ctx, IPPROTO_TCP, TCP_ULP, (void *)kmesh_module_name_get, 16);
BPF_LOG(DEBUG, KMESH, "kmesh_module_name_get:%s ret:%d\n", kmesh_module_name_get, ret);
if (ret != 0) {
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);
return 0;
}
#endif
ret = listener_manager(ctx, listener, ctx);
if (ret != 0) {
BPF_LOG(ERR, KMESH, "listener_manager failed, ret %d\n", ret);
return ret;
}
#endif // KMESH_ENABLE_HTTP

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions bpf/kmesh/ads/include/circuit_breaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "bpf_log.h"
#include "kmesh_common.h"
#include "bpf_common.h"
#include "cluster/cluster.pb-c.h"

#ifndef __KMESH_CIRCUIT_BREAKER_H__
#define __KMESH_CIRCUIT_BREAKER_H__
Expand Down
4 changes: 2 additions & 2 deletions bpf/kmesh/ads/include/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ int filter_manager(ctx_buff_t *ctx)
kmesh_tail_delete_ctx(&ctx_key);

switch (filter->config_type_case) {
#ifndef CGROUP_SOCK_MANAGE
#if ENHANCED_KERNEL
case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER:
http_conn = KMESH_GET_PTR_VAL(filter->http_connection_manager, Filter__HttpConnectionManager);
ret = bpf_parse_header_msg(ctx_val->msg);
ret = bpf_parse_header_msg(ctx);
if (GET_RET_PROTO_TYPE(ret) != PROTO_HTTP_1_1) {
BPF_LOG(DEBUG, FILTER, "http filter manager,only support http1.1 this version");
break;
Expand Down
4 changes: 2 additions & 2 deletions bpf/kmesh/ads/include/kmesh_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ struct bpf_mem_ptr {
__u32 size;
};

#if !ENHANCED_KERNEL
static inline int bpf__strncmp(const char *dst, int n, const char *src)
{
if (dst == NULL || src == NULL)
Expand Down Expand Up @@ -69,7 +68,6 @@ static inline char *bpf_strncpy(char *dst, int n, const char *src)
}
return dst;
}
#endif

typedef Core__SocketAddress address_t;

Expand All @@ -81,6 +79,8 @@ enum kmesh_l7_proto_type { PROTO_UNKNOW = 0, PROTO_HTTP_1_1, PROTO_HTTP_2_0 };

enum kmesh_l7_msg_type { MSG_UNKNOW = 0, MSG_REQUEST, MSG_MID_REPONSE, MSG_FINAL_RESPONSE };

enum kmesh_strncmp_type { STRNCMP_FAILED = 0, STRNCMP_PREFIX, STRNCMP_EXACT };

#define KMESH_PROTO_TYPE_WIDTH (8)
#define GET_RET_PROTO_TYPE(n) ((n)&0xff)
#define GET_RET_MSG_TYPE(n) (((n) >> KMESH_PROTO_TYPE_WIDTH) & 0xff)
Expand Down
82 changes: 32 additions & 50 deletions bpf/kmesh/ads/include/route_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,15 @@ static inline Route__RouteConfiguration *map_lookup_route_config(const char *rou
return kmesh_map_lookup_elem(&map_of_router_config, route_name);
}

static inline int
virtual_host_match_check(Route__VirtualHost *virt_host, address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *host)
static inline int virtual_host_match_check(
Route__VirtualHost *virt_host, address_t *addr, ctx_buff_t *ctx, char *host_key, int host_key_len)
{
int i;
void *domains = NULL;
void *domain = NULL;
void *ptr;
__u32 ptr_length;

if (!host)
return 0;

ptr = _(host->ptr);
if (!ptr)
return 0;

ptr_length = _(host->size);

if (!virt_host->domains)
return 0;

Expand All @@ -65,14 +56,8 @@ virtual_host_match_check(Route__VirtualHost *virt_host, address_t *addr, ctx_buf
if (((char *)domain)[0] == '*' && ((char *)domain)[1] == '\0')
return 1;

if (bpf_strnstr(ptr, domain, ptr_length) != NULL) {
BPF_LOG(
DEBUG,
ROUTER_CONFIG,
"match virtual_host, name=\"%s\"\n",
(char *)KMESH_GET_PTR_VAL(virt_host->name, char *));
if (bpf_km_strnstr(ctx, host_key, host_key_len, domain, BPF_DATA_MAX_LEN) != NULL)
return 1;
}
}

return 0;
Expand All @@ -95,7 +80,7 @@ virtual_host_match(Route__RouteConfiguration *route_config, address_t *addr, ctx
Route__VirtualHost *virt_host = NULL;
Route__VirtualHost *virt_host_allow_any = NULL;
char host_key[5] = {'H', 'o', 's', 't', '\0'};
struct bpf_mem_ptr *host;
int host_key_len = 5;

if (route_config->n_virtual_hosts <= 0 || route_config->n_virtual_hosts > KMESH_PER_VIRT_HOST_NUM) {
BPF_LOG(WARN, ROUTER_CONFIG, "invalid virt hosts num=%d\n", route_config->n_virtual_hosts);
Expand All @@ -108,12 +93,6 @@ virtual_host_match(Route__RouteConfiguration *route_config, address_t *addr, ctx
return NULL;
}

host = bpf_get_msg_header_element(host_key);
if (!host) {
BPF_LOG(ERR, ROUTER_CONFIG, "failed to get URI in msg\n");
return NULL;
}

for (i = 0; i < KMESH_PER_VIRT_HOST_NUM; i++) {
if (i >= route_config->n_virtual_hosts) {
break;
Expand All @@ -128,27 +107,34 @@ virtual_host_match(Route__RouteConfiguration *route_config, address_t *addr, ctx
continue;
}

if (virtual_host_match_check(virt_host, addr, ctx, host))
if (virtual_host_match_check(virt_host, addr, ctx, host_key, host_key_len)) {
BPF_LOG(
DEBUG,
ROUTER_CONFIG,
"match virtual_host, name=\"%s\"\n",
(char *)KMESH_GET_PTR_VAL(virt_host->name, char *));
return virt_host;
}
}
// allow_any as the default virt_host
if (virt_host_allow_any && virtual_host_match_check(virt_host_allow_any, addr, ctx, host))
if (virt_host_allow_any && virtual_host_match_check(virt_host_allow_any, addr, ctx, host_key, host_key_len))
return virt_host_allow_any;
return NULL;
}

static inline bool check_header_value_match(char *target, struct bpf_mem_ptr *head, bool exact)
static inline bool check_header_value_match(struct bpf_sock_addr *ctx, char *header_name, char *target, bool exact)
{
BPF_LOG(DEBUG, ROUTER_CONFIG, "header match, is exact:%d value:%s\n", exact, target);
long target_length = bpf_strnlen(target, BPF_DATA_MAX_LEN);
if (!exact)
return (bpf__strncmp(target, target_length, _(head->ptr)) == 0);
if (target_length != _(head->size))
return false;
return (bpf__strncmp(target, target_length, _(head->ptr)) == 0);
int ret = 0;
ret = bpf_km_strncmp(ctx, header_name, BPF_DATA_MAX_LEN, target, BPF_DATA_MAX_LEN);
if (ret == STRNCMP_EXACT) {
return true;
} else if (ret == STRNCMP_PREFIX && !exact) {
return true;
}
return false;
}

static inline bool check_headers_match(Route__RouteMatch *match)
static inline bool check_headers_match(struct bpf_sock_addr *ctx, Route__RouteMatch *match)
{
int i;
void *ptrs = NULL;
Expand Down Expand Up @@ -182,19 +168,15 @@ static inline bool check_headers_match(Route__RouteMatch *match)
BPF_LOG(ERR, ROUTER_CONFIG, "failed to get match headers in route match\n");
return false;
}
msg_header = (struct bpf_mem_ptr *)bpf_get_msg_header_element(header_name);
if (!msg_header) {
BPF_LOG(DEBUG, ROUTER_CONFIG, "failed to get header value form msg\n");
return false;
}
BPF_LOG(DEBUG, ROUTER_CONFIG, "header match check, name:%s\n", header_name);

switch (header_match->header_match_specifier_case) {
case ROUTE__HEADER_MATCHER__HEADER_MATCH_SPECIFIER_EXACT_MATCH: {
config_header_value = KMESH_GET_PTR_VAL(header_match->exact_match, char *);
if (config_header_value == NULL) {
BPF_LOG(ERR, ROUTER_CONFIG, "failed to get config_header_value\n");
return false;
}
if (!check_header_value_match(config_header_value, msg_header, true)) {
if (!check_header_value_match(ctx, header_name, config_header_value, true)) {
return false;
}
break;
Expand All @@ -203,8 +185,9 @@ static inline bool check_headers_match(Route__RouteMatch *match)
config_header_value = KMESH_GET_PTR_VAL(header_match->prefix_match, char *);
if (config_header_value == NULL) {
BPF_LOG(ERR, ROUTER_CONFIG, "prefix:failed to get config_header_value\n");
return false;
}
if (!check_header_value_match(config_header_value, msg_header, false)) {
if (!check_header_value_match(ctx, header_name, config_header_value, false)) {
return false;
}
break;
Expand All @@ -223,10 +206,8 @@ virtual_host_route_match_check(Route__Route *route, address_t *addr, ctx_buff_t
Route__RouteMatch *match;
char *prefix;
void *ptr;

ptr = _(msg->ptr);
if (!ptr)
return 0;
char all_header[4] = {'A', 'l', 'l', '\0'};
int all_header_len = 4;

if (!route->match)
return 0;
Expand All @@ -239,10 +220,11 @@ virtual_host_route_match_check(Route__Route *route, address_t *addr, ctx_buff_t
if (!prefix)
return 0;

if (bpf_strnstr(ptr, prefix, BPF_DATA_MAX_LEN) == NULL)
if (bpf_km_strnstr(ctx, all_header, all_header_len, prefix, BPF_DATA_MAX_LEN) == 0) {
return 0;
}

if (!check_headers_match(match))
if (!check_headers_match(ctx, match))
return 0;

BPF_LOG(DEBUG, ROUTER_CONFIG, "match route, name=\"%s\"\n", (char *)KMESH_GET_PTR_VAL(route->name, char *));
Expand Down
38 changes: 0 additions & 38 deletions bpf/kmesh/ads/sockops.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,11 @@
#include <sys/socket.h>
#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"
#include "circuit_breaker.h"

#if KMESH_ENABLE_IPV4
#if KMESH_ENABLE_HTTP

static int sockops_traffic_control(struct bpf_sock_ops *skops, struct bpf_mem_ptr *msg)
{
int ret;
/* 1 lookup listener */
DECLARE_VAR_ADDRESS(skops, addr);
addr.port = GET_SKOPS_REMOTE_PORT(skops);

Listener__Listener *listener = map_lookup_listener(&addr);

if (!listener) {
addr.ipv4 = 0;
listener = map_lookup_listener(&addr);
if (!listener) {
/* no match vip/nodeport listener */
return 0;
}
}

DECLARE_VAR_IPV4(skops->remote_ip4, ip)
BPF_LOG(
DEBUG,
SOCKOPS,
"sockops_traffic_control listener=\"%s\", addr=[%s:%u]\n",
(char *)KMESH_GET_PTR_VAL(listener->name, char *),
ip2str(&ip, 1),
bpf_ntohs(skops->remote_port));
return listener_manager(skops, listener, msg);
}

SEC("sockops")
int sockops_prog(struct bpf_sock_ops *skops)
{
Expand All @@ -53,10 +19,6 @@ int sockops_prog(struct bpf_sock_ops *skops)
return BPF_OK;

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]);
(void)sockops_traffic_control(skops, msg);
break;
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) {
BPF_LOG(ERR, SOCKOPS, "set sockops cb failed!\n");
Expand Down
Loading

0 comments on commit 8423b77

Please sign in to comment.