diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..4f3186cf1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,216 @@ +# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto +Language: Cpp +# BasedOnStyle: LLVM + +# 访问说明符(public、private等)的偏移 +AccessModifierOffset: -4 + +# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行) +AlignAfterOpenBracket: AlwaysBreak + +# 连续宏定义 +AlignConsecutiveMacros: true + +# 连续赋值时,对齐所有等号 +AlignConsecutiveAssignments: false + +# 连续声明时,对齐所有声明的变量名 +AlignConsecutiveDeclarations: false + +# 右对齐逃脱换行(使用反斜杠换行)的反斜杠 +AlignEscapedNewlines: Right + +# 水平对齐二元和三元表达式的操作数 +AlignOperands: true + +# 对齐连续的尾随的注释 +AlignTrailingComments: true + +# 不允许函数声明的所有参数在放在下一行 +AllowAllParametersOfDeclarationOnNextLine: true + +# 允许短的块放在同一行 +AllowShortBlocksOnASingleLine: false + +# 允许短的case标签放在同一行 +AllowShortCaseLabelsOnASingleLine: false + +# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All +AllowShortFunctionsOnASingleLine: None + +# 允许短的if语句保持在同一行 +AllowShortIfStatementsOnASingleLine: false + +# 允许短的循环保持在同一行 +AllowShortLoopsOnASingleLine: false + +# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), +# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义) +AlwaysBreakAfterReturnType: None + +# 总是在多行string字面量前换行 +AlwaysBreakBeforeMultilineStrings: false + +# 总是在template声明后换行 +AlwaysBreakTemplateDeclarations: true + +# false表示函数实参要么都在同一行,要么都各自一行 +BinPackArguments: false + +# false表示所有形参要么都在同一行,要么都各自一行 +BinPackParameters: false + +# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效 +BraceWrapping: + # class定义后面 + AfterClass: false + # 控制语句后面 + AfterControlStatement: false + # enum定义后面 + AfterEnum: false + # 函数定义后面 + AfterFunction: true + # 命名空间定义后面 + AfterNamespace: false + # struct定义后面 + AfterStruct: false + # union定义后面 + AfterUnion: false + # extern之后 + AfterExternBlock: false + # catch之前 + BeforeCatch: false + # else之前 + BeforeElse: false + # 缩进大括号 + IndentBraces: false + # 分离空函数 + SplitEmptyFunction: false + # 分离空语句 + SplitEmptyRecord: false + # 分离空命名空间 + SplitEmptyNamespace: false + +# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行) +BreakBeforeBinaryOperators: NonAssignment + +# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), +# Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), +# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom +# 注:这里认为语句块也属于函数 +BreakBeforeBraces: Custom + +# 在三元运算符前换行 +BreakBeforeTernaryOperators: false + +# 在构造函数的初始化列表的冒号后换行 +BreakConstructorInitializers: AfterColon + +#BreakInheritanceList: AfterColon + +BreakStringLiterals: false + +# 每行字符的限制,0表示没有限制 +ColumnLimit: 120 + +CompactNamespaces: true + +# 构造函数的初始化列表要么都在同一行,要么都各自一行 +ConstructorInitializerAllOnOneLineOrOnePerLine: false + +# 构造函数的初始化列表的缩进宽度 +ConstructorInitializerIndentWidth: 4 + +# 延续的行的缩进宽度 +ContinuationIndentWidth: 4 + +# 去除C++11的列表初始化的大括号{后和}前的空格 +Cpp11BracedListStyle: true + +# 继承最常用的指针和引用的对齐方式 +DerivePointerAlignment: false + +# 固定命名空间注释 +FixNamespaceComments: true + +# 缩进case标签 +IndentCaseLabels: false + +IndentPPDirectives: None + +# 缩进宽度 +IndentWidth: 4 + +# 函数返回类型换行时,缩进函数声明或函数定义的函数名 +IndentWrappedFunctionNames: false + +# 保留在块开始处的空行 +KeepEmptyLinesAtTheStartOfBlocks: false + +# 连续空行的最大数量 +MaxEmptyLinesToKeep: 1 + +# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All +NamespaceIndentation: None + +# 指针和引用的对齐: Left, Right, Middle +PointerAlignment: Right + +# 允许重新排版注释 +ReflowComments: true + +# 允许排序#include +SortIncludes: false + +# 允许排序 using 声明 +SortUsingDeclarations: false + +# 在C风格类型转换后添加空格 +SpaceAfterCStyleCast: false + +# 在Template 关键字后面添加空格 +SpaceAfterTemplateKeyword: true + +# 在赋值运算符之前添加空格 +SpaceBeforeAssignmentOperators: true + +# SpaceBeforeCpp11BracedList: true + +# SpaceBeforeCtorInitializerColon: true + +# SpaceBeforeInheritanceColon: true + +# 开圆括号之前添加一个空格: Never, ControlStatements, Always +SpaceBeforeParens: ControlStatements + +# SpaceBeforeRangeBasedForLoopColon: true + +# 在空的圆括号中添加空格 +SpaceInEmptyParentheses: false + +# 在尾随的评论前添加的空格数(只适用于//) +SpacesBeforeTrailingComments: 1 + +# 在尖括号的<后和>前添加空格 +SpacesInAngles: false + +# 在C风格类型转换的括号中添加空格 +SpacesInCStyleCastParentheses: false + +# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格 +SpacesInContainerLiterals: true + +# 在圆括号的(后和)前添加空格 +SpacesInParentheses: false + +# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响 +SpacesInSquareBrackets: false + +# 标准: Cpp03, Cpp11, Auto +Standard: Cpp11 + +# tab宽度 +TabWidth: 4 + +# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always +UseTab: Never diff --git a/Makefile b/Makefile index 6039746ed..300bebc8f 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,8 @@ tidy: .PHONY: gen gen: tidy\ - gen-proto + gen-proto \ + format .PHONY: gen-check gen-check: gen @@ -140,6 +141,9 @@ build: docker: build docker build --build-arg arch=$(DIR) -f build/docker/kmesh.dockerfile -t $(HUB)/$(TARGET):$(TAG) . +format: + ./hack/format.sh + clean: $(QUIET) rm -rf ./out $(QUIET) rm -rf ./config/linux-bpf.h diff --git a/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.c b/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.c index 5b9b3e036..e16c62cc7 100644 --- a/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.c +++ b/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.c @@ -30,1367 +30,1336 @@ #include "deserialization_to_bpf_map.h" #include "../../config/kmesh_marcos_def.h" -#define LOG_ERR(fmt, args...) printf(fmt, ## args) -#define LOG_WARN(fmt, args...) printf(fmt, ## args) -#define LOG_INFO(fmt, args...) printf(fmt, ## args) +#define LOG_ERR(fmt, args...) printf(fmt, ##args) +#define LOG_WARN(fmt, args...) printf(fmt, ##args) +#define LOG_INFO(fmt, args...) printf(fmt, ##args) -#define FREE_MAP_SIZE (MAX_OUTTER_MAP_ENTRIES / (sizeof(uint32_t) * 8)) +#define FREE_MAP_SIZE (MAX_OUTTER_MAP_ENTRIES / (sizeof(uint32_t) * 8)) struct outter_map_alloc_control { - unsigned int used; - uint32_t free_map[FREE_MAP_SIZE]; + unsigned int used; + uint32_t free_map[FREE_MAP_SIZE]; }; struct op_context { - void *key; - void *value; - int outter_fd; - int map_fd; - int curr_fd; - struct bpf_map_info *outter_info; - struct bpf_map_info *inner_info; - struct bpf_map_info *info; - struct bpf_map_info *curr_info; - char *inner_map_object; - const ProtobufCMessageDescriptor *desc; + void *key; + void *value; + int outter_fd; + int map_fd; + int curr_fd; + struct bpf_map_info *outter_info; + struct bpf_map_info *inner_info; + struct bpf_map_info *info; + struct bpf_map_info *curr_info; + char *inner_map_object; + const ProtobufCMessageDescriptor *desc; }; -#define init_op_context(context, key, val, desc, o_fd, fd, o_info, \ - i_info, m_info) \ -do { \ - (context).key = (key); \ - (context).value = (val); \ - (context).desc = (desc); \ - (context).outter_fd = (o_fd); \ - (context).map_fd = (fd); \ - (context).outter_info = (o_info); \ - (context).inner_info = (i_info); \ - (context).info = (m_info); \ - (context).curr_info = (m_info); \ - (context).curr_fd = (fd); \ -} while (0) +#define init_op_context(context, key, val, desc, o_fd, fd, o_info, i_info, m_info) \ + do { \ + (context).key = (key); \ + (context).value = (val); \ + (context).desc = (desc); \ + (context).outter_fd = (o_fd); \ + (context).map_fd = (fd); \ + (context).outter_info = (o_info); \ + (context).inner_info = (i_info); \ + (context).info = (m_info); \ + (context).curr_info = (m_info); \ + (context).curr_fd = (fd); \ + } while (0) static int update_bpf_map(struct op_context *ctx); -static void* create_struct(struct op_context *ctx, int *err); +static void *create_struct(struct op_context *ctx, int *err); static int del_bpf_map(struct op_context *ctx, int is_inner); static int free_outter_map_entry(struct op_context *ctx, void *outter_key); static int normalize_key(struct op_context *ctx, void *key, const char *map_name) { - ctx->key = calloc(1, ctx->curr_info->key_size); - if (!ctx->key) - return -errno; - - if (!map_name) - return -errno; - - // TODO - if (!strncmp(map_name, "Listener", strlen(map_name))) - memcpy_s(ctx->key, ctx->curr_info->key_size, key, ctx->curr_info->key_size); - else - strncpy(ctx->key, key, ctx->curr_info->key_size); - - return 0; + ctx->key = calloc(1, ctx->curr_info->key_size); + if (!ctx->key) + return -errno; + + if (!map_name) + return -errno; + + // TODO + if (!strncmp(map_name, "Listener", strlen(map_name))) + memcpy_s(ctx->key, ctx->curr_info->key_size, key, ctx->curr_info->key_size); + else + strncpy(ctx->key, key, ctx->curr_info->key_size); + + return 0; } -static inline int selected_oneof_field(void *value, - const ProtobufCFieldDescriptor *field) +static inline int selected_oneof_field(void *value, const ProtobufCFieldDescriptor *field) { - uint32_t n = *(uint32_t*)((char*)value + field->quantifier_offset); + uint32_t n = *(uint32_t *)((char *)value + field->quantifier_offset); - if ((field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF) && field->id != n) - return 0; + if ((field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF) && field->id != n) + return 0; - return 1; + return 1; } -static inline int valid_field_value(void *value, - const ProtobufCFieldDescriptor *field) +static inline int valid_field_value(void *value, const ProtobufCFieldDescriptor *field) { - uint32_t val = *(uint32_t*)((char*)value + field->offset); - - if (val == 0) { - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - case PROTOBUF_C_TYPE_STRING: - return 0; - default: - break; - } - - switch (field->label) { - case PROTOBUF_C_LABEL_REPEATED: - return 0; - default: - break; - } - } - - return 1; + uint32_t val = *(uint32_t *)((char *)value + field->offset); + + if (val == 0) { + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + case PROTOBUF_C_TYPE_STRING: + return 0; + default: + break; + } + + switch (field->label) { + case PROTOBUF_C_LABEL_REPEATED: + return 0; + default: + break; + } + } + + return 1; } static inline size_t sizeof_elt_in_repeated_array(ProtobufCType type) { - switch (type) { - case PROTOBUF_C_TYPE_SINT32: - case PROTOBUF_C_TYPE_INT32: - case PROTOBUF_C_TYPE_UINT32: - case PROTOBUF_C_TYPE_SFIXED32: - case PROTOBUF_C_TYPE_FIXED32: - case PROTOBUF_C_TYPE_FLOAT: - case PROTOBUF_C_TYPE_ENUM: - return 4; - case PROTOBUF_C_TYPE_SINT64: - case PROTOBUF_C_TYPE_INT64: - case PROTOBUF_C_TYPE_UINT64: - case PROTOBUF_C_TYPE_SFIXED64: - case PROTOBUF_C_TYPE_FIXED64: - case PROTOBUF_C_TYPE_DOUBLE: - return 8; - case PROTOBUF_C_TYPE_BOOL: - return sizeof(protobuf_c_boolean); - case PROTOBUF_C_TYPE_STRING: - case PROTOBUF_C_TYPE_MESSAGE: - return sizeof(void *); - case PROTOBUF_C_TYPE_BYTES: - return sizeof(ProtobufCBinaryData); - default: - break; - } - - return 0; + switch (type) { + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + case PROTOBUF_C_TYPE_ENUM: + return 4; + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + return 8; + case PROTOBUF_C_TYPE_BOOL: + return sizeof(protobuf_c_boolean); + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_MESSAGE: + return sizeof(void *); + case PROTOBUF_C_TYPE_BYTES: + return sizeof(ProtobufCBinaryData); + default: + break; + } + + return 0; } static inline int valid_outter_key(struct op_context *ctx, unsigned int outter_key) { - if (outter_key >= ctx->outter_info->max_entries || !outter_key) - return 0; + if (outter_key >= ctx->outter_info->max_entries || !outter_key) + return 0; - return 1; + return 1; } static void free_elem(void *ptr) { - if ((uintptr_t)ptr < MAX_OUTTER_MAP_ENTRIES) - return; + if ((uintptr_t)ptr < MAX_OUTTER_MAP_ENTRIES) + return; - free(ptr); + free(ptr); } static void free_keys(struct op_context *ctx, void *keys, int n) { - int i; - unsigned int key; - for (i = 0; i < n; i++) { - key = *((uintptr_t*)keys + i); - if (!key) - return; - - free_outter_map_entry(ctx, &key); - } + int i; + unsigned int key; + for (i = 0; i < n; i++) { + key = *((uintptr_t *)keys + i); + if (!key) + return; + + free_outter_map_entry(ctx, &key); + } } static int get_map_ids(const char *name, unsigned int *id, unsigned int *outter_id, unsigned int *inner_id) { - char *ptr = NULL; - char *map_id, *map_in_map_id; - - map_id = (name == NULL) ? getenv("MAP_ID") : getenv(name); - if (!map_id) { - LOG_ERR("%s is not set\n", ((name == NULL) ? "MAP_ID" : name)); - return -EINVAL; - } - - errno = 0; - - *id = (unsigned int)strtol(map_id, &ptr, 10); - if (!ptr[0]) { - map_in_map_id = getenv("OUTTER_MAP_ID"); - if (!map_in_map_id) - return 0; - *outter_id = (unsigned int)strtol(map_in_map_id, &ptr, 10); - } - - if (!ptr[0]) { - map_in_map_id = getenv("INNER_MAP_ID"); - if (!map_in_map_id) { - LOG_ERR("INNER_MAP_ID is not set\n"); - return -EINVAL; - } - *inner_id = (unsigned int)strtol(map_in_map_id, &ptr, 10); - } - return -errno; + char *ptr = NULL; + char *map_id, *map_in_map_id; + + map_id = (name == NULL) ? getenv("MAP_ID") : getenv(name); + if (!map_id) { + LOG_ERR("%s is not set\n", ((name == NULL) ? "MAP_ID" : name)); + return -EINVAL; + } + + errno = 0; + + *id = (unsigned int)strtol(map_id, &ptr, 10); + if (!ptr[0]) { + map_in_map_id = getenv("OUTTER_MAP_ID"); + if (!map_in_map_id) + return 0; + *outter_id = (unsigned int)strtol(map_in_map_id, &ptr, 10); + } + + if (!ptr[0]) { + map_in_map_id = getenv("INNER_MAP_ID"); + if (!map_in_map_id) { + LOG_ERR("INNER_MAP_ID is not set\n"); + return -EINVAL; + } + *inner_id = (unsigned int)strtol(map_in_map_id, &ptr, 10); + } + return -errno; } static int get_map_fd_info(unsigned int id, int *map_fd, struct bpf_map_info *info) { - int ret; - __u32 map_info_len; + int ret; + __u32 map_info_len; - *map_fd = bpf_map_get_fd_by_id(id); - if (*map_fd < 0) - return *map_fd; + *map_fd = bpf_map_get_fd_by_id(id); + if (*map_fd < 0) + return *map_fd; - map_info_len = sizeof(*info); - ret = bpf_obj_get_info_by_fd(*map_fd, info, &map_info_len); - return ret; + map_info_len = sizeof(*info); + ret = bpf_obj_get_info_by_fd(*map_fd, info, &map_info_len); + return ret; } static int alloc_and_set_inner_map(struct op_context *ctx, int key) { - int fd, ret; - struct bpf_map_info *inner_info = ctx->inner_info; + int fd, ret; + struct bpf_map_info *inner_info = ctx->inner_info; #if LIBBPF_HIGHER_0_6_0_VERSION - LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = inner_info->map_flags); + LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = inner_info->map_flags); - fd = bpf_map_create(inner_info->type, NULL, inner_info->key_size, - inner_info->value_size, inner_info->max_entries, - &opts); + fd = bpf_map_create( + inner_info->type, NULL, inner_info->key_size, inner_info->value_size, inner_info->max_entries, &opts); #else - fd = bpf_create_map_name(inner_info->type, NULL, inner_info->key_size, - inner_info->value_size, inner_info->max_entries, - inner_info->map_flags); + fd = bpf_create_map_name( + inner_info->type, + NULL, + inner_info->key_size, + inner_info->value_size, + inner_info->max_entries, + inner_info->map_flags); #endif - if (fd < 0) - return fd; + if (fd < 0) + return fd; - ret = bpf_map_update_elem(ctx->outter_fd, &key, &fd, BPF_ANY); - close(fd); + ret = bpf_map_update_elem(ctx->outter_fd, &key, &fd, BPF_ANY); + close(fd); - return ret; + return ret; } -static int find_free_outter_map_entry(struct op_context *ctx, - struct outter_map_alloc_control *a_ctl) +static int find_free_outter_map_entry(struct op_context *ctx, struct outter_map_alloc_control *a_ctl) { - int index; - unsigned int i; - - for (i = 0; i < FREE_MAP_SIZE; i++) { - if (a_ctl->free_map[i]) { - index = __builtin_ffs(a_ctl->free_map[i]); - a_ctl->free_map[i] &= ~(1U << (index - 1)); - return (index - 1 + (i * 32)); - } - } - - return -ENOENT; + int index; + unsigned int i; + + for (i = 0; i < FREE_MAP_SIZE; i++) { + if (a_ctl->free_map[i]) { + index = __builtin_ffs(a_ctl->free_map[i]); + a_ctl->free_map[i] &= ~(1U << (index - 1)); + return (index - 1 + (i * 32)); + } + } + + return -ENOENT; } static int free_outter_map_entry(struct op_context *ctx, void *outter_key) { - int ret; - int key = 0; - unsigned int i = *(unsigned int*)outter_key; - int inner_map_fd; - __u32 inner_map_id; - struct outter_map_alloc_control *a_ctl; - void *inner_map_object; - - ret = bpf_map_delete_elem(ctx->outter_fd, outter_key); - if (ret) - return ret; - - ret = bpf_map_lookup_elem(ctx->outter_fd, &key, &inner_map_id); - if (ret < 0) - return 0; - - inner_map_fd = bpf_map_get_fd_by_id(inner_map_id); - if (inner_map_fd < 0) - return inner_map_fd; - - inner_map_object = malloc(ctx->inner_info->value_size); - if (!inner_map_object) { - close(inner_map_fd); - return -ENOMEM; - } - - ret = bpf_map_lookup_elem(inner_map_fd, &key, inner_map_object); - if (ret < 0) { - close(inner_map_fd); - free(inner_map_object); - return ret; - } - - a_ctl = (struct outter_map_alloc_control *)inner_map_object; - a_ctl->used--; - a_ctl->free_map[i / 32] |= (1U << (i % 32)); - bpf_map_update_elem(inner_map_fd, &key, a_ctl, BPF_ANY); - free(inner_map_object); - close(inner_map_fd); - - return 0; + int ret; + int key = 0; + unsigned int i = *(unsigned int *)outter_key; + int inner_map_fd; + __u32 inner_map_id; + struct outter_map_alloc_control *a_ctl; + void *inner_map_object; + + ret = bpf_map_delete_elem(ctx->outter_fd, outter_key); + if (ret) + return ret; + + ret = bpf_map_lookup_elem(ctx->outter_fd, &key, &inner_map_id); + if (ret < 0) + return 0; + + inner_map_fd = bpf_map_get_fd_by_id(inner_map_id); + if (inner_map_fd < 0) + return inner_map_fd; + + inner_map_object = malloc(ctx->inner_info->value_size); + if (!inner_map_object) { + close(inner_map_fd); + return -ENOMEM; + } + + ret = bpf_map_lookup_elem(inner_map_fd, &key, inner_map_object); + if (ret < 0) { + close(inner_map_fd); + free(inner_map_object); + return ret; + } + + a_ctl = (struct outter_map_alloc_control *)inner_map_object; + a_ctl->used--; + a_ctl->free_map[i / 32] |= (1U << (i % 32)); + bpf_map_update_elem(inner_map_fd, &key, a_ctl, BPF_ANY); + free(inner_map_object); + close(inner_map_fd); + + return 0; } static int alloc_outter_map_entry(struct op_context *ctx) { - int ret; - unsigned int first = 0; - int key = 0, ret_key; - int inner_map_fd; - __u32 inner_map_id; - struct outter_map_alloc_control *a_ctl; + int ret; + unsigned int first = 0; + int key = 0, ret_key; + int inner_map_fd; + __u32 inner_map_id; + struct outter_map_alloc_control *a_ctl; retry: - ret = bpf_map_lookup_elem(ctx->outter_fd, &key, &inner_map_id); - if (ret < 0) { - if (-errno != -ENOENT) - return ret; - ret = alloc_and_set_inner_map(ctx, key); - if (ret) - return ret; - - first = 1; - goto retry; - } - - inner_map_fd = bpf_map_get_fd_by_id(inner_map_id); - if (inner_map_fd < 0) - return inner_map_fd; - - ret = bpf_map_lookup_elem(inner_map_fd, &key, ctx->inner_map_object); - if (ret < 0) { - close(inner_map_fd); - return ret; - } - - a_ctl = (struct outter_map_alloc_control *)ctx->inner_map_object; - if (a_ctl->used >= (int)ctx->outter_info->max_entries) { - LOG_ERR("outter map entries has consumed out\n"); - close(inner_map_fd); - return -ENOENT; - } - - if (first) { - memset_s(a_ctl->free_map, sizeof(a_ctl->free_map), 0xff, sizeof(a_ctl->free_map)); - a_ctl->free_map[0] &= ~1U; - } - - ret_key = find_free_outter_map_entry(ctx, a_ctl); - if (ret_key > 0) { - ret = alloc_and_set_inner_map(ctx, ret_key); - if (ret) { - close(inner_map_fd); - return ret; - } - - a_ctl->used += first + 1; - bpf_map_update_elem(inner_map_fd, &key, a_ctl, BPF_ANY); - } - - close(inner_map_fd); - return ret_key; + ret = bpf_map_lookup_elem(ctx->outter_fd, &key, &inner_map_id); + if (ret < 0) { + if (-errno != -ENOENT) + return ret; + ret = alloc_and_set_inner_map(ctx, key); + if (ret) + return ret; + + first = 1; + goto retry; + } + + inner_map_fd = bpf_map_get_fd_by_id(inner_map_id); + if (inner_map_fd < 0) + return inner_map_fd; + + ret = bpf_map_lookup_elem(inner_map_fd, &key, ctx->inner_map_object); + if (ret < 0) { + close(inner_map_fd); + return ret; + } + + a_ctl = (struct outter_map_alloc_control *)ctx->inner_map_object; + if (a_ctl->used >= (int)ctx->outter_info->max_entries) { + LOG_ERR("outter map entries has consumed out\n"); + close(inner_map_fd); + return -ENOENT; + } + + if (first) { + memset_s(a_ctl->free_map, sizeof(a_ctl->free_map), 0xff, sizeof(a_ctl->free_map)); + a_ctl->free_map[0] &= ~1U; + } + + ret_key = find_free_outter_map_entry(ctx, a_ctl); + if (ret_key > 0) { + ret = alloc_and_set_inner_map(ctx, ret_key); + if (ret) { + close(inner_map_fd); + return ret; + } + + a_ctl->used += first + 1; + bpf_map_update_elem(inner_map_fd, &key, a_ctl, BPF_ANY); + } + + close(inner_map_fd); + return ret_key; } static int outter_key_to_inner_fd(struct op_context *ctx, unsigned int key) { - int ret; - __u32 inner_map_id; + int ret; + __u32 inner_map_id; - ret = bpf_map_lookup_elem(ctx->outter_fd, &key, &inner_map_id); - if (ret < 0) - return ret; + ret = bpf_map_lookup_elem(ctx->outter_fd, &key, &inner_map_id); + if (ret < 0) + return ret; - return bpf_map_get_fd_by_id(inner_map_id); + return bpf_map_get_fd_by_id(inner_map_id); } -static int copy_sfield_to_map(struct op_context *ctx, int o_index, - const ProtobufCFieldDescriptor *field) +static int copy_sfield_to_map(struct op_context *ctx, int o_index, const ProtobufCFieldDescriptor *field) { - int ret; - int key = 0; - int inner_fd; - char **value = (char**)((char*)ctx->value + field->offset); - char *save_value = *value; - - *(uintptr_t *)value = (size_t)o_index; - ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); - if (ret) { - free_outter_map_entry(ctx, &o_index); - return ret; - } - - inner_fd = outter_key_to_inner_fd(ctx, o_index); - if (inner_fd < 0) - return inner_fd; - - strcpy_s(ctx->inner_map_object, ctx->inner_info->value_size, save_value); - ret = bpf_map_update_elem(inner_fd, &key, ctx->inner_map_object, BPF_ANY); - close(inner_fd); - return ret; + int ret; + int key = 0; + int inner_fd; + char **value = (char **)((char *)ctx->value + field->offset); + char *save_value = *value; + + *(uintptr_t *)value = (size_t)o_index; + ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); + if (ret) { + free_outter_map_entry(ctx, &o_index); + return ret; + } + + inner_fd = outter_key_to_inner_fd(ctx, o_index); + if (inner_fd < 0) + return inner_fd; + + strcpy_s(ctx->inner_map_object, ctx->inner_info->value_size, save_value); + ret = bpf_map_update_elem(inner_fd, &key, ctx->inner_map_object, BPF_ANY); + close(inner_fd); + return ret; } -static int copy_msg_field_to_map(struct op_context *ctx, int o_index, - const ProtobufCFieldDescriptor *field) +static int copy_msg_field_to_map(struct op_context *ctx, int o_index, const ProtobufCFieldDescriptor *field) { - int ret; - int key = 0; - int inner_fd; - void **value = (void**)((char*)ctx->value + field->offset); - void *msg = *value; - struct op_context new_ctx; - const ProtobufCMessageDescriptor *desc; - - *(uintptr_t*)value = (size_t)o_index; - ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); - if (ret) { - free_outter_map_entry(ctx, &o_index); - return ret; - } - - inner_fd = outter_key_to_inner_fd(ctx, o_index); - if (inner_fd < 0) - return inner_fd; - - memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); - - new_ctx.curr_fd = inner_fd; - new_ctx.key = (void*)&key; - new_ctx.value = msg; - new_ctx.curr_info = ctx->inner_info; - - desc = ((ProtobufCMessage *)new_ctx.value)->descriptor; - if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { - close(inner_fd); - return -EINVAL; - } - - new_ctx.desc = desc; - - ret = update_bpf_map(&new_ctx); - close(inner_fd); - return ret; + int ret; + int key = 0; + int inner_fd; + void **value = (void **)((char *)ctx->value + field->offset); + void *msg = *value; + struct op_context new_ctx; + const ProtobufCMessageDescriptor *desc; + + *(uintptr_t *)value = (size_t)o_index; + ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); + if (ret) { + free_outter_map_entry(ctx, &o_index); + return ret; + } + + inner_fd = outter_key_to_inner_fd(ctx, o_index); + if (inner_fd < 0) + return inner_fd; + + memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); + + new_ctx.curr_fd = inner_fd; + new_ctx.key = (void *)&key; + new_ctx.value = msg; + new_ctx.curr_info = ctx->inner_info; + + desc = ((ProtobufCMessage *)new_ctx.value)->descriptor; + if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { + close(inner_fd); + return -EINVAL; + } + + new_ctx.desc = desc; + + ret = update_bpf_map(&new_ctx); + close(inner_fd); + return ret; } -static int field_handle(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int field_handle(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int key = 0; - - if (field->type == PROTOBUF_C_TYPE_MESSAGE || - field->type == PROTOBUF_C_TYPE_STRING) { - key = alloc_outter_map_entry(ctx); - if (key < 0) - return key; - } - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - return copy_msg_field_to_map(ctx, key, field); - case PROTOBUF_C_TYPE_STRING: - return copy_sfield_to_map(ctx, key, field); - default: - break; - } - - return 0; + int key = 0; + + if (field->type == PROTOBUF_C_TYPE_MESSAGE || field->type == PROTOBUF_C_TYPE_STRING) { + key = alloc_outter_map_entry(ctx); + if (key < 0) + return key; + } + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + return copy_msg_field_to_map(ctx, key, field); + case PROTOBUF_C_TYPE_STRING: + return copy_sfield_to_map(ctx, key, field); + default: + break; + } + + return 0; } -static int copy_indirect_data_to_map(struct op_context *ctx, int outter_key, - void *value, ProtobufCType type) +static int copy_indirect_data_to_map(struct op_context *ctx, int outter_key, void *value, ProtobufCType type) { - int ret = 0; - int inner_fd, key = 0; - struct op_context new_ctx; - const ProtobufCMessageDescriptor *desc; - - inner_fd = outter_key_to_inner_fd(ctx, outter_key); - if (inner_fd < 0) - return inner_fd; - - switch (type) { - case PROTOBUF_C_TYPE_MESSAGE: - memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); - new_ctx.curr_fd = inner_fd; - new_ctx.key = (void*)&key; - new_ctx.value = value; - new_ctx.curr_info = ctx->inner_info; - - desc = ((ProtobufCMessage *)value)->descriptor; - if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { - close(inner_fd); - return -EINVAL; - } - - new_ctx.desc = desc; - ret = update_bpf_map(&new_ctx); - break; - case PROTOBUF_C_TYPE_STRING: - strcpy_s(ctx->inner_map_object, ctx->inner_info->value_size, (char*)value); - ret = bpf_map_update_elem(inner_fd, &key, - ctx->inner_map_object, BPF_ANY); - break; - default: - break; - } - - close(inner_fd); - return ret; + int ret = 0; + int inner_fd, key = 0; + struct op_context new_ctx; + const ProtobufCMessageDescriptor *desc; + + inner_fd = outter_key_to_inner_fd(ctx, outter_key); + if (inner_fd < 0) + return inner_fd; + + switch (type) { + case PROTOBUF_C_TYPE_MESSAGE: + memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); + new_ctx.curr_fd = inner_fd; + new_ctx.key = (void *)&key; + new_ctx.value = value; + new_ctx.curr_info = ctx->inner_info; + + desc = ((ProtobufCMessage *)value)->descriptor; + if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { + close(inner_fd); + return -EINVAL; + } + + new_ctx.desc = desc; + ret = update_bpf_map(&new_ctx); + break; + case PROTOBUF_C_TYPE_STRING: + strcpy_s(ctx->inner_map_object, ctx->inner_info->value_size, (char *)value); + ret = bpf_map_update_elem(inner_fd, &key, ctx->inner_map_object, BPF_ANY); + break; + default: + break; + } + + close(inner_fd); + return ret; } -static bool indirect_data_type(ProtobufCType type) +static bool indirect_data_type(ProtobufCType type) { - switch (type) { - case PROTOBUF_C_TYPE_MESSAGE: - case PROTOBUF_C_TYPE_STRING: - return true; - default: - return false; - } + switch (type) { + case PROTOBUF_C_TYPE_MESSAGE: + case PROTOBUF_C_TYPE_STRING: + return true; + default: + return false; + } } -static int repeat_field_handle(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int repeat_field_handle(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int ret, ret1; - unsigned int i; - int outter_key, inner_fd, key = 0; - void *n = ((char*)ctx->value) + field->quantifier_offset; - void ***value = (void***)((char*)ctx->value + field->offset); - void **origin_value = *value; - char *inner_map_object; - - outter_key = alloc_outter_map_entry(ctx); - if (outter_key < 0) - return outter_key; - - *(uintptr_t*)value = (size_t)outter_key; - ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); - if (ret) { - free_outter_map_entry(ctx, &outter_key); - return ret; - } - - inner_fd = outter_key_to_inner_fd(ctx, outter_key); - if (inner_fd < 0) - return inner_fd; - - inner_map_object = calloc(1, ctx->inner_info->value_size); - if (!inner_map_object) { - close(inner_fd); - return -ENOMEM; - } - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - case PROTOBUF_C_TYPE_STRING: - for (i = 0; i < *(unsigned int*)n; i++) { - outter_key = alloc_outter_map_entry(ctx); - if (outter_key < 0) - goto end; - - *((uintptr_t*)inner_map_object + i) = (size_t)outter_key; - ret = copy_indirect_data_to_map(ctx, outter_key, - origin_value[i], field->type); - if (ret) - goto end; - } - break; - default: - memcpy_s(inner_map_object, ctx->inner_info->value_size, (void*)origin_value, - *(size_t*)n * sizeof_elt_in_repeated_array(field->type)); - break; - } + int ret, ret1; + unsigned int i; + int outter_key, inner_fd, key = 0; + void *n = ((char *)ctx->value) + field->quantifier_offset; + void ***value = (void ***)((char *)ctx->value + field->offset); + void **origin_value = *value; + char *inner_map_object; + + outter_key = alloc_outter_map_entry(ctx); + if (outter_key < 0) + return outter_key; + + *(uintptr_t *)value = (size_t)outter_key; + ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); + if (ret) { + free_outter_map_entry(ctx, &outter_key); + return ret; + } + + inner_fd = outter_key_to_inner_fd(ctx, outter_key); + if (inner_fd < 0) + return inner_fd; + + inner_map_object = calloc(1, ctx->inner_info->value_size); + if (!inner_map_object) { + close(inner_fd); + return -ENOMEM; + } + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + case PROTOBUF_C_TYPE_STRING: + for (i = 0; i < *(unsigned int *)n; i++) { + outter_key = alloc_outter_map_entry(ctx); + if (outter_key < 0) + goto end; + + *((uintptr_t *)inner_map_object + i) = (size_t)outter_key; + ret = copy_indirect_data_to_map(ctx, outter_key, origin_value[i], field->type); + if (ret) + goto end; + } + break; + default: + memcpy_s( + inner_map_object, + ctx->inner_info->value_size, + (void *)origin_value, + *(size_t *)n * sizeof_elt_in_repeated_array(field->type)); + break; + } end: - ret1 = bpf_map_update_elem(inner_fd, &key, inner_map_object, BPF_ANY); - if (ret1) { - ret = ret1; - if (indirect_data_type(field->type)) - free_keys(ctx, inner_map_object, *(size_t*)n); - } + ret1 = bpf_map_update_elem(inner_fd, &key, inner_map_object, BPF_ANY); + if (ret1) { + ret = ret1; + if (indirect_data_type(field->type)) + free_keys(ctx, inner_map_object, *(size_t *)n); + } - free(inner_map_object); - close(inner_fd); + free(inner_map_object); + close(inner_fd); - return ret; + return ret; } static int update_bpf_map(struct op_context *ctx) { - int ret; - unsigned int i; - void *temp_val; - const ProtobufCMessageDescriptor *desc = ctx->desc; - - if (desc->sizeof_message > ctx->curr_info->value_size) { - LOG_ERR("map entry size is too small\n"); - return -EINVAL; - } - - temp_val = malloc(ctx->curr_info->value_size); - if (!temp_val) - return -ENOMEM; - - memcpy_s(temp_val, ctx->curr_info->value_size, ctx->value, ctx->curr_info->value_size); - ctx->value = temp_val; - - for (i = 0; i < desc->n_fields; i++) { - const ProtobufCFieldDescriptor *field = desc->fields + i; - - if (!selected_oneof_field(ctx->value, field) || - !valid_field_value(ctx->value, field)) - continue; - - switch (field->label) { - case PROTOBUF_C_LABEL_REPEATED: - ret = repeat_field_handle(ctx, field); - break; - default: - ret = field_handle(ctx, field); - break; - } - - if (ret) { - LOG_INFO("field[%d] handle fail\n", i); - free(temp_val); - return ret; - } - } - - ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); - free(temp_val); - return ret; + int ret; + unsigned int i; + void *temp_val; + const ProtobufCMessageDescriptor *desc = ctx->desc; + + if (desc->sizeof_message > ctx->curr_info->value_size) { + LOG_ERR("map entry size is too small\n"); + return -EINVAL; + } + + temp_val = malloc(ctx->curr_info->value_size); + if (!temp_val) + return -ENOMEM; + + memcpy_s(temp_val, ctx->curr_info->value_size, ctx->value, ctx->curr_info->value_size); + ctx->value = temp_val; + + for (i = 0; i < desc->n_fields; i++) { + const ProtobufCFieldDescriptor *field = desc->fields + i; + + if (!selected_oneof_field(ctx->value, field) || !valid_field_value(ctx->value, field)) + continue; + + switch (field->label) { + case PROTOBUF_C_LABEL_REPEATED: + ret = repeat_field_handle(ctx, field); + break; + default: + ret = field_handle(ctx, field); + break; + } + + if (ret) { + LOG_INFO("field[%d] handle fail\n", i); + free(temp_val); + return ret; + } + } + + ret = bpf_map_update_elem(ctx->curr_fd, ctx->key, ctx->value, BPF_ANY); + free(temp_val); + return ret; } -static int map_info_check(struct bpf_map_info *outter_info, - struct bpf_map_info *inner_info) +static int map_info_check(struct bpf_map_info *outter_info, struct bpf_map_info *inner_info) { - if (outter_info->type != BPF_MAP_TYPE_ARRAY_OF_MAPS) { - LOG_ERR("outter map type must be BPF_MAP_TYPE_ARRAY_OF_MAPS\n"); - return -EINVAL; - } - - if (outter_info->max_entries < 2 || - outter_info->max_entries > MAX_OUTTER_MAP_ENTRIES) { - LOG_ERR("outter map max_entries must be in[2,%d]\n", - MAX_OUTTER_MAP_ENTRIES); - return -EINVAL; - } - - if (inner_info->value_size < sizeof(struct outter_map_alloc_control)) { - LOG_ERR("inner map value_size must be large than %lu(bytes)\n", - sizeof(struct outter_map_alloc_control)); - return -EINVAL; - } - - return 0; + if (outter_info->type != BPF_MAP_TYPE_ARRAY_OF_MAPS) { + LOG_ERR("outter map type must be BPF_MAP_TYPE_ARRAY_OF_MAPS\n"); + return -EINVAL; + } + + if (outter_info->max_entries < 2 || outter_info->max_entries > MAX_OUTTER_MAP_ENTRIES) { + LOG_ERR("outter map max_entries must be in[2,%d]\n", MAX_OUTTER_MAP_ENTRIES); + return -EINVAL; + } + + if (inner_info->value_size < sizeof(struct outter_map_alloc_control)) { + LOG_ERR("inner map value_size must be large than %lu(bytes)\n", sizeof(struct outter_map_alloc_control)); + return -EINVAL; + } + + return 0; } int deserial_update_elem(void *key, void *value) { - int ret; - const char *map_name = NULL; - struct op_context context = {.inner_map_object = NULL}; - const ProtobufCMessageDescriptor *desc; - struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0}; - int map_fd, outter_fd = 0, inner_fd = 0; - unsigned int id, outter_id = 0, inner_id = 0; - - if (!key || !value) - return -EINVAL; - - desc = ((ProtobufCMessage *)value)->descriptor; - if (desc && desc->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) - map_name = desc->short_name; - - ret = get_map_ids(map_name, &id, &outter_id, &inner_id); - if (ret) - return ret; - - ret = get_map_fd_info(id, &map_fd, &info); - if (ret < 0) { - LOG_ERR("invlid MAP_ID: %d\n", id); - return ret; - } - - if (!map_name) { - ret = bpf_map_update_elem(map_fd, key, value, BPF_ANY); - goto end; - } - - ret = get_map_fd_info(inner_id, &inner_fd, &inner_info); - ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info); - if (ret < 0 || map_info_check(&outter_info, &inner_info)) - goto end; - - deserial_delete_elem(key, desc); - - init_op_context(context, key, value, desc, outter_fd, map_fd, - &outter_info, &inner_info, &info); - - context.inner_map_object = calloc(1, context.inner_info->value_size); - if (context.inner_map_object == NULL) { - ret = -errno; - goto end; - } - - normalize_key(&context, key, map_name); - - ret = update_bpf_map(&context); - if (ret) - deserial_delete_elem(key, desc); + int ret; + const char *map_name = NULL; + struct op_context context = {.inner_map_object = NULL}; + const ProtobufCMessageDescriptor *desc; + struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0}; + int map_fd, outter_fd = 0, inner_fd = 0; + unsigned int id, outter_id = 0, inner_id = 0; + + if (!key || !value) + return -EINVAL; + + desc = ((ProtobufCMessage *)value)->descriptor; + if (desc && desc->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + map_name = desc->short_name; + + ret = get_map_ids(map_name, &id, &outter_id, &inner_id); + if (ret) + return ret; + + ret = get_map_fd_info(id, &map_fd, &info); + if (ret < 0) { + LOG_ERR("invlid MAP_ID: %d\n", id); + return ret; + } + + if (!map_name) { + ret = bpf_map_update_elem(map_fd, key, value, BPF_ANY); + goto end; + } + + ret = get_map_fd_info(inner_id, &inner_fd, &inner_info); + ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info); + if (ret < 0 || map_info_check(&outter_info, &inner_info)) + goto end; + + deserial_delete_elem(key, desc); + + init_op_context(context, key, value, desc, outter_fd, map_fd, &outter_info, &inner_info, &info); + + context.inner_map_object = calloc(1, context.inner_info->value_size); + if (context.inner_map_object == NULL) { + ret = -errno; + goto end; + } + + normalize_key(&context, key, map_name); + + ret = update_bpf_map(&context); + if (ret) + deserial_delete_elem(key, desc); end: - if (context.key != NULL) - free(context.key); - if (context.inner_map_object != NULL) - free(context.inner_map_object); - if (map_fd > 0) - close(map_fd); - if (outter_fd > 0) - close(outter_fd); - if (inner_fd > 0) - close(inner_fd); - return ret; + if (context.key != NULL) + free(context.key); + if (context.inner_map_object != NULL) + free(context.inner_map_object); + if (map_fd > 0) + close(map_fd); + if (outter_fd > 0) + close(outter_fd); + if (inner_fd > 0) + close(inner_fd); + return ret; } -static int query_string_field(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int query_string_field(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int key = 0, ret; - int inner_fd; - void *string; - void *outter_key = (void*)((char*)ctx->value + field->offset); - - inner_fd = outter_key_to_inner_fd(ctx, *(int*)outter_key); - if (inner_fd < 0) - return inner_fd; - - string = malloc(ctx->inner_info->value_size); - if (!string) { - close(inner_fd); - return -ENOMEM; - } - - (*(uintptr_t *)outter_key) = (uintptr_t)string; - - ret = bpf_map_lookup_elem(inner_fd, &key, string); - close(inner_fd); - return ret; + int key = 0, ret; + int inner_fd; + void *string; + void *outter_key = (void *)((char *)ctx->value + field->offset); + + inner_fd = outter_key_to_inner_fd(ctx, *(int *)outter_key); + if (inner_fd < 0) + return inner_fd; + + string = malloc(ctx->inner_info->value_size); + if (!string) { + close(inner_fd); + return -ENOMEM; + } + + (*(uintptr_t *)outter_key) = (uintptr_t)string; + + ret = bpf_map_lookup_elem(inner_fd, &key, string); + close(inner_fd); + return ret; } -static int query_message_field(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int query_message_field(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int ret; - int key = 0; - int inner_fd; - void *message; - struct op_context new_ctx; - const ProtobufCMessageDescriptor *desc; - uintptr_t *outter_key = (uintptr_t *)((char*)ctx->value + field->offset); - - inner_fd = outter_key_to_inner_fd(ctx, *outter_key); - if (inner_fd < 0) - return inner_fd; - - memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); - new_ctx.curr_fd = inner_fd; - new_ctx.key = (void*)&key; - new_ctx.curr_info = ctx->inner_info; - - desc = (ProtobufCMessageDescriptor*)field->descriptor; - if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { - close(inner_fd); - return -EINVAL; - } - - new_ctx.desc = desc; - - message = create_struct(&new_ctx, &ret); - *outter_key = (uintptr_t)message; - close(inner_fd); - return ret; + int ret; + int key = 0; + int inner_fd; + void *message; + struct op_context new_ctx; + const ProtobufCMessageDescriptor *desc; + uintptr_t *outter_key = (uintptr_t *)((char *)ctx->value + field->offset); + + inner_fd = outter_key_to_inner_fd(ctx, *outter_key); + if (inner_fd < 0) + return inner_fd; + + memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); + new_ctx.curr_fd = inner_fd; + new_ctx.key = (void *)&key; + new_ctx.curr_info = ctx->inner_info; + + desc = (ProtobufCMessageDescriptor *)field->descriptor; + if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { + close(inner_fd); + return -EINVAL; + } + + new_ctx.desc = desc; + + message = create_struct(&new_ctx, &ret); + *outter_key = (uintptr_t)message; + close(inner_fd); + return ret; } -static int field_query(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int field_query(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - return query_message_field(ctx, field); - case PROTOBUF_C_TYPE_STRING: - return query_string_field(ctx, field); - default: - break; - } - - return 0; + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + return query_message_field(ctx, field); + case PROTOBUF_C_TYPE_STRING: + return query_string_field(ctx, field); + default: + break; + } + + return 0; } -static void* create_indirect_struct(struct op_context *ctx, unsigned long outter_key, - const ProtobufCFieldDescriptor *field, - int *err) +static void *create_indirect_struct( + struct op_context *ctx, unsigned long outter_key, const ProtobufCFieldDescriptor *field, int *err) { - int inner_fd, key = 0; - void *value; - struct op_context new_ctx; - const ProtobufCMessageDescriptor *desc; - - inner_fd = outter_key_to_inner_fd(ctx, outter_key); - if (inner_fd < 0) { - *err = inner_fd; - return NULL; - } - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); - new_ctx.curr_fd = inner_fd; - new_ctx.key = (void*)&key; - new_ctx.curr_info = ctx->inner_info; - - desc = (ProtobufCMessageDescriptor*)field->descriptor; - if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { - *err = -EINVAL; - close(inner_fd); - return NULL; - } - - new_ctx.desc = desc; - value = create_struct(&new_ctx, err); - close(inner_fd); - return value; - default: - value = malloc(ctx->inner_info->value_size); - if (!value) { - *err = -ENOMEM; - close(inner_fd); - return NULL; - } - - *err = bpf_map_lookup_elem(inner_fd, &key, value); - if (*err < 0) { - close(inner_fd); - return value; - } - - break; - } - - close(inner_fd); - *err = 0; - return value; + int inner_fd, key = 0; + void *value; + struct op_context new_ctx; + const ProtobufCMessageDescriptor *desc; + + inner_fd = outter_key_to_inner_fd(ctx, outter_key); + if (inner_fd < 0) { + *err = inner_fd; + return NULL; + } + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); + new_ctx.curr_fd = inner_fd; + new_ctx.key = (void *)&key; + new_ctx.curr_info = ctx->inner_info; + + desc = (ProtobufCMessageDescriptor *)field->descriptor; + if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { + *err = -EINVAL; + close(inner_fd); + return NULL; + } + + new_ctx.desc = desc; + value = create_struct(&new_ctx, err); + close(inner_fd); + return value; + default: + value = malloc(ctx->inner_info->value_size); + if (!value) { + *err = -ENOMEM; + close(inner_fd); + return NULL; + } + + *err = bpf_map_lookup_elem(inner_fd, &key, value); + if (*err < 0) { + close(inner_fd); + return value; + } + + break; + } + + close(inner_fd); + *err = 0; + return value; } - -static int repeat_field_query(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) + +static int repeat_field_query(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int ret; - int key = 0; - int inner_fd; - void *array; - unsigned int i; - void *n = ((char*)ctx->value) + field->quantifier_offset; - uintptr_t *outter_key = (uintptr_t*)((char*)ctx->value + field->offset); - - inner_fd = outter_key_to_inner_fd(ctx, *outter_key); - if (inner_fd < 0) - return inner_fd; - - array = calloc(1, ctx->inner_info->value_size); - if (!array) { - close(inner_fd); - return -ENOMEM; - } - - *outter_key = (uintptr_t)array; - ret = bpf_map_lookup_elem(inner_fd, &key, array); - if (ret < 0) { - close(inner_fd); - return ret; - } - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - case PROTOBUF_C_TYPE_STRING: - for (i = 0; i < *(unsigned int*)n; i++) { - outter_key = (uintptr_t*)array + i; - *outter_key = (uintptr_t)create_indirect_struct(ctx, - *outter_key, field, &ret); - if (ret) - break; - } - break; - default: - break; - } - - close(inner_fd); - return ret; + int ret; + int key = 0; + int inner_fd; + void *array; + unsigned int i; + void *n = ((char *)ctx->value) + field->quantifier_offset; + uintptr_t *outter_key = (uintptr_t *)((char *)ctx->value + field->offset); + + inner_fd = outter_key_to_inner_fd(ctx, *outter_key); + if (inner_fd < 0) + return inner_fd; + + array = calloc(1, ctx->inner_info->value_size); + if (!array) { + close(inner_fd); + return -ENOMEM; + } + + *outter_key = (uintptr_t)array; + ret = bpf_map_lookup_elem(inner_fd, &key, array); + if (ret < 0) { + close(inner_fd); + return ret; + } + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + case PROTOBUF_C_TYPE_STRING: + for (i = 0; i < *(unsigned int *)n; i++) { + outter_key = (uintptr_t *)array + i; + *outter_key = (uintptr_t)create_indirect_struct(ctx, *outter_key, field, &ret); + if (ret) + break; + } + break; + default: + break; + } + + close(inner_fd); + return ret; } -static void* create_struct(struct op_context *ctx, int *err) +static void *create_struct(struct op_context *ctx, int *err) { - void *value; - int ret; - unsigned int i; - const ProtobufCMessageDescriptor *desc = ctx->desc; - - *err = 0; - - if (desc->sizeof_message > ctx->curr_info->value_size) { - LOG_ERR("map entry size is too small\n"); - return NULL; - } - - value = calloc(1, ctx->curr_info->value_size); - if (!value) - return value; - - ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, value); - if (ret < 0) { - free(value); - return NULL; - } - - ctx->value = value; - for (i = 0; i < desc->n_fields; i++) { - const ProtobufCFieldDescriptor *field = desc->fields + i; - - if (!selected_oneof_field(ctx->value, field) || - !valid_field_value(ctx->value, field)) - continue; - - switch (field->label) { - case PROTOBUF_C_LABEL_REPEATED: - ret = repeat_field_query(ctx, field); - break; - default: - ret = field_query(ctx, field); - break; - } - - if (ret) { - LOG_INFO("field[%d] query fail\n", i); - *err = 1; - return value; - } - } - - return value; + void *value; + int ret; + unsigned int i; + const ProtobufCMessageDescriptor *desc = ctx->desc; + + *err = 0; + + if (desc->sizeof_message > ctx->curr_info->value_size) { + LOG_ERR("map entry size is too small\n"); + return NULL; + } + + value = calloc(1, ctx->curr_info->value_size); + if (!value) + return value; + + ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, value); + if (ret < 0) { + free(value); + return NULL; + } + + ctx->value = value; + for (i = 0; i < desc->n_fields; i++) { + const ProtobufCFieldDescriptor *field = desc->fields + i; + + if (!selected_oneof_field(ctx->value, field) || !valid_field_value(ctx->value, field)) + continue; + + switch (field->label) { + case PROTOBUF_C_LABEL_REPEATED: + ret = repeat_field_query(ctx, field); + break; + default: + ret = field_query(ctx, field); + break; + } + + if (ret) { + LOG_INFO("field[%d] query fail\n", i); + *err = 1; + return value; + } + } + + return value; } -void* deserial_lookup_elem(void *key, const void *msg_desciptor) +void *deserial_lookup_elem(void *key, const void *msg_desciptor) { - int ret, err; - void *value = NULL; - const char *map_name = NULL; - struct op_context context = {.inner_map_object = NULL}; - const ProtobufCMessageDescriptor *desc; - struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0}; - int map_fd, outter_fd = 0, inner_fd = 0; - unsigned int id, outter_id = 0, inner_id = 0; - - if (msg_desciptor == NULL || key == NULL) - return NULL; - - desc = (ProtobufCMessageDescriptor*)msg_desciptor; - if (desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) - return NULL; - - map_name = desc->short_name; - ret = get_map_ids(map_name, &id, &outter_id, &inner_id); - if (ret) - return NULL; - - ret = get_map_fd_info(id, &map_fd, &info); - if (ret < 0) { - LOG_ERR("invlid MAP_ID: %d\n", id); - return NULL; - } - - ret = get_map_fd_info(inner_id, &inner_fd, &inner_info); - ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info); - if (ret < 0 || map_info_check(&outter_info, &inner_info)) - goto end; - - init_op_context(context, key, NULL, desc, outter_fd, map_fd, - &outter_info, &inner_info, &info); - - normalize_key(&context, key, map_name); - value = create_struct(&context, &err); - if (err != 0) { - deserial_free_elem(value); - value = NULL; - } + int ret, err; + void *value = NULL; + const char *map_name = NULL; + struct op_context context = {.inner_map_object = NULL}; + const ProtobufCMessageDescriptor *desc; + struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0}; + int map_fd, outter_fd = 0, inner_fd = 0; + unsigned int id, outter_id = 0, inner_id = 0; + + if (msg_desciptor == NULL || key == NULL) + return NULL; + + desc = (ProtobufCMessageDescriptor *)msg_desciptor; + if (desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + return NULL; + + map_name = desc->short_name; + ret = get_map_ids(map_name, &id, &outter_id, &inner_id); + if (ret) + return NULL; + + ret = get_map_fd_info(id, &map_fd, &info); + if (ret < 0) { + LOG_ERR("invlid MAP_ID: %d\n", id); + return NULL; + } + + ret = get_map_fd_info(inner_id, &inner_fd, &inner_info); + ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info); + if (ret < 0 || map_info_check(&outter_info, &inner_info)) + goto end; + + init_op_context(context, key, NULL, desc, outter_fd, map_fd, &outter_info, &inner_info, &info); + + normalize_key(&context, key, map_name); + value = create_struct(&context, &err); + if (err != 0) { + deserial_free_elem(value); + value = NULL; + } end: - if (context.key != NULL) - free(context.key); - if (map_fd > 0) - close(map_fd); - if (outter_fd > 0) - close(outter_fd); - if (inner_fd > 0) - close(inner_fd); - return value; + if (context.key != NULL) + free(context.key); + if (map_fd > 0) + close(map_fd); + if (outter_fd > 0) + close(outter_fd); + if (inner_fd > 0) + close(inner_fd); + return value; } -static int indirect_field_del(struct op_context *ctx, unsigned int outter_key, - const ProtobufCFieldDescriptor *field) +static int indirect_field_del(struct op_context *ctx, unsigned int outter_key, const ProtobufCFieldDescriptor *field) { - char *inner_map_object = NULL; - int inner_fd, key = 0; - struct op_context new_ctx; - const ProtobufCMessageDescriptor *desc; - - if (!valid_outter_key(ctx, outter_key)) - return -EINVAL; - - inner_fd = outter_key_to_inner_fd(ctx, (unsigned long)outter_key); - if (inner_fd < 0) - return inner_fd; - - free_outter_map_entry(ctx, &outter_key); - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - desc = (ProtobufCMessageDescriptor*)field->descriptor; - if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { - close(inner_fd); - return -EINVAL; - } - - inner_map_object = malloc(ctx->inner_info->value_size); - if (!inner_map_object) { - close(inner_fd); - return -ENOMEM; - } - - memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); - new_ctx.curr_fd = inner_fd; - new_ctx.key = (void*)&key; - new_ctx.curr_info = ctx->inner_info; - new_ctx.value = inner_map_object; - new_ctx.desc = desc; - - (void)del_bpf_map(&new_ctx, 1); - free(inner_map_object); - break; - - default: - break; - } - - close(inner_fd); - return 0; + char *inner_map_object = NULL; + int inner_fd, key = 0; + struct op_context new_ctx; + const ProtobufCMessageDescriptor *desc; + + if (!valid_outter_key(ctx, outter_key)) + return -EINVAL; + + inner_fd = outter_key_to_inner_fd(ctx, (unsigned long)outter_key); + if (inner_fd < 0) + return inner_fd; + + free_outter_map_entry(ctx, &outter_key); + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + desc = (ProtobufCMessageDescriptor *)field->descriptor; + if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { + close(inner_fd); + return -EINVAL; + } + + inner_map_object = malloc(ctx->inner_info->value_size); + if (!inner_map_object) { + close(inner_fd); + return -ENOMEM; + } + + memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); + new_ctx.curr_fd = inner_fd; + new_ctx.key = (void *)&key; + new_ctx.curr_info = ctx->inner_info; + new_ctx.value = inner_map_object; + new_ctx.desc = desc; + + (void)del_bpf_map(&new_ctx, 1); + free(inner_map_object); + break; + + default: + break; + } + + close(inner_fd); + return 0; } -static int repeat_field_del(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int repeat_field_del(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int ret; - unsigned int i; - int inner_fd, key = 0; - void *inner_map_object = NULL; - void *n; - uintptr_t *outter_key; - - ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, ctx->value); - if (ret < 0) { - LOG_WARN("faild to find map(%d) elem: %d.", ctx->curr_fd, ret); - return ret; - } - - outter_key = (uintptr_t*)((char*)ctx->value + field->offset); - if (!valid_outter_key(ctx, *outter_key)) - return -EINVAL; - - inner_fd = outter_key_to_inner_fd(ctx, *outter_key); - if (inner_fd < 0) - return inner_fd; - - ret = free_outter_map_entry(ctx, outter_key); - if (ret) - return ret; - - n = ((char*)ctx->value) + field->quantifier_offset; - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - //lint -fallthrough - case PROTOBUF_C_TYPE_STRING: - inner_map_object = calloc(1, ctx->inner_info->value_size); - if (!inner_map_object) { - ret = -ENOMEM; - goto end; - } - - ret = bpf_map_lookup_elem(inner_fd, &key, inner_map_object); - if (ret < 0) - goto end; - - for (i = 0; i < *(size_t*)n; i++) { - outter_key = (uintptr_t*)inner_map_object + i; - indirect_field_del(ctx, *outter_key, field); - } - default: - break; - } + int ret; + unsigned int i; + int inner_fd, key = 0; + void *inner_map_object = NULL; + void *n; + uintptr_t *outter_key; + + ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, ctx->value); + if (ret < 0) { + LOG_WARN("faild to find map(%d) elem: %d.", ctx->curr_fd, ret); + return ret; + } + + outter_key = (uintptr_t *)((char *)ctx->value + field->offset); + if (!valid_outter_key(ctx, *outter_key)) + return -EINVAL; + + inner_fd = outter_key_to_inner_fd(ctx, *outter_key); + if (inner_fd < 0) + return inner_fd; + + ret = free_outter_map_entry(ctx, outter_key); + if (ret) + return ret; + + n = ((char *)ctx->value) + field->quantifier_offset; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + // lint -fallthrough + case PROTOBUF_C_TYPE_STRING: + inner_map_object = calloc(1, ctx->inner_info->value_size); + if (!inner_map_object) { + ret = -ENOMEM; + goto end; + } + + ret = bpf_map_lookup_elem(inner_fd, &key, inner_map_object); + if (ret < 0) + goto end; + + for (i = 0; i < *(size_t *)n; i++) { + outter_key = (uintptr_t *)inner_map_object + i; + indirect_field_del(ctx, *outter_key, field); + } + default: + break; + } end: - if (inner_map_object != NULL) - free(inner_map_object); - close(inner_fd); - return ret; + if (inner_map_object != NULL) + free(inner_map_object); + close(inner_fd); + return ret; } -static int msg_field_del(struct op_context *ctx, int inner_fd, - const ProtobufCFieldDescriptor *field) +static int msg_field_del(struct op_context *ctx, int inner_fd, const ProtobufCFieldDescriptor *field) { - int key = 0; - int ret; - char *inner_map_object = NULL; - struct op_context new_ctx; - const ProtobufCMessageDescriptor *desc; - - desc = (ProtobufCMessageDescriptor*)field->descriptor; - if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) - return -EINVAL; - - inner_map_object = malloc(ctx->inner_info->value_size); - if (!inner_map_object) - return -ENOMEM; - - memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); - new_ctx.curr_fd = inner_fd; - new_ctx.key = (void*)&key; - new_ctx.curr_info = ctx->inner_info; - new_ctx.value = inner_map_object; - new_ctx.desc = desc; - - ret = del_bpf_map(&new_ctx, 1); - free(inner_map_object); - return ret; + int key = 0; + int ret; + char *inner_map_object = NULL; + struct op_context new_ctx; + const ProtobufCMessageDescriptor *desc; + + desc = (ProtobufCMessageDescriptor *)field->descriptor; + if (!desc || desc->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + return -EINVAL; + + inner_map_object = malloc(ctx->inner_info->value_size); + if (!inner_map_object) + return -ENOMEM; + + memcpy_s(&new_ctx, sizeof(new_ctx), ctx, sizeof(*ctx)); + new_ctx.curr_fd = inner_fd; + new_ctx.key = (void *)&key; + new_ctx.curr_info = ctx->inner_info; + new_ctx.value = inner_map_object; + new_ctx.desc = desc; + + ret = del_bpf_map(&new_ctx, 1); + free(inner_map_object); + return ret; } -static int field_del(struct op_context *ctx, - const ProtobufCFieldDescriptor *field) +static int field_del(struct op_context *ctx, const ProtobufCFieldDescriptor *field) { - int ret; - int inner_fd; - uintptr_t *outter_key; - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - case PROTOBUF_C_TYPE_STRING: - ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, ctx->value); - if (ret < 0) - return ret; - - outter_key = (uintptr_t*)((char*)ctx->value + field->offset); - if (!valid_outter_key(ctx, *outter_key)) - return -EINVAL; - - inner_fd = outter_key_to_inner_fd(ctx, *outter_key); - if (inner_fd < 0) - return inner_fd; - - free_outter_map_entry(ctx, outter_key); - - if (field->type == PROTOBUF_C_TYPE_STRING) { - close(inner_fd); - break; - } - - msg_field_del(ctx, inner_fd, field); - close(inner_fd); - break; - default: - break; - } - - return 0; + int ret; + int inner_fd; + uintptr_t *outter_key; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + case PROTOBUF_C_TYPE_STRING: + ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, ctx->value); + if (ret < 0) + return ret; + + outter_key = (uintptr_t *)((char *)ctx->value + field->offset); + if (!valid_outter_key(ctx, *outter_key)) + return -EINVAL; + + inner_fd = outter_key_to_inner_fd(ctx, *outter_key); + if (inner_fd < 0) + return inner_fd; + + free_outter_map_entry(ctx, outter_key); + + if (field->type == PROTOBUF_C_TYPE_STRING) { + close(inner_fd); + break; + } + + msg_field_del(ctx, inner_fd, field); + close(inner_fd); + break; + default: + break; + } + + return 0; } static int del_bpf_map(struct op_context *ctx, int is_inner) { - int ret; - unsigned int i; - const ProtobufCMessageDescriptor *desc = ctx->desc; - - ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, ctx->value); - if (ret < 0) - return ret; - - for (i = 0; i < desc->n_fields; i++) { - const ProtobufCFieldDescriptor *field = desc->fields + i; - - if (!selected_oneof_field(ctx->value, field) || - !valid_field_value(ctx->value, field)) - continue; - - switch (field->label) { - case PROTOBUF_C_LABEL_REPEATED: - ret = repeat_field_del(ctx, field); - if (ret) - goto end; - break; - default: - ret = field_del(ctx, field); - if (ret) - goto end; - break; - } - } + int ret; + unsigned int i; + const ProtobufCMessageDescriptor *desc = ctx->desc; + + ret = bpf_map_lookup_elem(ctx->curr_fd, ctx->key, ctx->value); + if (ret < 0) + return ret; + + for (i = 0; i < desc->n_fields; i++) { + const ProtobufCFieldDescriptor *field = desc->fields + i; + + if (!selected_oneof_field(ctx->value, field) || !valid_field_value(ctx->value, field)) + continue; + + switch (field->label) { + case PROTOBUF_C_LABEL_REPEATED: + ret = repeat_field_del(ctx, field); + if (ret) + goto end; + break; + default: + ret = field_del(ctx, field); + if (ret) + goto end; + break; + } + } end: - return (is_inner == 1) ? close(ctx->curr_fd) : - bpf_map_delete_elem(ctx->curr_fd, ctx->key); + return (is_inner == 1) ? close(ctx->curr_fd) : bpf_map_delete_elem(ctx->curr_fd, ctx->key); } int deserial_delete_elem(void *key, const void *msg_desciptor) { - int ret; - const char *map_name = NULL; - struct op_context context = {.inner_map_object = NULL}; - const ProtobufCMessageDescriptor *desc; - struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0}; - int map_fd, outter_fd = 0, inner_fd = 0; - unsigned int id, outter_id = 0, inner_id = 0; - char *inner_map_object = NULL; - - if (!key || !msg_desciptor) - return -EINVAL; - - desc = (ProtobufCMessageDescriptor *)msg_desciptor; - if (desc->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) - map_name = desc->short_name; - - ret = get_map_ids(map_name, &id, &outter_id, &inner_id); - if (ret) - return ret; - - ret = get_map_fd_info(id, &map_fd, &info); - if (ret < 0) { - LOG_ERR("invlid MAP_ID: %d\n", id); - return ret; - } - - if (!map_name) { - ret = bpf_map_delete_elem(map_fd, key); - goto end; - } - - ret = get_map_fd_info(inner_id, &inner_fd, &inner_info); - ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info); - if (ret < 0 || map_info_check(&outter_info, &inner_info)) - goto end; - - init_op_context(context, key, NULL, desc, outter_fd, map_fd, - &outter_info, &inner_info, &info); - - context.inner_map_object = calloc(1, context.inner_info->value_size); - context.value = calloc(1, context.curr_info->value_size); - if (!context.inner_map_object || !context.value) { - ret = -errno; - goto end; - } - - inner_map_object = context.inner_map_object; - - normalize_key(&context, key, map_name); - ret = del_bpf_map(&context, 0); + int ret; + const char *map_name = NULL; + struct op_context context = {.inner_map_object = NULL}; + const ProtobufCMessageDescriptor *desc; + struct bpf_map_info outter_info = {0}, inner_info = {0}, info = {0}; + int map_fd, outter_fd = 0, inner_fd = 0; + unsigned int id, outter_id = 0, inner_id = 0; + char *inner_map_object = NULL; + + if (!key || !msg_desciptor) + return -EINVAL; + + desc = (ProtobufCMessageDescriptor *)msg_desciptor; + if (desc->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + map_name = desc->short_name; + + ret = get_map_ids(map_name, &id, &outter_id, &inner_id); + if (ret) + return ret; + + ret = get_map_fd_info(id, &map_fd, &info); + if (ret < 0) { + LOG_ERR("invlid MAP_ID: %d\n", id); + return ret; + } + + if (!map_name) { + ret = bpf_map_delete_elem(map_fd, key); + goto end; + } + + ret = get_map_fd_info(inner_id, &inner_fd, &inner_info); + ret |= get_map_fd_info(outter_id, &outter_fd, &outter_info); + if (ret < 0 || map_info_check(&outter_info, &inner_info)) + goto end; + + init_op_context(context, key, NULL, desc, outter_fd, map_fd, &outter_info, &inner_info, &info); + + context.inner_map_object = calloc(1, context.inner_info->value_size); + context.value = calloc(1, context.curr_info->value_size); + if (!context.inner_map_object || !context.value) { + ret = -errno; + goto end; + } + + inner_map_object = context.inner_map_object; + + normalize_key(&context, key, map_name); + ret = del_bpf_map(&context, 0); end: - if (context.key != NULL) - free(context.key); - if (context.value != NULL) - free(context.value); - if (inner_map_object != NULL) - free(inner_map_object); - if (map_fd > 0) - close(map_fd); - if (outter_fd > 0) - close(outter_fd); - if (inner_fd > 0) - close(inner_fd); - return ret; + if (context.key != NULL) + free(context.key); + if (context.value != NULL) + free(context.value); + if (inner_map_object != NULL) + free(inner_map_object); + if (map_fd > 0) + close(map_fd); + if (outter_fd > 0) + close(outter_fd); + if (inner_fd > 0) + close(inner_fd); + return ret; } - -static void repeat_field_free(void *value, - const ProtobufCFieldDescriptor *field) +static void repeat_field_free(void *value, const ProtobufCFieldDescriptor *field) { - unsigned int i; - void *n = ((char*)value) + field->quantifier_offset; - uintptr_t *ptr_array = *(uintptr_t**)((char*)value + field->offset); - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - case PROTOBUF_C_TYPE_STRING: - for (i = 0; i < *(unsigned int*)n; i++) { - if (field->type == PROTOBUF_C_TYPE_STRING) - free_elem((void*)ptr_array[i]); - else - deserial_free_elem((void*)ptr_array[i]); - } - break; - default: - free_elem((void*)ptr_array); - break; - } - - return; + unsigned int i; + void *n = ((char *)value) + field->quantifier_offset; + uintptr_t *ptr_array = *(uintptr_t **)((char *)value + field->offset); + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + case PROTOBUF_C_TYPE_STRING: + for (i = 0; i < *(unsigned int *)n; i++) { + if (field->type == PROTOBUF_C_TYPE_STRING) + free_elem((void *)ptr_array[i]); + else + deserial_free_elem((void *)ptr_array[i]); + } + break; + default: + free_elem((void *)ptr_array); + break; + } + + return; } -static void field_free(void *value, - const ProtobufCFieldDescriptor *field) +static void field_free(void *value, const ProtobufCFieldDescriptor *field) { - uintptr_t *tobe_free = (uintptr_t *)((char*)value + field->offset); - - switch (field->type) { - case PROTOBUF_C_TYPE_MESSAGE: - deserial_free_elem((void*)(*tobe_free)); - break; - case PROTOBUF_C_TYPE_STRING: - free_elem((void*)*tobe_free); - break; - default: - break; - } - - return; + uintptr_t *tobe_free = (uintptr_t *)((char *)value + field->offset); + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: + deserial_free_elem((void *)(*tobe_free)); + break; + case PROTOBUF_C_TYPE_STRING: + free_elem((void *)*tobe_free); + break; + default: + break; + } + + return; } void deserial_free_elem(void *value) { - unsigned int i; - const char *map_name = NULL; - const ProtobufCMessageDescriptor *desc; - - if (!value || (uintptr_t)value < MAX_OUTTER_MAP_ENTRIES) - return; - - desc = ((ProtobufCMessage *)value)->descriptor; - if (desc && desc->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) - map_name = desc->short_name; - - if (!map_name) { - LOG_ERR("map_name is NULL"); - free_elem(value); - return; - } - - for (i = 0; i < desc->n_fields; i++) { - const ProtobufCFieldDescriptor *field = desc->fields + i; - - if (!selected_oneof_field(value, field) || - !valid_field_value(value, field)) - continue; - - switch (field->label) { - case PROTOBUF_C_LABEL_REPEATED: - repeat_field_free(value, field); - break; - default: - field_free(value, field); - break; - } - } - - free_elem(value); - return; + unsigned int i; + const char *map_name = NULL; + const ProtobufCMessageDescriptor *desc; + + if (!value || (uintptr_t)value < MAX_OUTTER_MAP_ENTRIES) + return; + + desc = ((ProtobufCMessage *)value)->descriptor; + if (desc && desc->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + map_name = desc->short_name; + + if (!map_name) { + LOG_ERR("map_name is NULL"); + free_elem(value); + return; + } + + for (i = 0; i < desc->n_fields; i++) { + const ProtobufCFieldDescriptor *field = desc->fields + i; + + if (!selected_oneof_field(value, field) || !valid_field_value(value, field)) + continue; + + switch (field->label) { + case PROTOBUF_C_LABEL_REPEATED: + repeat_field_free(value, field); + break; + default: + field_free(value, field); + break; + } + } + + free_elem(value); + return; } diff --git a/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.h b/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.h index 374c5dada..d1b2f4bf6 100644 --- a/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.h +++ b/bpf/deserialization_to_bpf_map/deserialization_to_bpf_map.h @@ -17,12 +17,11 @@ #ifndef __DESERIALIZATION_TO_BPF_MAP_H__ #define __DESERIALIZATION_TO_BPF_MAP_H__ -#define MAX_OUTTER_MAP_ENTRIES (10000) +#define MAX_OUTTER_MAP_ENTRIES (10000) int deserial_update_elem(void *key, void *value); -void* deserial_lookup_elem(void *key, const void *msg_desciptor); +void *deserial_lookup_elem(void *key, const void *msg_desciptor); void deserial_free_elem(void *value); int deserial_delete_elem(void *key, const void *msg_desciptor); - #endif /* __DESERIALIZATION_TO_BPF_MAP_H__ */ diff --git a/bpf/include/bpf_log.h b/bpf/include/bpf_log.h index b01b5ff34..34202c39c 100644 --- a/bpf/include/bpf_log.h +++ b/bpf/include/bpf_log.h @@ -22,30 +22,30 @@ #include "common.h" -#define BPF_DEBUG_ON 0 -#define BPF_DEBUG_OFF (-1) +#define BPF_DEBUG_ON 0 +#define BPF_DEBUG_OFF (-1) -#define BPF_LOG_LEVEL BPF_LOG_DEBUG +#define BPF_LOG_LEVEL BPF_LOG_DEBUG -#define BPF_LOGTYPE_SOCKMAP BPF_DEBUG_OFF -#define BPF_LOGTYPE_KMESH BPF_DEBUG_ON -#define BPF_LOGTYPE_SOCKOPS BPF_DEBUG_OFF -#define BPF_LOGTYPE_XDP BPF_DEBUG_OFF -#define BPF_LOGTYPE_SENDMSG BPF_DEBUG_OFF +#define BPF_LOGTYPE_SOCKMAP BPF_DEBUG_OFF +#define BPF_LOGTYPE_KMESH BPF_DEBUG_ON +#define BPF_LOGTYPE_SOCKOPS BPF_DEBUG_OFF +#define BPF_LOGTYPE_XDP BPF_DEBUG_OFF +#define BPF_LOGTYPE_SENDMSG BPF_DEBUG_OFF enum bpf_loglevel { - BPF_LOG_ERR = 0, - BPF_LOG_WARN, - BPF_LOG_INFO, - BPF_LOG_DEBUG, + BPF_LOG_ERR = 0, + BPF_LOG_WARN, + BPF_LOG_INFO, + BPF_LOG_DEBUG, }; -#define BPF_LOG(l, t, f, ...) \ - do { \ - int loglevel = BPF_MIN((int)BPF_LOG_LEVEL, ((int)BPF_LOG_DEBUG + (int)(BPF_LOGTYPE_ ## t))); \ - if ((int)(BPF_LOG_ ## l) <= loglevel) { \ - char fmt[] = "["# t"] " # l": " f""; \ - bpf_trace_printk(fmt, sizeof(fmt), ##__VA_ARGS__); \ - } \ - } while (0) +#define BPF_LOG(l, t, f, ...) \ + do { \ + int loglevel = BPF_MIN((int)BPF_LOG_LEVEL, ((int)BPF_LOG_DEBUG + (int)(BPF_LOGTYPE_##t))); \ + if ((int)(BPF_LOG_##l) <= loglevel) { \ + char fmt[] = "[" #t "] " #l ": " f ""; \ + bpf_trace_printk(fmt, sizeof(fmt), ##__VA_ARGS__); \ + } \ + } while (0) #endif // _BPF_LOG_H_ diff --git a/bpf/include/common.h b/bpf/include/common.h index 51099cc1d..1da865f70 100644 --- a/bpf/include/common.h +++ b/bpf/include/common.h @@ -36,36 +36,36 @@ #define bpf_unused __attribute__((__unused__)) -#define BPF_MAX(x, y) (((x) > (y)) ? (x) : (y)) -#define BPF_MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define BPF_MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define BPF_MIN(x, y) (((x) < (y)) ? (x) : (y)) #ifndef bpf_memset -#define bpf_memset(dest, chr, n) __builtin_memset((dest), (chr), (n)) +#define bpf_memset(dest, chr, n) __builtin_memset((dest), (chr), (n)) #endif #ifndef bpf_memcpy -#define bpf_memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) +#define bpf_memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) #endif #ifndef __stringify -#define __stringify(X) #X +#define __stringify(X) #X #endif -#define SEC_TAIL(ID, KEY) SEC(__stringify(ID) "/" __stringify(KEY)) +#define SEC_TAIL(ID, KEY) SEC(__stringify(ID) "/" __stringify(KEY)) static inline void *kmesh_map_lookup_elem(void *map, const void *key) { - return bpf_map_lookup_elem(map, key); + return bpf_map_lookup_elem(map, key); } static inline int kmesh_map_delete_elem(void *map, const void *key) { - return (int)bpf_map_delete_elem(map, key); + return (int)bpf_map_delete_elem(map, key); } static inline int kmesh_map_update_elem(void *map, const void *key, const void *value) { - // TODO: Duplicate element, status update - return (int)bpf_map_update_elem(map, key, value, BPF_ANY); + // TODO: Duplicate element, status update + return (int)bpf_map_update_elem(map, key, value, BPF_ANY); } #if OE_23_03 diff --git a/bpf/include/errno.h b/bpf/include/errno.h index 6922b74dd..15a2456b4 100644 --- a/bpf/include/errno.h +++ b/bpf/include/errno.h @@ -21,27 +21,27 @@ #define _ERRNO_H_ #ifndef ENOENT -#define ENOENT 2 /* No such file or directory */ +#define ENOENT 2 /* No such file or directory */ #endif #ifndef ENOEXEC -#define ENOEXEC 8 /* Exec format error */ +#define ENOEXEC 8 /* Exec format error */ #endif #ifndef EAGAIN -#define EAGAIN 11 /* Try again */ +#define EAGAIN 11 /* Try again */ #endif #ifndef EBUSY -#define EBUSY 16 /* Device or resource busy */ +#define EBUSY 16 /* Device or resource busy */ #endif #ifndef EINVAL -#define EINVAL 22 /* Invalid argument */ +#define EINVAL 22 /* Invalid argument */ #endif #ifndef ENOSPC -#define ENOSPC 28 /* No space left on device */ +#define ENOSPC 28 /* No space left on device */ #endif #endif // _ERRNO_H_ \ No newline at end of file diff --git a/bpf/kmesh/cgroup_sock.c b/bpf/kmesh/cgroup_sock.c index 071b4778e..84dd1e275 100644 --- a/bpf/kmesh/cgroup_sock.c +++ b/bpf/kmesh/cgroup_sock.c @@ -31,108 +31,106 @@ #if KMESH_ENABLE_HTTP struct { - __uint(type, BPF_MAP_TYPE_HASH); - __type(key, __u64); - __type(value, __u32); - __uint(max_entries, MAP_SIZE_OF_MANAGER); - __uint(map_flags, 0); + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, __u64); + __type(value, __u32); + __uint(max_entries, MAP_SIZE_OF_MANAGER); + __uint(map_flags, 0); } map_of_manager SEC(".maps"); static const char kmesh_module_name[] = "kmesh_defer"; static inline void record_netns_cookie(struct bpf_sock_addr *ctx) { - int err; - int value = 0; - __u64 cookie = bpf_get_netns_cookie(ctx); - err = bpf_map_update_elem(&map_of_manager, &cookie, &value, BPF_NOEXIST); - if (err) - BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); + int err; + int value = 0; + __u64 cookie = bpf_get_netns_cookie(ctx); + err = bpf_map_update_elem(&map_of_manager, &cookie, &value, BPF_NOEXIST); + if (err) + BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); } static inline void remove_netns_cookie(struct bpf_sock_addr *ctx) { - int err; - __u64 cookie = bpf_get_netns_cookie(ctx); - err = bpf_map_delete_elem(&map_of_manager, &cookie); - if (err && err != -ENOENT) - BPF_LOG(ERR, KMESH, "remove netcookie failed!, err is %d\n", err); + int err; + __u64 cookie = bpf_get_netns_cookie(ctx); + err = bpf_map_delete_elem(&map_of_manager, &cookie); + if (err && err != -ENOENT) + BPF_LOG(ERR, KMESH, "remove netcookie failed!, err is %d\n", err); } static inline bool check_kmesh_enabled(struct bpf_sock_addr *ctx) { - __u64 cookie = bpf_get_netns_cookie(ctx); - return bpf_map_lookup_elem(&map_of_manager, &cookie); + __u64 cookie = bpf_get_netns_cookie(ctx); + return bpf_map_lookup_elem(&map_of_manager, &cookie); } static inline int sock4_traffic_control(struct bpf_sock_addr *ctx) { - int ret; + int ret; - Listener__Listener *listener = NULL; + Listener__Listener *listener = NULL; - if (!check_kmesh_enabled(ctx)) - return 0; + if (!check_kmesh_enabled(ctx)) + return 0; - DECLARE_VAR_ADDRESS(ctx, address); + DECLARE_VAR_ADDRESS(ctx, address); - listener = map_lookup_listener(&address); - if (listener == NULL) { - address.ipv4 = 0; - listener = map_lookup_listener(&address); - if (!listener) - return -ENOENT; - } - BPF_LOG(DEBUG, KMESH, "bpf find listener addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); + listener = map_lookup_listener(&address); + if (listener == NULL) { + address.ipv4 = 0; + listener = map_lookup_listener(&address); + if (!listener) + return -ENOENT; + } + BPF_LOG(DEBUG, KMESH, "bpf find listener addr=[%u:%u]\n", ctx->user_ip4, 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); - if (ret != 0) { - BPF_LOG(ERR, KMESH, "listener_manager failed, ret %d\n", ret); - return ret; - } + // 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); + if (ret != 0) { + BPF_LOG(ERR, KMESH, "listener_manager failed, ret %d\n", ret); + return ret; + } #endif // KMESH_ENABLE_HTTP - return 0; + return 0; } static inline bool conn_from_cni_sim_add(struct bpf_sock_addr *ctx) { - // cni sim connect 0.0.0.0:929(0x3a1) - // 0x3a1 is the specific port handled by the cni for enable Kmesh - return ((bpf_ntohl(ctx->user_ip4) == 1) && - (bpf_ntohl(ctx->user_port) == 0x3a10000)); + // cni sim connect 0.0.0.0:929(0x3a1) + // 0x3a1 is the specific port handled by the cni for enable Kmesh + return ((bpf_ntohl(ctx->user_ip4) == 1) && (bpf_ntohl(ctx->user_port) == 0x3a10000)); } static inline bool conn_from_cni_sim_delete(struct bpf_sock_addr *ctx) { - // cni sim connect 0.0.0.1:930(0x3a2) - // 0x3a2 is the specific port handled by the cni for disable Kmesh - return ((bpf_ntohl(ctx->user_ip4) == 1) && - (bpf_ntohl(ctx->user_port) == 0x3a20000)); + // cni sim connect 0.0.0.1:930(0x3a2) + // 0x3a2 is the specific port handled by the cni for disable Kmesh + return ((bpf_ntohl(ctx->user_ip4) == 1) && (bpf_ntohl(ctx->user_port) == 0x3a20000)); } SEC("cgroup/connect4") int cgroup_connect4_prog(struct bpf_sock_addr *ctx) { - if (conn_from_cni_sim_add(ctx)) { - record_netns_cookie(ctx); - // return failed, cni sim connect 0.0.0.1:929(0x3a1) - // A normal program will not connect to this IP address - return CGROUP_SOCK_OK; - } - if (conn_from_cni_sim_delete(ctx)) { - remove_netns_cookie(ctx); - return CGROUP_SOCK_OK; - } - int ret = sock4_traffic_control(ctx); - return CGROUP_SOCK_OK; + if (conn_from_cni_sim_add(ctx)) { + record_netns_cookie(ctx); + // return failed, cni sim connect 0.0.0.1:929(0x3a1) + // A normal program will not connect to this IP address + return CGROUP_SOCK_OK; + } + if (conn_from_cni_sim_delete(ctx)) { + remove_netns_cookie(ctx); + return CGROUP_SOCK_OK; + } + int ret = sock4_traffic_control(ctx); + return CGROUP_SOCK_OK; } #endif // KMESH_ENABLE_TCP @@ -140,4 +138,3 @@ int cgroup_connect4_prog(struct bpf_sock_addr *ctx) 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 fa6f05ab5..c5712c372 100644 --- a/bpf/kmesh/include/cluster.h +++ b/bpf/kmesh/include/cluster.h @@ -12,9 +12,6 @@ * 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-14 */ #ifndef __KMESH_CLUSTER_H__ @@ -26,310 +23,308 @@ #include "cluster/cluster.pb-c.h" #include "endpoint/endpoint.pb-c.h" -#define CLUSTER_NAME_MAX_LEN BPF_DATA_MAX_LEN +#define CLUSTER_NAME_MAX_LEN BPF_DATA_MAX_LEN struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(key_size, CLUSTER_NAME_MAX_LEN); - __uint(value_size, sizeof(Cluster__Cluster)); - __uint(map_flags, BPF_F_NO_PREALLOC); - __uint(max_entries, MAP_SIZE_OF_CLUSTER); + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, CLUSTER_NAME_MAX_LEN); + __uint(value_size, sizeof(Cluster__Cluster)); + __uint(map_flags, BPF_F_NO_PREALLOC); + __uint(max_entries, MAP_SIZE_OF_CLUSTER); } map_of_cluster SEC(".maps"); struct cluster_endpoints { - __u32 ep_num; - /* */ - __u64 ep_identity[KMESH_PER_ENDPOINT_NUM]; - union { - /* ROUND_ROBIN */ - __u32 last_round_robin_idx; - /* LEAST_REQUEST */ - __u32 conn_num[KMESH_PER_ENDPOINT_NUM]; - }; + __u32 ep_num; + /* */ + __u64 ep_identity[KMESH_PER_ENDPOINT_NUM]; + union { + /* ROUND_ROBIN */ + __u32 last_round_robin_idx; + /* LEAST_REQUEST */ + __u32 conn_num[KMESH_PER_ENDPOINT_NUM]; + }; }; struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(key_size, CLUSTER_NAME_MAX_LEN); - __uint(value_size, sizeof(struct cluster_endpoints)); - __uint(max_entries, MAP_SIZE_OF_ENDPOINT); - __uint(map_flags, BPF_F_NO_PREALLOC); + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, CLUSTER_NAME_MAX_LEN); + __uint(value_size, sizeof(struct cluster_endpoints)); + __uint(max_entries, MAP_SIZE_OF_ENDPOINT); + __uint(map_flags, BPF_F_NO_PREALLOC); } map_of_cluster_eps SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __uint(key_size, sizeof(int)); - __uint(value_size, sizeof(struct cluster_endpoints)); - __uint(max_entries, 1); + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __uint(key_size, sizeof(int)); + __uint(value_size, sizeof(struct cluster_endpoints)); + __uint(max_entries, 1); } map_of_cluster_eps_data SEC(".maps"); static inline Cluster__Cluster *map_lookup_cluster_eps_data() { - int location = 0; - return kmesh_map_lookup_elem(&map_of_cluster_eps_data, &location); + int location = 0; + return kmesh_map_lookup_elem(&map_of_cluster_eps_data, &location); } static inline Cluster__Cluster *map_lookup_cluster(const char *cluster_name) { - return kmesh_map_lookup_elem(&map_of_cluster, cluster_name); + return kmesh_map_lookup_elem(&map_of_cluster, cluster_name); } static inline struct cluster_endpoints *map_lookup_cluster_eps(const char *cluster_name) { - return kmesh_map_lookup_elem(&map_of_cluster_eps, cluster_name); + return kmesh_map_lookup_elem(&map_of_cluster_eps, cluster_name); } static inline int map_add_cluster_eps(const char *cluster_name, const struct cluster_endpoints *eps) { - return kmesh_map_update_elem(&map_of_cluster_eps, cluster_name, eps); + return kmesh_map_update_elem(&map_of_cluster_eps, cluster_name, eps); } -static inline int cluster_add_endpoints(const Endpoint__LocalityLbEndpoints *lb_ep, - struct cluster_endpoints *cluster_eps) +static inline int +cluster_add_endpoints(const Endpoint__LocalityLbEndpoints *lb_ep, struct cluster_endpoints *cluster_eps) { - __u32 i; - void *ep_ptrs = NULL; - - ep_ptrs = kmesh_get_ptr_val(lb_ep->lb_endpoints); - if (!ep_ptrs) - return -1; - - #pragma unroll - for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { - if (i >= lb_ep->n_lb_endpoints || cluster_eps->ep_num >= KMESH_PER_ENDPOINT_NUM) - break; - - /* store ep identity */ - cluster_eps->ep_identity[cluster_eps->ep_num++] = (__u64)*((__u64*)ep_ptrs + i); - } - return 0; + __u32 i; + void *ep_ptrs = NULL; + + ep_ptrs = kmesh_get_ptr_val(lb_ep->lb_endpoints); + if (!ep_ptrs) + return -1; + +#pragma unroll + for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { + if (i >= lb_ep->n_lb_endpoints || cluster_eps->ep_num >= KMESH_PER_ENDPOINT_NUM) + break; + + /* store ep identity */ + cluster_eps->ep_identity[cluster_eps->ep_num++] = (__u64) * ((__u64 *)ep_ptrs + i); + } + return 0; } static inline __u32 cluster_get_endpoints_num(const Endpoint__ClusterLoadAssignment *cla) { - __u32 i; - __u32 num = 0; - void *ptrs = NULL; - Endpoint__LocalityLbEndpoints *lb_ep = NULL; - - ptrs = kmesh_get_ptr_val(cla->endpoints); - if (!ptrs) - return 0; - - #pragma unroll - for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { - if (i >= cla->n_endpoints) { - break; - } - - lb_ep = (Endpoint__LocalityLbEndpoints *)kmesh_get_ptr_val((void*)*((__u64*)ptrs + i)); - if (!lb_ep) - continue; - - num += (__u32)lb_ep->n_lb_endpoints; - } - return num; + __u32 i; + __u32 num = 0; + void *ptrs = NULL; + Endpoint__LocalityLbEndpoints *lb_ep = NULL; + + ptrs = kmesh_get_ptr_val(cla->endpoints); + if (!ptrs) + return 0; + +#pragma unroll + for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { + if (i >= cla->n_endpoints) { + break; + } + + lb_ep = (Endpoint__LocalityLbEndpoints *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!lb_ep) + continue; + + num += (__u32)lb_ep->n_lb_endpoints; + } + return num; } -static inline int cluster_init_endpoints(const char *cluster_name, - const Endpoint__ClusterLoadAssignment *cla) +static inline int cluster_init_endpoints(const char *cluster_name, const Endpoint__ClusterLoadAssignment *cla) { - __u32 i; - int ret = 0; - void *ptrs = NULL; - Endpoint__LocalityLbEndpoints *ep = NULL; - /* A percpu array map is added to store cluster eps data. - * The reason for using percpu array map is that a alarge value exceeds - * the 512 bytes limit of the stack in ebpf. - */ - struct cluster_endpoints *cluster_eps = map_lookup_cluster_eps_data(); - - if (!cluster_eps) { - BPF_LOG(ERR, CLUSTER, "failed to get percpu cluster eps data\n"); - return -1; - } - cluster_eps->ep_num = 0; - - ptrs = kmesh_get_ptr_val(cla->endpoints); - if (!ptrs) { - BPF_LOG(ERR, CLUSTER, "failed to get cla endpoints ptrs\n"); - return -1; - } - - #pragma unroll - for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { - if (i >= cla->n_endpoints) - break; - - ep = (Endpoint__LocalityLbEndpoints *)kmesh_get_ptr_val((void*)*((__u64*)ptrs + i)); - if (!ep) - continue; - - ret = cluster_add_endpoints(ep, cluster_eps); - if (ret != 0) - return -1; - } - - return map_add_cluster_eps(cluster_name, cluster_eps); + __u32 i; + int ret = 0; + void *ptrs = NULL; + Endpoint__LocalityLbEndpoints *ep = NULL; + /* A percpu array map is added to store cluster eps data. + * The reason for using percpu array map is that a alarge value exceeds + * the 512 bytes limit of the stack in ebpf. + */ + struct cluster_endpoints *cluster_eps = map_lookup_cluster_eps_data(); + + if (!cluster_eps) { + BPF_LOG(ERR, CLUSTER, "failed to get percpu cluster eps data\n"); + return -1; + } + cluster_eps->ep_num = 0; + + ptrs = kmesh_get_ptr_val(cla->endpoints); + if (!ptrs) { + BPF_LOG(ERR, CLUSTER, "failed to get cla endpoints ptrs\n"); + return -1; + } + +#pragma unroll + for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { + if (i >= cla->n_endpoints) + break; + + ep = (Endpoint__LocalityLbEndpoints *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!ep) + continue; + + ret = cluster_add_endpoints(ep, cluster_eps); + if (ret != 0) + return -1; + } + + return map_add_cluster_eps(cluster_name, cluster_eps); } -static inline int cluster_check_endpoints(const struct cluster_endpoints *eps, - const Endpoint__ClusterLoadAssignment *cla) +static inline int +cluster_check_endpoints(const struct cluster_endpoints *eps, const Endpoint__ClusterLoadAssignment *cla) { - /* 0 -- failed 1 -- succeed */ - __u32 i; - void *ptrs = NULL; - __u32 lb_num = cluster_get_endpoints_num(cla); - - if (!eps || eps->ep_num != lb_num) - return 0; - - ptrs = kmesh_get_ptr_val(cla->endpoints); - if (!ptrs) - return 0; - - #pragma unroll - for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { - if (i >= lb_num) { - break; - } - - if (eps->ep_identity[i] != (__u64)_(ptrs + i)) - return 0; - } - return 1; + /* 0 -- failed 1 -- succeed */ + __u32 i; + void *ptrs = NULL; + __u32 lb_num = cluster_get_endpoints_num(cla); + + if (!eps || eps->ep_num != lb_num) + return 0; + + ptrs = kmesh_get_ptr_val(cla->endpoints); + if (!ptrs) + return 0; + +#pragma unroll + for (i = 0; i < KMESH_PER_ENDPOINT_NUM; i++) { + if (i >= lb_num) { + break; + } + + if (eps->ep_identity[i] != (__u64)_(ptrs + i)) + return 0; + } + return 1; } static inline struct cluster_endpoints *cluster_refresh_endpoints(const Cluster__Cluster *cluster, const char *name) { - struct cluster_endpoints *eps = NULL; - Endpoint__ClusterLoadAssignment *cla = NULL; - - cla = kmesh_get_ptr_val(cluster->load_assignment); - if (!cla) { - BPF_LOG(ERR, CLUSTER, "get load_assignment failed\n"); - return NULL; - } - - // FIXME: if control-plane delete or update, clear - // FIXME: if cluster_init_endpoints failed, clear - // FIXME: if cluster_check_endpoints failed, clear - eps = map_lookup_cluster_eps(name); - if (eps) // TODO: && cluster_check_endpoints(eps, cla) != 0) - return eps; - - if (cluster_init_endpoints(name, cla) != 0) - return NULL; - return map_lookup_cluster_eps(name); + struct cluster_endpoints *eps = NULL; + Endpoint__ClusterLoadAssignment *cla = NULL; + + cla = kmesh_get_ptr_val(cluster->load_assignment); + if (!cla) { + BPF_LOG(ERR, CLUSTER, "get load_assignment failed\n"); + return NULL; + } + + // FIXME: if control-plane delete or update, clear + // FIXME: if cluster_init_endpoints failed, clear + // FIXME: if cluster_check_endpoints failed, clear + eps = map_lookup_cluster_eps(name); + if (eps) // TODO: && cluster_check_endpoints(eps, cla) != 0) + return eps; + + if (cluster_init_endpoints(name, cla) != 0) + 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; + 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; + __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]; + __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; + 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; + 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; + 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; + int ret = 0; + ctx_key_t ctx_key = {0}; + ctx_val_t *ctx_val = NULL; + Cluster__Cluster *cluster = NULL; - DECLARE_VAR_ADDRESS(ctx, addr); + DECLARE_VAR_ADDRESS(ctx, addr); - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_CLUSTER, addr); - ctx_val = kmesh_tail_lookup_ctx(&ctx_key); - if (ctx_val == NULL) - return KMESH_TAIL_CALL_RET(ENOENT); + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_CLUSTER, addr); + ctx_val = kmesh_tail_lookup_ctx(&ctx_key); + if (ctx_val == NULL) + return KMESH_TAIL_CALL_RET(ENOENT); - cluster = map_lookup_cluster(ctx_val->data); - kmesh_tail_delete_ctx(&ctx_key); - if (cluster == NULL) - return KMESH_TAIL_CALL_RET(ENOENT); + cluster = map_lookup_cluster(ctx_val->data); + kmesh_tail_delete_ctx(&ctx_key); + if (cluster == NULL) + return KMESH_TAIL_CALL_RET(ENOENT); - ret = cluster_handle_loadbalance(cluster, &addr, ctx); - return KMESH_TAIL_CALL_RET(ret); + ret = cluster_handle_loadbalance(cluster, &addr, ctx); + return KMESH_TAIL_CALL_RET(ret); } #endif diff --git a/bpf/kmesh/include/config.h b/bpf/kmesh/include/config.h index 4faf4a34c..f7630a5c7 100644 --- a/bpf/kmesh/include/config.h +++ b/bpf/kmesh/include/config.h @@ -22,74 +22,65 @@ // ************ // options -#define KMESH_MODULE_ON 1 -#define KMESH_MODULE_OFF 0 +#define KMESH_MODULE_ON 1 +#define KMESH_MODULE_OFF 0 // L3 -#define KMESH_ENABLE_IPV4 KMESH_MODULE_ON -#define KMESH_ENABLE_IPV6 KMESH_MODULE_OFF +#define KMESH_ENABLE_IPV4 KMESH_MODULE_ON +#define KMESH_ENABLE_IPV6 KMESH_MODULE_OFF // L4 -#define KMESH_ENABLE_TCP KMESH_MODULE_ON -#define KMESH_ENABLE_UDP KMESH_MODULE_OFF +#define KMESH_ENABLE_TCP KMESH_MODULE_ON +#define KMESH_ENABLE_UDP KMESH_MODULE_OFF // L7 -#define KMESH_ENABLE_HTTP KMESH_MODULE_ON -#define KMESH_ENABLE_HTTPS KMESH_MODULE_OFF - +#define KMESH_ENABLE_HTTP KMESH_MODULE_ON +#define KMESH_ENABLE_HTTPS KMESH_MODULE_OFF // ************ // map size -#define MAP_SIZE_OF_PER_LISTENER 64 -#define MAP_SIZE_OF_PER_FILTER_CHAIN 4 -#define MAP_SIZE_OF_PER_FILTER 4 -#define MAP_SIZE_OF_PER_VIRTUAL_HOST 16 -#define MAP_SIZE_OF_PER_ROUTE 8 -#define MAP_SIZE_OF_PER_CLUSTER 32 -#define MAP_SIZE_OF_PER_ENDPOINT 64 -#define MAP_SIZE_OF_MANAGER 8192 +#define MAP_SIZE_OF_PER_LISTENER 64 +#define MAP_SIZE_OF_PER_FILTER_CHAIN 4 +#define MAP_SIZE_OF_PER_FILTER 4 +#define MAP_SIZE_OF_PER_VIRTUAL_HOST 16 +#define MAP_SIZE_OF_PER_ROUTE 8 +#define MAP_SIZE_OF_PER_CLUSTER 32 +#define MAP_SIZE_OF_PER_ENDPOINT 64 +#define MAP_SIZE_OF_MANAGER 8192 -#define MAP_SIZE_OF_MAX 8192 +#define MAP_SIZE_OF_MAX 8192 -#define MAP_SIZE_OF_LISTENER \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_LISTENER) -#define MAP_SIZE_OF_FILTER_CHAIN \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_FILTER_CHAIN * MAP_SIZE_OF_LISTENER) -#define MAP_SIZE_OF_FILTER \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_FILTER * MAP_SIZE_OF_FILTER_CHAIN) -#define MAP_SIZE_OF_VIRTUAL_HOST \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_VIRTUAL_HOST * MAP_SIZE_OF_FILTER) -#define MAP_SIZE_OF_ROUTE \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_ROUTE * MAP_SIZE_OF_VIRTUAL_HOST) -#define MAP_SIZE_OF_CLUSTER \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_CLUSTER * MAP_SIZE_OF_ROUTE) -#define MAP_SIZE_OF_ENDPOINT \ - BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_ENDPOINT * MAP_SIZE_OF_CLUSTER) +#define MAP_SIZE_OF_LISTENER BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_LISTENER) +#define MAP_SIZE_OF_FILTER_CHAIN BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_FILTER_CHAIN *MAP_SIZE_OF_LISTENER) +#define MAP_SIZE_OF_FILTER BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_FILTER *MAP_SIZE_OF_FILTER_CHAIN) +#define MAP_SIZE_OF_VIRTUAL_HOST BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_VIRTUAL_HOST *MAP_SIZE_OF_FILTER) +#define MAP_SIZE_OF_ROUTE BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_ROUTE *MAP_SIZE_OF_VIRTUAL_HOST) +#define MAP_SIZE_OF_CLUSTER BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_CLUSTER *MAP_SIZE_OF_ROUTE) +#define MAP_SIZE_OF_ENDPOINT BPF_MIN(MAP_SIZE_OF_MAX, MAP_SIZE_OF_PER_ENDPOINT *MAP_SIZE_OF_CLUSTER) // rename map to avoid truncation when name length exceeds BPF_OBJ_NAME_LEN = 16 -#define map_of_listener kmesh_listener -#define map_of_filter_chain kmesh_filter_chain -#define map_of_filter kmesh_filter -#define map_of_virtual_host kmesh_virtual_host -#define map_of_route kmesh_route -#define map_of_cluster kmesh_cluster -#define map_of_loadbalance kmesh_loadbalance -#define map_of_endpoint kmesh_endpoint -#define map_of_tail_call_prog kmesh_tail_call_prog -#define map_of_tail_call_ctx kmesh_tail_call_ctx - +#define map_of_listener kmesh_listener +#define map_of_filter_chain kmesh_filter_chain +#define map_of_filter kmesh_filter +#define map_of_virtual_host kmesh_virtual_host +#define map_of_route kmesh_route +#define map_of_cluster kmesh_cluster +#define map_of_loadbalance kmesh_loadbalance +#define map_of_endpoint kmesh_endpoint +#define map_of_tail_call_prog kmesh_tail_call_prog +#define map_of_tail_call_ctx kmesh_tail_call_ctx // ************ // array len -#define KMESH_NAME_LEN 64 -#define KMESH_TYPE_LEN 64 -#define KMESH_HOST_LEN 128 -#define KMESH_FILTER_CHAINS_LEN 64 -#define KMESH_HTTP_DOMAIN_NUM 32 -#define KMESH_HTTP_DOMAIN_LEN 128 -#define KMESH_PER_FILTER_CHAIN_NUM MAP_SIZE_OF_PER_FILTER_CHAIN -#define KMESH_PER_FILTER_NUM MAP_SIZE_OF_PER_FILTER -#define KMESH_PER_VIRT_HOST_NUM MAP_SIZE_OF_PER_VIRTUAL_HOST -#define KMESH_PER_ROUTE_NUM MAP_SIZE_OF_PER_ROUTE -#define KMESH_PER_ENDPOINT_NUM MAP_SIZE_OF_PER_ENDPOINT -#define KMESH_PER_HEADER_MUM 32 +#define KMESH_NAME_LEN 64 +#define KMESH_TYPE_LEN 64 +#define KMESH_HOST_LEN 128 +#define KMESH_FILTER_CHAINS_LEN 64 +#define KMESH_HTTP_DOMAIN_NUM 32 +#define KMESH_HTTP_DOMAIN_LEN 128 +#define KMESH_PER_FILTER_CHAIN_NUM MAP_SIZE_OF_PER_FILTER_CHAIN +#define KMESH_PER_FILTER_NUM MAP_SIZE_OF_PER_FILTER +#define KMESH_PER_VIRT_HOST_NUM MAP_SIZE_OF_PER_VIRTUAL_HOST +#define KMESH_PER_ROUTE_NUM MAP_SIZE_OF_PER_ROUTE +#define KMESH_PER_ENDPOINT_NUM MAP_SIZE_OF_PER_ENDPOINT +#define KMESH_PER_HEADER_MUM 32 #define KMESH_PER_WEIGHT_CLUSTER_NUM 32 #endif // _CONFIG_H_ diff --git a/bpf/kmesh/include/ctx/sock_addr.h b/bpf/kmesh/include/ctx/sock_addr.h index 7fbba9e29..8f90d779b 100644 --- a/bpf/kmesh/include/ctx/sock_addr.h +++ b/bpf/kmesh/include/ctx/sock_addr.h @@ -1,39 +1,37 @@ -/* - * Copyright 2023 The Kmesh Authors. - * - * 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 +/* + * Copyright 2023 The Kmesh Authors. + * + * 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. + */ + +#ifndef __BPF_CTX_SOCK_ADDR_H +#define __BPF_CTX_SOCK_ADDR_H + +typedef struct bpf_sock_addr ctx_buff_t; + +// clang-format off +#define KMESH_PORG_CALLS cgroup/connect4 +// clang-format on + +#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 index 2a3d8279c..b52b96e92 100644 --- a/bpf/kmesh/include/ctx/sock_ops.h +++ b/bpf/kmesh/include/ctx/sock_ops.h @@ -22,23 +22,23 @@ #include "kmesh_common.h" -typedef struct bpf_sock_ops ctx_buff_t; +typedef struct bpf_sock_ops ctx_buff_t; -#define KMESH_PORG_CALLS sockops +#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)->replylong[2] = (address)->ipv4; \ - (ctx)->replylong[3] = (address)->port +#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)->replylong[2] = (address)->ipv4; \ + (ctx)->replylong[3] = (address)->port #if OE_23_03 #undef SET_CTX_ADDRESS -#define SET_CTX_ADDRESS(ctx, address) \ - (ctx)->remote_ip4 = (address)->ipv4; \ - (ctx)->remote_port = (address)->port +#define SET_CTX_ADDRESS(ctx, address) \ + (ctx)->remote_ip4 = (address)->ipv4; \ + (ctx)->remote_port = (address)->port #endif #endif //__BPF_CTX_SOCK_OPS_H diff --git a/bpf/kmesh/include/filter.h b/bpf/kmesh/include/filter.h index a2893aac1..895723bac 100644 --- a/bpf/kmesh/include/filter.h +++ b/bpf/kmesh/include/filter.h @@ -27,192 +27,190 @@ #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) { - int match = 0; - switch (filter->config_type_case) { - case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER: - match = 1; - break; - case LISTENER__FILTER__CONFIG_TYPE_TCP_PROXY: - match = 1; - break; - default: - break; - } - return match; + int match = 0; + switch (filter->config_type_case) { + case LISTENER__FILTER__CONFIG_TYPE_HTTP_CONNECTION_MANAGER: + match = 1; + break; + case LISTENER__FILTER__CONFIG_TYPE_TCP_PROXY: + match = 1; + break; + default: + break; + } + return match; } -static inline int filter_chain_filter_match(const Listener__FilterChain *filter_chain, - const address_t *addr, - const ctx_buff_t *ctx, - Listener__Filter **filter_ptr, - __u64 *filter_ptr_idx) +static inline int filter_chain_filter_match( + const Listener__FilterChain *filter_chain, + const address_t *addr, + const ctx_buff_t *ctx, + Listener__Filter **filter_ptr, + __u64 *filter_ptr_idx) { - void *ptrs = NULL; - Listener__Filter *filter = NULL; - - if (!filter_ptr || !filter_ptr_idx) { - BPF_LOG(ERR, FILTERCHAIN, "invalid params\n"); - return -1; - } - - if (filter_chain->n_filters == 0 || filter_chain->n_filters > KMESH_PER_FILTER_NUM) { - BPF_LOG(ERR, FILTERCHAIN, "nfilter num(%d) invalid\n", filter_chain->n_filters); - return -1; - } - - /* filter match */ - ptrs = kmesh_get_ptr_val(filter_chain->filters); - if (!ptrs) { - BPF_LOG(ERR, FILTER, "failed to get filter ptrs\n"); - return -1; - } - - /* limit loop cap to pass bpf verify */ - #pragma unroll - for (unsigned int i = 0; i < KMESH_PER_FILTER_NUM; i++) { - if (i >= filter_chain->n_filters) { - break; - } - - filter = (Listener__Filter *)kmesh_get_ptr_val((void*)*((__u64*)ptrs + i)); - if (!filter) { - continue; - } - - // FIXME: repeat on filter_manager - if (filter_match_check(filter, addr, ctx)) { - *filter_ptr = filter; - *filter_ptr_idx = (__u64)*((__u64 *)ptrs + i); - return 0; - } - } - return -1; + void *ptrs = NULL; + Listener__Filter *filter = NULL; + + if (!filter_ptr || !filter_ptr_idx) { + BPF_LOG(ERR, FILTERCHAIN, "invalid params\n"); + return -1; + } + + if (filter_chain->n_filters == 0 || filter_chain->n_filters > KMESH_PER_FILTER_NUM) { + BPF_LOG(ERR, FILTERCHAIN, "nfilter num(%d) invalid\n", filter_chain->n_filters); + return -1; + } + + /* filter match */ + ptrs = kmesh_get_ptr_val(filter_chain->filters); + if (!ptrs) { + BPF_LOG(ERR, FILTER, "failed to get filter ptrs\n"); + return -1; + } + +/* limit loop cap to pass bpf verify */ +#pragma unroll + for (unsigned int i = 0; i < KMESH_PER_FILTER_NUM; i++) { + if (i >= filter_chain->n_filters) { + break; + } + + filter = (Listener__Filter *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!filter) { + continue; + } + + // FIXME: repeat on filter_manager + if (filter_match_check(filter, addr, ctx)) { + *filter_ptr = filter; + *filter_ptr_idx = (__u64) * ((__u64 *)ptrs + i); + return 0; + } + } + 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) + 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; - } - - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_ROUTER_CONFIG, *addr); - KMESH_TAIL_CALL_CTX_VALSTR(ctx_val, msg, route_name); - - KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_ROUTER_CONFIG, ctx_key, ctx_val); - return KMESH_TAIL_CALL_RET(ret); + 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; + } + + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_ROUTER_CONFIG, *addr); + KMESH_TAIL_CALL_CTX_VALSTR(ctx_val, msg, route_name); + + KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_ROUTER_CONFIG, ctx_key, ctx_val); + return KMESH_TAIL_CALL_RET(ret); } 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); - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER, addr); - ctx_val = kmesh_tail_lookup_ctx(&ctx_key); - if (!ctx_val) { - BPF_LOG(ERR, FILTER, "failed to lookup tail call val\n"); - return KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_RET(-1); - } - kmesh_tail_delete_ctx(&ctx_key); - - switch (filter->config_type_case) { + 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); + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER, addr); + ctx_val = kmesh_tail_lookup_ctx(&ctx_key); + if (!ctx_val) { + BPF_LOG(ERR, FILTER, "failed to lookup tail call val\n"); + return KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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"); - break; - } - - 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_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"); + break; + } + + 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 KMESH_TAIL_CALL_RET(ret); + 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 KMESH_TAIL_CALL_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); - - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER_CHAIN, addr); - ctx_val_ptr = kmesh_tail_lookup_ctx(&ctx_key); - if (!ctx_val_ptr) { - BPF_LOG(ERR, FILTERCHAIN, "failed to lookup tail ctx\n"); - return KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_RET(-1); - } - - // FIXME: when filter_manager unsuccessful, - // we should skip back and handle next filter, rather than exit. - - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER, addr); - KMESH_TAIL_CALL_CTX_VAL(ctx_val, ctx_val_ptr->msg, filter_idx); - - KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_FILTER, ctx_key, ctx_val); - return KMESH_TAIL_CALL_RET(ret); + 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); + + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER_CHAIN, addr); + ctx_val_ptr = kmesh_tail_lookup_ctx(&ctx_key); + if (!ctx_val_ptr) { + BPF_LOG(ERR, FILTERCHAIN, "failed to lookup tail ctx\n"); + return KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_RET(-1); + } + + // FIXME: when filter_manager unsuccessful, + // we should skip back and handle next filter, rather than exit. + + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER, addr); + KMESH_TAIL_CALL_CTX_VAL(ctx_val, ctx_val_ptr->msg, filter_idx); + + KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_FILTER, ctx_key, ctx_val); + return KMESH_TAIL_CALL_RET(ret); } - #endif diff --git a/bpf/kmesh/include/kmesh_common.h b/bpf/kmesh/include/kmesh_common.h index 43d51842d..3c94a1c5c 100644 --- a/bpf/kmesh/include/kmesh_common.h +++ b/bpf/kmesh/include/kmesh_common.h @@ -25,145 +25,138 @@ #include "config.h" #include "core/address.pb-c.h" - -#define BPF_LOGTYPE_LISTENER BPF_DEBUG_OFF -#define BPF_LOGTYPE_FILTERCHAIN BPF_DEBUG_OFF -#define BPF_LOGTYPE_FILTER BPF_DEBUG_OFF -#define BPF_LOGTYPE_CLUSTER BPF_DEBUG_OFF -#define BPF_LOGTYPE_SOCKOPS BPF_DEBUG_OFF -#define BPF_LOGTYPE_ROUTER BPF_DEBUG_OFF -#define BPF_LOGTYPE_ROUTER_CONFIG BPF_DEBUG_OFF -#define BPF_LOGTYPE_COMMON BPF_DEBUG_OFF - -#define KMESH_CLASSID_MARK 0x1000 - -#define BPF_DATA_MAX_LEN 192 /* this value should be - small that make compile success */ -#define BPF_INNER_MAP_DATA_LEN 1300 - -#define BPF_OK 1 - -#define _(P) \ - ({ \ - typeof(P) val; \ - bpf_probe_read_kernel(&val, sizeof(val), &P); \ - val; \ - }) +#define BPF_LOGTYPE_LISTENER BPF_DEBUG_OFF +#define BPF_LOGTYPE_FILTERCHAIN BPF_DEBUG_OFF +#define BPF_LOGTYPE_FILTER BPF_DEBUG_OFF +#define BPF_LOGTYPE_CLUSTER BPF_DEBUG_OFF +#define BPF_LOGTYPE_SOCKOPS BPF_DEBUG_OFF +#define BPF_LOGTYPE_ROUTER BPF_DEBUG_OFF +#define BPF_LOGTYPE_ROUTER_CONFIG BPF_DEBUG_OFF +#define BPF_LOGTYPE_COMMON BPF_DEBUG_OFF + +#define KMESH_CLASSID_MARK 0x1000 + +#define BPF_DATA_MAX_LEN \ + 192 /* this value should be \ +small that make compile success */ +#define BPF_INNER_MAP_DATA_LEN 1300 + +#define BPF_OK 1 + +#define _(P) \ + ({ \ + typeof(P) val; \ + bpf_probe_read_kernel(&val, sizeof(val), &P); \ + val; \ + }) struct bpf_mem_ptr { - void *ptr; - __u32 size; + void *ptr; + __u32 size; }; #if !ENHANCED_KERNEL -static inline int bpf__strncmp (char *dst, int n, const char *src) { - if (dst == NULL || src == NULL) - return -1; - - #pragma unroll - for (int i = 0; i < BPF_DATA_MAX_LEN; i++) { - if (dst[i] != src[i]) - return dst[i] - src[i]; - else if (dst[i] == '\0' || i == n - 1) - return 0; - } - return 0; +static inline int bpf__strncmp(char *dst, int n, const char *src) +{ + if (dst == NULL || src == NULL) + return -1; + +#pragma unroll + for (int i = 0; i < BPF_DATA_MAX_LEN; i++) { + if (dst[i] != src[i]) + return dst[i] - src[i]; + else if (dst[i] == '\0' || i == n - 1) + return 0; + } + return 0; }; -static inline char *bpf_strncpy(char *dst, int n, const char *src) { - int isEnd = 0; - if (src == NULL) - return 0; - - #pragma unroll - for (int i = 0; i < BPF_DATA_MAX_LEN; i++) { - if (src[i] == '\0') - isEnd = 1; - if (isEnd == 1) - dst[i] = '\0'; - else - dst[i] = src[i]; - if (i == n - 1) - break; - } - return dst; +static inline char *bpf_strncpy(char *dst, int n, const char *src) +{ + int isEnd = 0; + if (src == NULL) + return 0; + +#pragma unroll + for (int i = 0; i < BPF_DATA_MAX_LEN; i++) { + if (src[i] == '\0') + isEnd = 1; + if (isEnd == 1) + dst[i] = '\0'; + else + dst[i] = src[i]; + if (i == n - 1) + break; + } + return dst; } #endif struct { - __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); - __uint(key_size, sizeof(__u32)); - __uint(value_size, sizeof(__u32)); - __uint(max_entries, MAP_SIZE_OF_MAX); - __uint(map_flags, 0); + __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u32)); + __uint(max_entries, MAP_SIZE_OF_MAX); + __uint(map_flags, 0); } outer_map SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __uint(key_size, sizeof(__u32)); - __uint(value_size, BPF_INNER_MAP_DATA_LEN); - __uint(max_entries, 1); - __uint(map_flags, 0); + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(key_size, sizeof(__u32)); + __uint(value_size, BPF_INNER_MAP_DATA_LEN); + __uint(max_entries, 1); + __uint(map_flags, 0); } inner_map SEC(".maps"); 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_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; // bpf return value -#define CGROUP_SOCK_ERR 0 -#define CGROUP_SOCK_OK 1 +#define CGROUP_SOCK_ERR 0 +#define CGROUP_SOCK_OK 1 -enum kmesh_l7_proto_type { - PROTO_UNKNOW = 0, - PROTO_HTTP_1_1, - PROTO_HTTP_2_0 -}; +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_l7_msg_type { MSG_UNKNOW = 0, MSG_REQUEST, MSG_MID_REPONSE, MSG_FINAL_RESPONSE }; #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) +#define GET_RET_PROTO_TYPE(n) ((n)&0xff) +#define GET_RET_MSG_TYPE(n) (((n) >> KMESH_PROTO_TYPE_WIDTH) & 0xff) static inline void *kmesh_get_ptr_val(const void *ptr) { - /* - map_in_map -- outer_map: - key value - idx1 inner_map_fd1 // point to inner map1 - idx2 inner_map_fd2 // point to inner map2 - - structA.ptr_member1 = idx1; // store idx in outer_map - */ - void *inner_map_instance = NULL; - __u32 inner_idx = 0; - __u64 idx = (__u64)ptr; - - BPF_LOG(DEBUG, COMMON, "kmesh_get_ptr_val idx=%u\n", idx); - if (!ptr) { - return NULL; - } - - /* get inner_map_instance by idx */ - inner_map_instance = kmesh_map_lookup_elem(&outer_map, &idx); - if (!inner_map_instance) { - return NULL; - } - - /* get inner_map_instance value */ - return kmesh_map_lookup_elem(inner_map_instance, &inner_idx); + /* + map_in_map -- outer_map: + key value + idx1 inner_map_fd1 // point to inner map1 + idx2 inner_map_fd2 // point to inner map2 + + structA.ptr_member1 = idx1; // store idx in outer_map + */ + void *inner_map_instance = NULL; + __u32 inner_idx = 0; + __u64 idx = (__u64)ptr; + + BPF_LOG(DEBUG, COMMON, "kmesh_get_ptr_val idx=%u\n", idx); + if (!ptr) { + return NULL; + } + + /* get inner_map_instance by idx */ + inner_map_instance = kmesh_map_lookup_elem(&outer_map, &idx); + if (!inner_map_instance) { + return NULL; + } + + /* get inner_map_instance value */ + return kmesh_map_lookup_elem(inner_map_instance, &inner_idx); } #endif // _KMESH_COMMON_H_ diff --git a/bpf/kmesh/include/listener.h b/bpf/kmesh/include/listener.h index fd61b5158..e2bfc1c83 100644 --- a/bpf/kmesh/include/listener.h +++ b/bpf/kmesh/include/listener.h @@ -24,112 +24,109 @@ #include "listener/listener.pb-c.h" struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(key_size, sizeof(address_t)); - __uint(value_size, sizeof(Listener__Listener)); - __uint(max_entries, MAP_SIZE_OF_LISTENER); - __uint(map_flags, BPF_F_NO_PREALLOC); + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, sizeof(address_t)); + __uint(value_size, sizeof(Listener__Listener)); + __uint(max_entries, MAP_SIZE_OF_LISTENER); + __uint(map_flags, BPF_F_NO_PREALLOC); } map_of_listener SEC(".maps"); static inline Listener__Listener *map_lookup_listener(const address_t *addr) { - return kmesh_map_lookup_elem(&map_of_listener, addr); + return kmesh_map_lookup_elem(&map_of_listener, addr); } -static inline bool listener_filter_chain_match_check(const Listener__FilterChain *filter_chain, - const address_t *addr, - const ctx_buff_t *ctx) +static inline bool listener_filter_chain_match_check( + const Listener__FilterChain *filter_chain, const address_t *addr, const ctx_buff_t *ctx) { - char *transport_protocol; - const char buf[] = "raw_buffer"; - - Listener__FilterChainMatch *filter_chain_match = - kmesh_get_ptr_val(filter_chain->filter_chain_match); - if (!filter_chain_match) - return false; - - if (filter_chain_match->destination_port != 0 && - filter_chain_match->destination_port != addr->port) - return false; - - transport_protocol = kmesh_get_ptr_val(filter_chain_match->transport_protocol); - if (!transport_protocol) { - BPF_LOG(WARN, LISTENER, "transport_protocol is NULL\n"); - return false; - } else if (transport_protocol[0] != '\0' && bpf__strncmp(buf, sizeof(buf), transport_protocol) != 0) { - BPF_LOG(WARN, LISTENER, "transport_protocol %s mismatch\n", transport_protocol); - return false; - } - - // TODO: application_protocols - - BPF_LOG(DEBUG, LISTENER, "match filter_chain, name=\"%s\"\n", - (char *)kmesh_get_ptr_val(filter_chain->name)); - return true; + char *transport_protocol; + const char buf[] = "raw_buffer"; + + Listener__FilterChainMatch *filter_chain_match = kmesh_get_ptr_val(filter_chain->filter_chain_match); + if (!filter_chain_match) + return false; + + if (filter_chain_match->destination_port != 0 && filter_chain_match->destination_port != addr->port) + return false; + + transport_protocol = kmesh_get_ptr_val(filter_chain_match->transport_protocol); + if (!transport_protocol) { + BPF_LOG(WARN, LISTENER, "transport_protocol is NULL\n"); + return false; + } else if (transport_protocol[0] != '\0' && bpf__strncmp(buf, sizeof(buf), transport_protocol) != 0) { + BPF_LOG(WARN, LISTENER, "transport_protocol %s mismatch\n", transport_protocol); + return false; + } + + // TODO: application_protocols + + BPF_LOG(DEBUG, LISTENER, "match filter_chain, name=\"%s\"\n", (char *)kmesh_get_ptr_val(filter_chain->name)); + return true; } -static inline int listener_filter_chain_match(const Listener__Listener *listener, - const address_t *addr, - const ctx_buff_t *ctx, - Listener__FilterChain **filter_chain_ptr, - __u64 *filter_chain_idx) +static inline int listener_filter_chain_match( + const Listener__Listener *listener, + const address_t *addr, + const ctx_buff_t *ctx, + Listener__FilterChain **filter_chain_ptr, + __u64 *filter_chain_idx) { - int i; - void *ptrs = NULL; - Listener__FilterChain *filter_chain = NULL; - - if (listener->n_filter_chains == 0 || listener->n_filter_chains > KMESH_PER_FILTER_CHAIN_NUM) { - BPF_LOG(ERR, LISTENER, "listener has no filter chains\n"); - return -1; - } - - ptrs = kmesh_get_ptr_val(listener->filter_chains); - if (!ptrs) { - BPF_LOG(ERR, LISTENER, "failed to get filter chain ptrs\n"); - return -1; - } - - #pragma unroll - for (i = 0; i < KMESH_PER_FILTER_CHAIN_NUM; i++) { - if (i >= (int)listener->n_filter_chains) { - break; - } - - filter_chain = (Listener__FilterChain *)kmesh_get_ptr_val((void*)*((__u64*)ptrs + i)); - if (!filter_chain) { - continue; - } - - if (listener_filter_chain_match_check(filter_chain, addr, ctx)) { - *filter_chain_ptr = filter_chain; - *filter_chain_idx = (__u64)*((__u64*)ptrs + i); - return 0; - } - } - return -1; + int i; + void *ptrs = NULL; + Listener__FilterChain *filter_chain = NULL; + + if (listener->n_filter_chains == 0 || listener->n_filter_chains > KMESH_PER_FILTER_CHAIN_NUM) { + BPF_LOG(ERR, LISTENER, "listener has no filter chains\n"); + return -1; + } + + ptrs = kmesh_get_ptr_val(listener->filter_chains); + if (!ptrs) { + BPF_LOG(ERR, LISTENER, "failed to get filter chain ptrs\n"); + return -1; + } + +#pragma unroll + for (i = 0; i < KMESH_PER_FILTER_CHAIN_NUM; i++) { + if (i >= (int)listener->n_filter_chains) { + break; + } + + filter_chain = (Listener__FilterChain *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!filter_chain) { + continue; + } + + if (listener_filter_chain_match_check(filter_chain, addr, ctx)) { + *filter_chain_ptr = filter_chain; + *filter_chain_idx = (__u64) * ((__u64 *)ptrs + i); + return 0; + } + } + return -1; } 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}; - - DECLARE_VAR_ADDRESS(ctx, addr); - /* filter chain match */ - ret = listener_filter_chain_match(listener, &addr, ctx, &filter_chain, &filter_chain_idx); - if (ret != 0) { - BPF_LOG(WARN, LISTENER, "filterchain mismatch, un support addr=%u:%u\n", addr.ipv4, addr.port); - return -1; - } - - /* exec filter chain */ - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER_CHAIN, addr); - KMESH_TAIL_CALL_CTX_VAL(ctx_val, msg, filter_chain_idx); - - KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_FILTER_CHAIN, ctx_key, ctx_val); - return KMESH_TAIL_CALL_RET(ret); + 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}; + + DECLARE_VAR_ADDRESS(ctx, addr); + /* filter chain match */ + ret = listener_filter_chain_match(listener, &addr, ctx, &filter_chain, &filter_chain_idx); + if (ret != 0) { + BPF_LOG(WARN, LISTENER, "filterchain mismatch, un support addr=%u:%u\n", addr.ipv4, addr.port); + return -1; + } + + /* exec filter chain */ + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_FILTER_CHAIN, addr); + KMESH_TAIL_CALL_CTX_VAL(ctx_val, msg, filter_chain_idx); + + KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_FILTER_CHAIN, ctx_key, ctx_val); + return KMESH_TAIL_CALL_RET(ret); } #endif diff --git a/bpf/kmesh/include/route_config.h b/bpf/kmesh/include/route_config.h index 86d149b79..d2aab75a2 100644 --- a/bpf/kmesh/include/route_config.h +++ b/bpf/kmesh/include/route_config.h @@ -24,374 +24,379 @@ #include "tail_call.h" #include "route/route.pb-c.h" -#define ROUTER_NAME_MAX_LEN BPF_DATA_MAX_LEN +#define ROUTER_NAME_MAX_LEN BPF_DATA_MAX_LEN struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(key_size, ROUTER_NAME_MAX_LEN); - __uint(value_size, sizeof(Route__RouteConfiguration)); - __uint(max_entries, MAP_SIZE_OF_ROUTE); - __uint(map_flags, BPF_F_NO_PREALLOC); + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, ROUTER_NAME_MAX_LEN); + __uint(value_size, sizeof(Route__RouteConfiguration)); + __uint(max_entries, MAP_SIZE_OF_ROUTE); + __uint(map_flags, BPF_F_NO_PREALLOC); } map_of_router_config SEC(".maps"); static inline Route__RouteConfiguration *map_lookup_route_config(const char *route_name) { - if (!route_name) - return NULL; + if (!route_name) + return NULL; - return kmesh_map_lookup_elem(&map_of_router_config, route_name); + 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 *uri) +static inline int +virtual_host_match_check(Route__VirtualHost *virt_host, address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *uri) { - int i; - void *domains = NULL; - void *domain = NULL; - void *ptr; - __u32 ptr_length; + int i; + void *domains = NULL; + void *domain = NULL; + void *ptr; + __u32 ptr_length; - if (!uri) - return 0; + if (!uri) + return 0; - ptr = _(uri->ptr); - if (!ptr) - return 0; + ptr = _(uri->ptr); + if (!ptr) + return 0; - ptr_length = _(uri->size); + ptr_length = _(uri->size); - if (!virt_host->domains) - return 0; + if (!virt_host->domains) + return 0; - domains = kmesh_get_ptr_val(_(virt_host->domains)); - if (!domains) - return 0; + domains = kmesh_get_ptr_val(_(virt_host->domains)); + if (!domains) + return 0; - for (i = 0; i < KMESH_HTTP_DOMAIN_NUM; i++) { - if (i >= virt_host->n_domains) { - break; - } + for (i = 0; i < KMESH_HTTP_DOMAIN_NUM; i++) { + if (i >= virt_host->n_domains) { + break; + } - domain = kmesh_get_ptr_val((void*)*((__u64*)domains + i)); - if (!domain) - continue; + domain = kmesh_get_ptr_val((void *)*((__u64 *)domains + i)); + if (!domain) + continue; - if (((char *)domain)[0] == '*' && ((char *)domain)[1] == '\0') - return 1; + 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)); - 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)); + return 1; + } + } - return 0; + return 0; } -static inline bool VirtualHost_check_allow_any(char *name) { - char allow_any[10] = {'a', 'l', 'l', 'o', 'w', '_','a', 'n', 'y', '\0'}; - if (name && bpf__strncmp(allow_any, 10, name) == 0) { - return true; - } - return false; +static inline bool VirtualHost_check_allow_any(char *name) +{ + char allow_any[10] = {'a', 'l', 'l', 'o', 'w', '_', 'a', 'n', 'y', '\0'}; + if (name && bpf__strncmp(allow_any, 10, name) == 0) { + return true; + } + return false; } -static inline Route__VirtualHost *virtual_host_match(Route__RouteConfiguration *route_config, - address_t *addr, - ctx_buff_t *ctx) +static inline Route__VirtualHost * +virtual_host_match(Route__RouteConfiguration *route_config, address_t *addr, ctx_buff_t *ctx) { - int i; - void *ptrs = NULL; - Route__VirtualHost *virt_host = NULL; - Route__VirtualHost *virt_host_allow_any = NULL; - char uri_key[4] = {'U', 'R', 'I', '\0'}; - struct bpf_mem_ptr *uri; - - 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); - return NULL; - } - - ptrs = kmesh_get_ptr_val(_(route_config->virtual_hosts)); - if (!ptrs) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get virtual hosts\n"); - return NULL; - } - - uri = bpf_get_msg_header_element(uri_key); - if (!uri) { - 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; - } - - virt_host = kmesh_get_ptr_val((void*)*((__u64*)ptrs + i)); - if (!virt_host) - continue; - - if (VirtualHost_check_allow_any((char *)kmesh_get_ptr_val(virt_host->name))) { - virt_host_allow_any = virt_host; - continue; - } - - if (virtual_host_match_check(virt_host, addr, ctx, uri)) - 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, uri)) - return virt_host_allow_any; - return NULL; + int i; + void *ptrs = NULL; + Route__VirtualHost *virt_host = NULL; + Route__VirtualHost *virt_host_allow_any = NULL; + char uri_key[4] = {'U', 'R', 'I', '\0'}; + struct bpf_mem_ptr *uri; + + 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); + return NULL; + } + + ptrs = kmesh_get_ptr_val(_(route_config->virtual_hosts)); + if (!ptrs) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get virtual hosts\n"); + return NULL; + } + + uri = bpf_get_msg_header_element(uri_key); + if (!uri) { + 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; + } + + virt_host = kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!virt_host) + continue; + + if (VirtualHost_check_allow_any((char *)kmesh_get_ptr_val(virt_host->name))) { + virt_host_allow_any = virt_host; + continue; + } + + if (virtual_host_match_check(virt_host, addr, ctx, uri)) + 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, uri)) + return virt_host_allow_any; + return NULL; } -static inline bool check_header_value_match(char *target, struct bpf_mem_ptr* head, 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); +static inline bool check_header_value_match(char *target, struct bpf_mem_ptr *head, 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); } -static inline bool check_headers_match(Route__RouteMatch *match) { - int i; - void *ptrs = NULL; - char *header_name = NULL; - char *config_header_value = NULL; - struct bpf_mem_ptr *msg_header = NULL; - Route__HeaderMatcher *header_match = NULL; - - if (match->n_headers <= 0) - return true; - if (match->n_headers > KMESH_PER_HEADER_MUM) { - BPF_LOG(ERR, ROUTER_CONFIG, "un support header num(%d), no need to check\n", match->n_headers); - return false; - } - ptrs = kmesh_get_ptr_val(_(match->headers)); - if (!ptrs) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get match headers in route match\n"); - return false; - } - for (i = 0; i < KMESH_PER_HEADER_MUM; i++) { - if (i >= match->n_headers) { - break; - } - header_match = (Route__HeaderMatcher *) kmesh_get_ptr_val((void *)*((__u64*)ptrs + i)); - if (!header_match) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get match headers in route match\n"); - return false; - } - header_name = kmesh_get_ptr_val(header_match->name); - if (!header_name) { - 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); - if (config_header_value == NULL) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get config_header_value\n"); - } - if (!check_header_value_match(config_header_value, msg_header, true)) { - return false; - } - break; - } - case ROUTE__HEADER_MATCHER__HEADER_MATCH_SPECIFIER_PREFIX_MATCH: { - config_header_value = kmesh_get_ptr_val(header_match->prefix_match); - if (config_header_value == NULL) { - BPF_LOG(ERR, ROUTER_CONFIG, "prefix:failed to get config_header_value\n"); - } - if (!check_header_value_match(config_header_value, msg_header, false)) { - return false; - } - break; - } - default: - BPF_LOG(ERR, ROUTER_CONFIG, "un-support match type:%d\n", header_match->header_match_specifier_case); - return false; - } - } - return true; +static inline bool check_headers_match(Route__RouteMatch *match) +{ + int i; + void *ptrs = NULL; + char *header_name = NULL; + char *config_header_value = NULL; + struct bpf_mem_ptr *msg_header = NULL; + Route__HeaderMatcher *header_match = NULL; + + if (match->n_headers <= 0) + return true; + if (match->n_headers > KMESH_PER_HEADER_MUM) { + BPF_LOG(ERR, ROUTER_CONFIG, "un support header num(%d), no need to check\n", match->n_headers); + return false; + } + ptrs = kmesh_get_ptr_val(_(match->headers)); + if (!ptrs) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get match headers in route match\n"); + return false; + } + for (i = 0; i < KMESH_PER_HEADER_MUM; i++) { + if (i >= match->n_headers) { + break; + } + header_match = (Route__HeaderMatcher *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!header_match) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get match headers in route match\n"); + return false; + } + header_name = kmesh_get_ptr_val(header_match->name); + if (!header_name) { + 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); + if (config_header_value == NULL) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get config_header_value\n"); + } + if (!check_header_value_match(config_header_value, msg_header, true)) { + return false; + } + break; + } + case ROUTE__HEADER_MATCHER__HEADER_MATCH_SPECIFIER_PREFIX_MATCH: { + config_header_value = kmesh_get_ptr_val(header_match->prefix_match); + if (config_header_value == NULL) { + BPF_LOG(ERR, ROUTER_CONFIG, "prefix:failed to get config_header_value\n"); + } + if (!check_header_value_match(config_header_value, msg_header, false)) { + return false; + } + break; + } + default: + BPF_LOG(ERR, ROUTER_CONFIG, "un-support match type:%d\n", header_match->header_match_specifier_case); + return false; + } + } + return true; } -static inline int virtual_host_route_match_check(Route__Route *route, - address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) +static inline int +virtual_host_route_match_check(Route__Route *route, address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { - Route__RouteMatch *match; - char *prefix; - void *ptr; + Route__RouteMatch *match; + char *prefix; + void *ptr; - ptr = _(msg->ptr); - if (!ptr) - return 0; + ptr = _(msg->ptr); + if (!ptr) + return 0; - if (!route->match) - return 0; + if (!route->match) + return 0; - match = kmesh_get_ptr_val(route->match); - if (!match) - return 0; + match = kmesh_get_ptr_val(route->match); + if (!match) + return 0; - prefix = kmesh_get_ptr_val(match->prefix); - if (!prefix) - return 0; + prefix = kmesh_get_ptr_val(match->prefix); + if (!prefix) + return 0; - if (bpf_strnstr(ptr, prefix, BPF_DATA_MAX_LEN) == NULL) - return 0; + if (bpf_strnstr(ptr, prefix, BPF_DATA_MAX_LEN) == NULL) + return 0; - if (!check_headers_match(match)) - return 0; + if (!check_headers_match(match)) + return 0; - BPF_LOG(DEBUG, ROUTER_CONFIG, "match route, name=\"%s\"\n", - (char *)kmesh_get_ptr_val(route->name)); - return 1; + BPF_LOG(DEBUG, ROUTER_CONFIG, "match route, name=\"%s\"\n", (char *)kmesh_get_ptr_val(route->name)); + return 1; } -static inline Route__Route *virtual_host_route_match(Route__VirtualHost *virt_host, - address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) +static inline Route__Route * +virtual_host_route_match(Route__VirtualHost *virt_host, address_t *addr, ctx_buff_t *ctx, struct bpf_mem_ptr *msg) { - int i; - void *ptrs = NULL; - Route__Route *route = NULL; - - if (virt_host->n_routes <= 0 || virt_host->n_routes > KMESH_PER_ROUTE_NUM) { - BPF_LOG(WARN, ROUTER_CONFIG, "invalid virtual route num(%d)\n", virt_host->n_routes); - return NULL; - } - - ptrs = kmesh_get_ptr_val(_(virt_host->routes)); - if (!ptrs) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get routes ptrs\n"); - return NULL; - } - - for (i = 0; i < KMESH_PER_ROUTE_NUM; i++) { - if (i >= virt_host->n_routes) { - break; - } - - route = (Route__Route *)kmesh_get_ptr_val((void*)*((__u64*)ptrs + i)); - if (!route) - continue; - - if (virtual_host_route_match_check(route, addr, ctx, msg)) - return route; - } - return NULL; + int i; + void *ptrs = NULL; + Route__Route *route = NULL; + + if (virt_host->n_routes <= 0 || virt_host->n_routes > KMESH_PER_ROUTE_NUM) { + BPF_LOG(WARN, ROUTER_CONFIG, "invalid virtual route num(%d)\n", virt_host->n_routes); + return NULL; + } + + ptrs = kmesh_get_ptr_val(_(virt_host->routes)); + if (!ptrs) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get routes ptrs\n"); + return NULL; + } + + for (i = 0; i < KMESH_PER_ROUTE_NUM; i++) { + if (i >= virt_host->n_routes) { + break; + } + + route = (Route__Route *)kmesh_get_ptr_val((void *)*((__u64 *)ptrs + i)); + if (!route) + continue; + + if (virtual_host_route_match_check(route, addr, ctx, msg)) + return route; + } + 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 *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)); + 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); - - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_ROUTER_CONFIG, addr); - ctx_val = kmesh_tail_lookup_ctx(&ctx_key); - if (!ctx_val) - return KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_RET(-1); - } - - cluster = route_get_cluster(route); - if (!cluster) { - BPF_LOG(ERR, ROUTER_CONFIG, "failed to get cluster\n"); - return KMESH_TAIL_CALL_RET(-1); - } - - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_CLUSTER, addr); - KMESH_TAIL_CALL_CTX_VALSTR(ctx_val_1, NULL, cluster); - - KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_CLUSTER, ctx_key, ctx_val_1); - return KMESH_TAIL_CALL_RET(ret); + 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); + + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_ROUTER_CONFIG, addr); + ctx_val = kmesh_tail_lookup_ctx(&ctx_key); + if (!ctx_val) + return KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_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 KMESH_TAIL_CALL_RET(-1); + } + + cluster = route_get_cluster(route); + if (!cluster) { + BPF_LOG(ERR, ROUTER_CONFIG, "failed to get cluster\n"); + return KMESH_TAIL_CALL_RET(-1); + } + + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_CLUSTER, addr); + KMESH_TAIL_CALL_CTX_VALSTR(ctx_val_1, NULL, cluster); + + KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_CLUSTER, ctx_key, ctx_val_1); + return KMESH_TAIL_CALL_RET(ret); } #endif diff --git a/bpf/kmesh/include/tail_call.h b/bpf/kmesh/include/tail_call.h index bb14132a6..f82e47f89 100644 --- a/bpf/kmesh/include/tail_call.h +++ b/bpf/kmesh/include/tail_call.h @@ -23,8 +23,8 @@ #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 MAP_SIZE_OF_TAIL_CALL_PROG 32 +#define MAP_SIZE_OF_TAIL_CALL_CTX 256 struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); @@ -78,44 +78,44 @@ static inline int kmesh_tail_update_ctx(const ctx_key_t *key, const ctx_val_t *v } /* - As a service mesh accelerator, Kmesh is expected to roll back to the original forwarding - process when the acceleration forwarding logic fails. The execution result of the bpf + As a service mesh accelerator, Kmesh is expected to roll back to the original forwarding + process when the acceleration forwarding logic fails. The execution result of the bpf tail caller must return BPF_OK. */ -#define KMESH_TAIL_CALL_RET(ret) BPF_OK +#define KMESH_TAIL_CALL_RET(ret) BPF_OK /* * To avoid interference between tail calls in different processes, we utilize - * the exclusivity of the eBPF program to the CPU to distinguish tail calls - * generated in different processes + * the exclusivity of the eBPF program to the CPU to distinguish tail calls + * generated in different processes */ -#define KMESH_TAIL_CALL_CTX_KEY(ckey, tail_call_idx, addr) \ -{ \ - ckey.address = addr; \ - ckey.tail_call_index = tail_call_idx + (bpf_get_smp_processor_id() << 16);\ -} - -#define KMESH_TAIL_CALL_CTX_VAL(cval, m, v) \ -{ \ - cval.msg = m; \ - cval.val = v; \ -} - -#define KMESH_TAIL_CALL_CTX_VALSTR(cval, m, s) \ -{ \ - cval.msg = m; \ - (void)bpf_strncpy(cval.data, BPF_DATA_MAX_LEN, s); \ -} - -#define KMESH_TAIL_CALL_WITH_CTX(tail_call_idx, ckey, cval) \ -{ \ - ret = kmesh_tail_update_ctx(&ckey, &cval); \ - if (ret != 0) { \ - BPF_LOG(ERR, COMMON, "kmesh tail update failed:%d\n", ret); \ - } else { \ - kmesh_tail_call(ctx, tail_call_idx); \ - kmesh_tail_delete_ctx(&ckey); \ - } \ -} +#define KMESH_TAIL_CALL_CTX_KEY(ckey, tail_call_idx, addr) \ + { \ + ckey.address = addr; \ + ckey.tail_call_index = tail_call_idx + (bpf_get_smp_processor_id() << 16); \ + } + +#define KMESH_TAIL_CALL_CTX_VAL(cval, m, v) \ + { \ + cval.msg = m; \ + cval.val = v; \ + } + +#define KMESH_TAIL_CALL_CTX_VALSTR(cval, m, s) \ + { \ + cval.msg = m; \ + (void)bpf_strncpy(cval.data, BPF_DATA_MAX_LEN, s); \ + } + +#define KMESH_TAIL_CALL_WITH_CTX(tail_call_idx, ckey, cval) \ + { \ + ret = kmesh_tail_update_ctx(&ckey, &cval); \ + if (ret != 0) { \ + BPF_LOG(ERR, COMMON, "kmesh tail update failed:%d\n", ret); \ + } else { \ + kmesh_tail_call(ctx, tail_call_idx); \ + kmesh_tail_delete_ctx(&ckey); \ + } \ + } #endif // _TAIL_CALL_H_ diff --git a/bpf/kmesh/include/tcp_proxy.h b/bpf/kmesh/include/tcp_proxy.h index f0085764c..de59d4637 100644 --- a/bpf/kmesh/include/tcp_proxy.h +++ b/bpf/kmesh/include/tcp_proxy.h @@ -26,71 +26,70 @@ static inline char *select_tcp_weight_cluster(const Filter__TcpProxy *tcpProxy) { - void *clusters = NULL; - Filter__TcpProxy__WeightedCluster *weightedClusters = NULL; - Filter__TcpProxy__WeightedCluster__ClusterWeight *cluster_weight = NULL; - int32_t select_value; - void *cluster_name = NULL; + void *clusters = NULL; + Filter__TcpProxy__WeightedCluster *weightedClusters = NULL; + Filter__TcpProxy__WeightedCluster__ClusterWeight *cluster_weight = NULL; + int32_t select_value; + void *cluster_name = NULL; - weightedClusters = (Filter__TcpProxy__WeightedCluster *)kmesh_get_ptr_val((tcpProxy->weighted_clusters)); - if (!weightedClusters) { - return NULL; - } - clusters = kmesh_get_ptr_val(weightedClusters->clusters); - if (!clusters) { - return NULL; - } + weightedClusters = (Filter__TcpProxy__WeightedCluster *)kmesh_get_ptr_val((tcpProxy->weighted_clusters)); + if (!weightedClusters) { + return NULL; + } + clusters = kmesh_get_ptr_val(weightedClusters->clusters); + if (!clusters) { + return NULL; + } - select_value = (int)(bpf_get_prandom_u32() % 100); - - #pragma unroll - for (int i = 0; i < KMESH_PER_WEIGHT_CLUSTER_NUM; i ++) { - if (i >= weightedClusters->n_clusters) { - break; - } - cluster_weight = (Filter__TcpProxy__WeightedCluster__ClusterWeight *) kmesh_get_ptr_val( - (void *) *((__u64 *) clusters + i)); - if (!cluster_weight) { - return NULL; - } - select_value = select_value - (int)cluster_weight->weight; - if (select_value <= 0) { - cluster_name = kmesh_get_ptr_val(cluster_weight->name); - BPF_LOG(DEBUG, FILTER, "select cluster, %s:%d\n", cluster_name, cluster_weight->weight); - return (char*)cluster_name; - } - } - return NULL; -} + select_value = (int)(bpf_get_prandom_u32() % 100); +#pragma unroll + for (int i = 0; i < KMESH_PER_WEIGHT_CLUSTER_NUM; i++) { + if (i >= weightedClusters->n_clusters) { + break; + } + cluster_weight = + (Filter__TcpProxy__WeightedCluster__ClusterWeight *)kmesh_get_ptr_val((void *)*((__u64 *)clusters + i)); + if (!cluster_weight) { + return NULL; + } + select_value = select_value - (int)cluster_weight->weight; + if (select_value <= 0) { + cluster_name = kmesh_get_ptr_val(cluster_weight->name); + BPF_LOG(DEBUG, FILTER, "select cluster, %s:%d\n", cluster_name, cluster_weight->weight); + return (char *)cluster_name; + } + } + return NULL; +} static inline char *tcp_proxy_get_cluster(const Filter__TcpProxy *tcpProxy) { - if (tcpProxy->cluster_specifier_case == FILTER__TCP_PROXY__CLUSTER_SPECIFIER_WEIGHTED_CLUSTERS) { - return select_tcp_weight_cluster(tcpProxy); - } + if (tcpProxy->cluster_specifier_case == FILTER__TCP_PROXY__CLUSTER_SPECIFIER_WEIGHTED_CLUSTERS) { + return select_tcp_weight_cluster(tcpProxy); + } - return (char*)kmesh_get_ptr_val(tcpProxy->cluster); + return (char *)kmesh_get_ptr_val(tcpProxy->cluster); } static inline int tcp_proxy_manager(const Filter__TcpProxy *tcpProxy, ctx_buff_t *ctx) { - int ret; - char *cluster = NULL; - ctx_key_t ctx_key = {0}; - ctx_val_t ctx_val = {0}; + int ret; + char *cluster = NULL; + ctx_key_t ctx_key = {0}; + ctx_val_t ctx_val = {0}; - if (NULL == tcpProxy) - return -EINVAL; + if (NULL == tcpProxy) + return -EINVAL; - DECLARE_VAR_ADDRESS(ctx, addr); - cluster = tcp_proxy_get_cluster(tcpProxy); + DECLARE_VAR_ADDRESS(ctx, addr); + cluster = tcp_proxy_get_cluster(tcpProxy); - KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_CLUSTER, addr); - KMESH_TAIL_CALL_CTX_VALSTR(ctx_val, NULL, cluster); + KMESH_TAIL_CALL_CTX_KEY(ctx_key, KMESH_TAIL_CALL_CLUSTER, addr); + KMESH_TAIL_CALL_CTX_VALSTR(ctx_val, NULL, cluster); - KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_CLUSTER, ctx_key, ctx_val); - return KMESH_TAIL_CALL_RET(ret); + KMESH_TAIL_CALL_WITH_CTX(KMESH_TAIL_CALL_CLUSTER, ctx_key, ctx_val); + return KMESH_TAIL_CALL_RET(ret); } #endif // __TCP_PROXY_H__ diff --git a/bpf/kmesh/sockops.c b/bpf/kmesh/sockops.c index 264d5c3ca..e59e33446 100644 --- a/bpf/kmesh/sockops.c +++ b/bpf/kmesh/sockops.c @@ -30,50 +30,52 @@ 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); + int ret; + /* 1 lookup listener */ + DECLARE_VAR_ADDRESS(skops, addr); #if !OE_23_03 - addr.port = addr.port >> 16; + addr.port = addr.port >> 16; #endif - Listener__Listener *listener = map_lookup_listener(&addr); + 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; - } - } + if (!listener) { + addr.ipv4 = 0; + listener = map_lookup_listener(&addr); + if (!listener) { + /* no match vip/nodeport listener */ + return 0; + } + } - 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); + 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)) -#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; - struct bpf_mem_ptr *msg = NULL; + if (skops->family != AF_INET) + return BPF_OK; - if (skops->family != AF_INET) - 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); - } - 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); + } + return BPF_OK; } #endif #endif char _license[] SEC("license") = "GPL"; int _version SEC("version") = 1; - diff --git a/bpf/kmesh/tracepoint.c b/bpf/kmesh/tracepoint.c index 32aaacfc3..4d44bf7b0 100644 --- a/bpf/kmesh/tracepoint.c +++ b/bpf/kmesh/tracepoint.c @@ -5,15 +5,15 @@ #define KMESH_DELAY_ERROR -1000 struct context { - int *err; + int *err; }; SEC("raw_tracepoint.w") int connect_ret(struct context *ctx) { - if (*ctx->err == KMESH_DELAY_ERROR) - *ctx->err = 0; - return 0; + if (*ctx->err == KMESH_DELAY_ERROR) + *ctx->err = 0; + return 0; } char _license[] SEC("license") = "GPL"; diff --git a/bpf/kmesh/workload/cgroup_sock.c b/bpf/kmesh/workload/cgroup_sock.c index 528abac3e..6dac1632a 100644 --- a/bpf/kmesh/workload/cgroup_sock.c +++ b/bpf/kmesh/workload/cgroup_sock.c @@ -26,116 +26,111 @@ static inline void record_netns_cookie(struct bpf_sock_addr *ctx) { - int err; - int value = 0; - __u64 cookie = bpf_get_netns_cookie(ctx); - err = bpf_map_update_elem(&map_of_manager, &cookie, &value, BPF_NOEXIST); - if (err) - BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); + int err; + int value = 0; + __u64 cookie = bpf_get_netns_cookie(ctx); + err = bpf_map_update_elem(&map_of_manager, &cookie, &value, BPF_NOEXIST); + if (err) + BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); } static inline void remove_netns_cookie(struct bpf_sock_addr *ctx) { - int err; - __u64 cookie = bpf_get_netns_cookie(ctx); - err = bpf_map_delete_elem(&map_of_manager, &cookie); - if (err && err != -ENOENT) - BPF_LOG(ERR, KMESH, "remove netcookie failed!, err is %d\n", err); + int err; + __u64 cookie = bpf_get_netns_cookie(ctx); + err = bpf_map_delete_elem(&map_of_manager, &cookie); + if (err && err != -ENOENT) + BPF_LOG(ERR, KMESH, "remove netcookie failed!, err is %d\n", err); } static inline bool check_kmesh_enabled(struct bpf_sock_addr *ctx) { - __u64 cookie = bpf_get_netns_cookie(ctx); - return bpf_map_lookup_elem(&map_of_manager, &cookie); + __u64 cookie = bpf_get_netns_cookie(ctx); + return bpf_map_lookup_elem(&map_of_manager, &cookie); } static inline int sock4_traffic_control(struct bpf_sock_addr *ctx) { - int ret; - frontend_value *frontend_v = NULL; - bool direct_backend = false; - - if (!check_kmesh_enabled(ctx)) - return 0; - - DECLARE_VAR_ADDRESS(ctx, address); - - BPF_LOG(DEBUG, KMESH, "origin addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); - frontend_v = map_lookup_frontend(&address); - if (!frontend_v) { - address.service_port = 0; - frontend_v = map_lookup_frontend(&address); - if (!frontend_v) { - return -ENOENT; - } - direct_backend = true; - } - - BPF_LOG(DEBUG, KMESH, "bpf find frontend addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); - - if (direct_backend) { - backend_key backend_k = {0}; - backend_value *backend_v = NULL; - - backend_k.backend_uid = frontend_v->upstream_id; - backend_v = map_lookup_backend(&backend_k); - if (!backend_v) { - BPF_LOG(ERR, KMESH, "find backend failed\n"); - return -ENOENT; - } - BPF_LOG(DEBUG, KMESH, "find pod frontend\n"); - ret = backend_manager(ctx, backend_v); - if (ret < 0) { - if (ret != -ENOENT) - BPF_LOG(ERR, KMESH, "backend_manager failed, ret:%d\n", ret); - return ret; - } - } else { - ret = frontend_manager(ctx, frontend_v); - if (ret != 0) { - if (ret != -ENOENT) - BPF_LOG(ERR, KMESH, "frontend_manager failed, ret:%d\n", ret); - return ret; - } - } - return 0; + int ret; + frontend_value *frontend_v = NULL; + bool direct_backend = false; + + if (!check_kmesh_enabled(ctx)) + return 0; + + DECLARE_VAR_ADDRESS(ctx, address); + + BPF_LOG(DEBUG, KMESH, "origin addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); + frontend_v = map_lookup_frontend(&address); + if (!frontend_v) { + address.service_port = 0; + frontend_v = map_lookup_frontend(&address); + if (!frontend_v) { + return -ENOENT; + } + direct_backend = true; + } + + BPF_LOG(DEBUG, KMESH, "bpf find frontend addr=[%u:%u]\n", ctx->user_ip4, ctx->user_port); + + if (direct_backend) { + backend_key backend_k = {0}; + backend_value *backend_v = NULL; + + backend_k.backend_uid = frontend_v->upstream_id; + backend_v = map_lookup_backend(&backend_k); + if (!backend_v) { + BPF_LOG(ERR, KMESH, "find backend failed\n"); + return -ENOENT; + } + BPF_LOG(DEBUG, KMESH, "find pod frontend\n"); + ret = backend_manager(ctx, backend_v); + if (ret < 0) { + if (ret != -ENOENT) + BPF_LOG(ERR, KMESH, "backend_manager failed, ret:%d\n", ret); + return ret; + } + } else { + ret = frontend_manager(ctx, frontend_v); + if (ret != 0) { + if (ret != -ENOENT) + BPF_LOG(ERR, KMESH, "frontend_manager failed, ret:%d\n", ret); + return ret; + } + } + return 0; } static inline bool conn_from_cni_sim_add(struct bpf_sock_addr *ctx) { - // cni sim connect 0.0.0.0:929(0x3a1) - // 0x3a1 is the specific port handled by the cni for enable Kmesh - return ((bpf_ntohl(ctx->user_ip4) == 1) && - (bpf_ntohl(ctx->user_port) == 0x3a10000)); + // cni sim connect 0.0.0.0:929(0x3a1) + // 0x3a1 is the specific port handled by the cni for enable Kmesh + return ((bpf_ntohl(ctx->user_ip4) == 1) && (bpf_ntohl(ctx->user_port) == 0x3a10000)); } static inline bool conn_from_cni_sim_delete(struct bpf_sock_addr *ctx) { - // cni sim connect 0.0.0.1:930(0x3a2) - // 0x3a2 is the specific port handled by the cni for disable Kmesh - return ((bpf_ntohl(ctx->user_ip4) == 1) && - (bpf_ntohl(ctx->user_port) == 0x3a20000)); + // cni sim connect 0.0.0.1:930(0x3a2) + // 0x3a2 is the specific port handled by the cni for disable Kmesh + return ((bpf_ntohl(ctx->user_ip4) == 1) && (bpf_ntohl(ctx->user_port) == 0x3a20000)); } - SEC("cgroup/connect4") int cgroup_connect4_prog(struct bpf_sock_addr *ctx) { - if (conn_from_cni_sim_add(ctx)) { - record_netns_cookie(ctx); - // return failed, cni sim connect 0.0.0.1:929(0x3a1) - // A normal program will not connect to this IP address - return CGROUP_SOCK_OK; - } - if (conn_from_cni_sim_delete(ctx)) { - remove_netns_cookie(ctx); - return CGROUP_SOCK_OK; - } - int ret = sock4_traffic_control(ctx); - return CGROUP_SOCK_OK; + if (conn_from_cni_sim_add(ctx)) { + record_netns_cookie(ctx); + // return failed, cni sim connect 0.0.0.1:929(0x3a1) + // A normal program will not connect to this IP address + return CGROUP_SOCK_OK; + } + if (conn_from_cni_sim_delete(ctx)) { + remove_netns_cookie(ctx); + return CGROUP_SOCK_OK; + } + int ret = sock4_traffic_control(ctx); + return CGROUP_SOCK_OK; } char _license[] SEC("license") = "GPL"; int _version SEC("version") = 1; - - diff --git a/bpf/kmesh/workload/include/backend.h b/bpf/kmesh/workload/include/backend.h index 1030bd92f..d57664eea 100644 --- a/bpf/kmesh/workload/include/backend.h +++ b/bpf/kmesh/workload/include/backend.h @@ -27,58 +27,55 @@ static inline backend_value *map_lookup_backend(const backend_key *key) { - return kmesh_map_lookup_elem(&map_of_backend, key); + return kmesh_map_lookup_elem(&map_of_backend, key); } static inline int backend_manager(ctx_buff_t *ctx, backend_value *backend_v) { - int ret; - address_t target_addr; - __u32 *sk = (__u32 *)ctx->sk; - struct bpf_sock_tuple value_tuple= {0}; + int ret; + address_t target_addr; + __u32 *sk = (__u32 *)ctx->sk; + struct bpf_sock_tuple value_tuple = {0}; - if (backend_v->waypoint_addr != 0 && backend_v->waypoint_port != 0) { - BPF_LOG(DEBUG, BACKEND, "find waypoint addr=[%u:%u]\n", backend_v->waypoint_addr, - backend_v->waypoint_port); - value_tuple.ipv4.daddr = ctx->user_ip4; - value_tuple.ipv4.dport = ctx->user_port; + if (backend_v->waypoint_addr != 0 && backend_v->waypoint_port != 0) { + BPF_LOG(DEBUG, BACKEND, "find waypoint addr=[%u:%u]\n", backend_v->waypoint_addr, backend_v->waypoint_port); + value_tuple.ipv4.daddr = ctx->user_ip4; + value_tuple.ipv4.dport = ctx->user_port; - ret = bpf_map_update_elem(&map_of_dst_info, &sk, &value_tuple, BPF_NOEXIST); - if (ret) { - BPF_LOG(ERR, BACKEND, "record metadata origin address and port failed, ret is %d\n", ret); - return ret; - } - target_addr.ipv4 = backend_v->waypoint_addr; - target_addr.port = backend_v->waypoint_port; - SET_CTX_ADDRESS(ctx, target_addr); - kmesh_workload_tail_call(ctx, TAIL_CALL_CONNECT4_INDEX); + ret = bpf_map_update_elem(&map_of_dst_info, &sk, &value_tuple, BPF_NOEXIST); + if (ret) { + BPF_LOG(ERR, BACKEND, "record metadata origin address and port failed, ret is %d\n", ret); + return ret; + } + target_addr.ipv4 = backend_v->waypoint_addr; + target_addr.port = backend_v->waypoint_port; + SET_CTX_ADDRESS(ctx, target_addr); + kmesh_workload_tail_call(ctx, TAIL_CALL_CONNECT4_INDEX); - // if tail call failed will run this code - BPF_LOG(ERR, BACKEND, "workload tail call failed, err is %d\n", ret); - return -ENOEXEC; - } + // if tail call failed will run this code + BPF_LOG(ERR, BACKEND, "workload tail call failed, err is %d\n", ret); + return -ENOEXEC; + } - DECLARE_VAR_ADDRESS(ctx, address); - #pragma unroll - for (unsigned int i = 0; i < backend_v->port_count; i++) { - if (i >= MAX_PORT_COUNT) { - BPF_LOG(WARN, BACKEND, "exceed the max port count\n"); - return -EINVAL; - } + DECLARE_VAR_ADDRESS(ctx, address); +#pragma unroll + for (unsigned int i = 0; i < backend_v->port_count; i++) { + if (i >= MAX_PORT_COUNT) { + BPF_LOG(WARN, BACKEND, "exceed the max port count\n"); + return -EINVAL; + } - if (address.service_port == backend_v->service_port[i]) { - target_addr.ipv4 = backend_v->ipv4; - target_addr.port = backend_v->target_port[i]; - SET_CTX_ADDRESS(ctx, target_addr); - BPF_LOG(DEBUG, BACKEND, "get the backend addr=[%u:%u]\n", - target_addr.ipv4, target_addr.port); - return 0; - } - } + if (address.service_port == backend_v->service_port[i]) { + target_addr.ipv4 = backend_v->ipv4; + target_addr.port = backend_v->target_port[i]; + SET_CTX_ADDRESS(ctx, target_addr); + BPF_LOG(DEBUG, BACKEND, "get the backend addr=[%u:%u]\n", target_addr.ipv4, target_addr.port); + return 0; + } + } - BPF_LOG(ERR, BACKEND, "failed to get the backend\n"); - return -ENOENT; + BPF_LOG(ERR, BACKEND, "failed to get the backend\n"); + return -ENOENT; } #endif - diff --git a/bpf/kmesh/workload/include/config.h b/bpf/kmesh/workload/include/config.h index 2cb91dc22..2db21278f 100644 --- a/bpf/kmesh/workload/include/config.h +++ b/bpf/kmesh/workload/include/config.h @@ -21,20 +21,19 @@ #define _KMESH_CONFIG_H_ // map size -#define MAP_SIZE_OF_FRONTEND 100 -#define MAP_SIZE_OF_SERVICE 100 -#define MAP_SIZE_OF_ENDPOINT 1000 -#define MAP_SIZE_OF_BACKEND 500 -#define MAP_SIZE_OF_AUTH 8192 -#define MAP_SIZE_OF_MANAGER 8192 -#define MAP_SIZE_OF_DSTINFO 8192 +#define MAP_SIZE_OF_FRONTEND 100 +#define MAP_SIZE_OF_SERVICE 100 +#define MAP_SIZE_OF_ENDPOINT 1000 +#define MAP_SIZE_OF_BACKEND 500 +#define MAP_SIZE_OF_AUTH 8192 +#define MAP_SIZE_OF_MANAGER 8192 +#define MAP_SIZE_OF_DSTINFO 8192 // map name -#define map_of_frontend kmesh_frontend -#define map_of_service kmesh_service -#define map_of_endpoint kmesh_endpoint -#define map_of_backend kmesh_backend -#define map_of_manager kmesh_manage +#define map_of_frontend kmesh_frontend +#define map_of_service kmesh_service +#define map_of_endpoint kmesh_endpoint +#define map_of_backend kmesh_backend +#define map_of_manager kmesh_manage #endif // _CONFIG_H_ - diff --git a/bpf/kmesh/workload/include/ctx/sock_addr.h b/bpf/kmesh/workload/include/ctx/sock_addr.h index c65861694..984d93462 100644 --- a/bpf/kmesh/workload/include/ctx/sock_addr.h +++ b/bpf/kmesh/workload/include/ctx/sock_addr.h @@ -17,25 +17,23 @@ * Create: 2024-01-20 */ - #ifndef __BPF_CTX_SOCK_ADDR_H #define __BPF_CTX_SOCK_ADDR_H typedef enum { - PROTOCOL_TCP = 0, - PROTOCOL_UDP, + PROTOCOL_TCP = 0, + PROTOCOL_UDP, } protocol_t; -typedef struct bpf_sock_addr ctx_buff_t; +typedef struct bpf_sock_addr ctx_buff_t; -#define DECLARE_VAR_ADDRESS(ctx, name) \ - frontend_key name = {0}; \ - name.ipv4 = (ctx)->user_ip4; \ - name.service_port = (ctx)->user_port \ +#define DECLARE_VAR_ADDRESS(ctx, name) \ + frontend_key name = {0}; \ + name.ipv4 = (ctx)->user_ip4; \ + name.service_port = (ctx)->user_port -#define SET_CTX_ADDRESS(ctx, address) \ - (ctx)->user_ip4 = (address).ipv4; \ - (ctx)->user_port = (address).port +#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/workload/include/endpoint.h b/bpf/kmesh/workload/include/endpoint.h index 76fc9532b..6e1716c90 100644 --- a/bpf/kmesh/workload/include/endpoint.h +++ b/bpf/kmesh/workload/include/endpoint.h @@ -25,31 +25,30 @@ static inline endpoint_value *map_lookup_endpoint(const endpoint_key *key) { - return kmesh_map_lookup_elem(&map_of_endpoint, key); + return kmesh_map_lookup_elem(&map_of_endpoint, key); } static inline int endpoint_manager(ctx_buff_t *ctx, endpoint_value *endpoint_v) { - int ret = 0; - backend_key backend_k = {0}; - backend_value *backend_v = NULL; - - backend_k.backend_uid = endpoint_v->backend_uid; - backend_v = map_lookup_backend(&backend_k); - if (!backend_v) { - BPF_LOG(WARN, ENDPOINT, "find backend failed"); - return -ENOENT; - } - - ret = backend_manager(ctx, backend_v); - if (ret != 0) { - if (ret != -ENOENT) - BPF_LOG(ERR, ENDPOINT, "backend_manager failed, ret:%d\n", ret); - return ret; - } - - return 0; + int ret = 0; + backend_key backend_k = {0}; + backend_value *backend_v = NULL; + + backend_k.backend_uid = endpoint_v->backend_uid; + backend_v = map_lookup_backend(&backend_k); + if (!backend_v) { + BPF_LOG(WARN, ENDPOINT, "find backend failed"); + return -ENOENT; + } + + ret = backend_manager(ctx, backend_v); + if (ret != 0) { + if (ret != -ENOENT) + BPF_LOG(ERR, ENDPOINT, "backend_manager failed, ret:%d\n", ret); + return ret; + } + + return 0; } #endif - diff --git a/bpf/kmesh/workload/include/frontend.h b/bpf/kmesh/workload/include/frontend.h index 2ff6589e8..4104279f9 100644 --- a/bpf/kmesh/workload/include/frontend.h +++ b/bpf/kmesh/workload/include/frontend.h @@ -24,31 +24,30 @@ static inline frontend_value *map_lookup_frontend(const frontend_key *key) { - return kmesh_map_lookup_elem(&map_of_frontend, key); + return kmesh_map_lookup_elem(&map_of_frontend, key); } static inline int frontend_manager(ctx_buff_t *ctx, frontend_value *frontend_v) { - int ret = 0; - service_key service_k = {0}; - service_value *service_v = NULL; - - service_k.service_id = frontend_v->upstream_id; - service_v = map_lookup_service(&service_k); - if (!service_v) { - BPF_LOG(WARN, FRONTEND, "find service failed\n"); - return -ENOENT; - } - - ret = service_manager(ctx, frontend_v->upstream_id, service_v); - if (ret != 0) { - if (ret != -ENOENT) - BPF_LOG(ERR, FRONTEND, "service_manager failed, ret:%d\n", ret); - return ret; - } - - return 0; + int ret = 0; + service_key service_k = {0}; + service_value *service_v = NULL; + + service_k.service_id = frontend_v->upstream_id; + service_v = map_lookup_service(&service_k); + if (!service_v) { + BPF_LOG(WARN, FRONTEND, "find service failed\n"); + return -ENOENT; + } + + ret = service_manager(ctx, frontend_v->upstream_id, service_v); + if (ret != 0) { + if (ret != -ENOENT) + BPF_LOG(ERR, FRONTEND, "service_manager failed, ret:%d\n", ret); + return ret; + } + + return 0; } #endif - diff --git a/bpf/kmesh/workload/include/service.h b/bpf/kmesh/workload/include/service.h index 59ac5cf76..4228ab981 100644 --- a/bpf/kmesh/workload/include/service.h +++ b/bpf/kmesh/workload/include/service.h @@ -24,51 +24,50 @@ static inline service_value *map_lookup_service(const service_key *key) { - return kmesh_map_lookup_elem(&map_of_service, key); + return kmesh_map_lookup_elem(&map_of_service, key); } static inline int lb_random_handle(ctx_buff_t *ctx, int service_id, service_value *service_v) { - int ret = 0; - endpoint_key endpoint_k = {0}; - endpoint_value *endpoint_v = NULL; + int ret = 0; + endpoint_key endpoint_k = {0}; + endpoint_value *endpoint_v = NULL; - endpoint_k.service_id = service_id; - endpoint_k.backend_index = bpf_get_prandom_u32() % service_v->endpoint_count + 1; + endpoint_k.service_id = service_id; + endpoint_k.backend_index = bpf_get_prandom_u32() % service_v->endpoint_count + 1; - endpoint_v = map_lookup_endpoint(&endpoint_k); - if (!endpoint_v) { - BPF_LOG(WARN, SERVICE, "find endpoint failed"); - return -ENOENT; - } + endpoint_v = map_lookup_endpoint(&endpoint_k); + if (!endpoint_v) { + BPF_LOG(WARN, SERVICE, "find endpoint failed"); + return -ENOENT; + } - ret = endpoint_manager(ctx, endpoint_v); - if (ret != 0) { - if (ret != -ENOENT) - BPF_LOG(ERR, SERVICE, "endpoint_manager failed, ret:%d\n", ret); - return ret; - } + ret = endpoint_manager(ctx, endpoint_v); + if (ret != 0) { + if (ret != -ENOENT) + BPF_LOG(ERR, SERVICE, "endpoint_manager failed, ret:%d\n", ret); + return ret; + } - return 0; + return 0; } static inline int service_manager(ctx_buff_t *ctx, int service_id, service_value *service_v) { - int ret = 0; + int ret = 0; - BPF_LOG(DEBUG, SERVICE, "load balance type:%u", service_v->lb_policy); - switch (service_v->lb_policy) { - case LB_POLICY_RANDOM: - ret = lb_random_handle(ctx, service_id, service_v); - break; - defalut: - BPF_LOG(ERR, SERVICE, "unsupport load balance type:%u\n", service_v->lb_policy); - ret = -EINVAL; - break; - } + BPF_LOG(DEBUG, SERVICE, "load balance type:%u", service_v->lb_policy); + switch (service_v->lb_policy) { + case LB_POLICY_RANDOM: + ret = lb_random_handle(ctx, service_id, service_v); + break; + defalut: + BPF_LOG(ERR, SERVICE, "unsupport load balance type:%u\n", service_v->lb_policy); + ret = -EINVAL; + break; + } - return ret; + return ret; } #endif - diff --git a/bpf/kmesh/workload/include/workload.h b/bpf/kmesh/workload/include/workload.h index 8f4fc2365..b6d9be4b6 100644 --- a/bpf/kmesh/workload/include/workload.h +++ b/bpf/kmesh/workload/include/workload.h @@ -22,56 +22,49 @@ #include "config.h" -#define MAX_PORT_COUNT 10 -#define RINGBUF_SIZE (1 << 12) +#define MAX_PORT_COUNT 10 +#define RINGBUF_SIZE (1 << 12) // frontend map // Generally, frontend_key store Service ip and port, for app access Service, -// Specifically, for app access Pod directly: frontend_key:{ipv4:, service_port:0}, frontend_value:{upstream_id:backend_uid} -typedef struct -{ +// Specifically, for app access Pod directly: frontend_key:{ipv4:, service_port:0}, +// frontend_value:{upstream_id:backend_uid} +typedef struct { __u32 ipv4; // Service ip or Pod ip - __u32 service_port; // actual port for Service or 0 for Pod + __u32 service_port; // actual port for Service or 0 for Pod } __attribute__((packed)) frontend_key; -typedef struct -{ +typedef struct { __u32 upstream_id; // service id for Service access or backend uid for Pod access } __attribute__((packed)) frontend_value; // service map -typedef struct -{ - __u32 service_id; // service id +typedef struct { + __u32 service_id; // service id } __attribute__((packed)) service_key; -typedef struct -{ - __u32 endpoint_count; // endpoint count of current service - __u32 lb_policy; // load balancing algorithm, currently only supports random algorithm +typedef struct { + __u32 endpoint_count; // endpoint count of current service + __u32 lb_policy; // load balancing algorithm, currently only supports random algorithm } __attribute__((packed)) service_value; // endpoint map -typedef struct -{ - __u32 service_id; // service id - __u32 backend_index; // if endpoint_count = 3, then backend_index = 0/1/2 +typedef struct { + __u32 service_id; // service id + __u32 backend_index; // if endpoint_count = 3, then backend_index = 0/1/2 } __attribute__((packed)) endpoint_key; -typedef struct -{ - __u32 backend_uid; // workload_uid to uint32 +typedef struct { + __u32 backend_uid; // workload_uid to uint32 } __attribute__((packed)) endpoint_value; // backend map -typedef struct -{ - __u32 backend_uid; // workload_uid to uint32 +typedef struct { + __u32 backend_uid; // workload_uid to uint32 } __attribute__((packed)) backend_key; -typedef struct -{ - __u32 ipv4; // backend ip +typedef struct { + __u32 ipv4; // backend ip __u32 port_count; __u32 service_port[MAX_PORT_COUNT]; __u32 target_port[MAX_PORT_COUNT]; @@ -124,11 +117,10 @@ struct { } map_of_tuple SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_HASH); - __type(key, __u64); - __type(value, __u32); - __uint(max_entries, MAP_SIZE_OF_MANAGER); - __uint(map_flags, 0); + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, __u64); + __type(value, __u32); + __uint(max_entries, MAP_SIZE_OF_MANAGER); + __uint(map_flags, 0); } map_of_manager SEC(".maps"); #endif - diff --git a/bpf/kmesh/workload/include/workload_common.h b/bpf/kmesh/workload/include/workload_common.h index ec76d6bac..87a70ddfc 100644 --- a/bpf/kmesh/workload/include/workload_common.h +++ b/bpf/kmesh/workload/include/workload_common.h @@ -25,28 +25,26 @@ #include "config.h" #include "workload.h" -#define KMESH_CLASSID_MARK 0x1000 +#define KMESH_CLASSID_MARK 0x1000 -#define BPF_LOGTYPE_FRONTEND BPF_DEBUG_OFF -#define BPF_LOGTYPE_SERVICE BPF_DEBUG_OFF -#define BPF_LOGTYPE_ENDPOINT BPF_DEBUG_OFF -#define BPF_LOGTYPE_BACKEND BPF_DEBUG_OFF +#define BPF_LOGTYPE_FRONTEND BPF_DEBUG_OFF +#define BPF_LOGTYPE_SERVICE BPF_DEBUG_OFF +#define BPF_LOGTYPE_ENDPOINT BPF_DEBUG_OFF +#define BPF_LOGTYPE_BACKEND BPF_DEBUG_OFF // bpf return value -#define CGROUP_SOCK_ERR 0 -#define CGROUP_SOCK_OK 1 +#define CGROUP_SOCK_ERR 0 +#define CGROUP_SOCK_OK 1 // loadbalance type typedef enum { - LB_POLICY_RANDOM = 0, + LB_POLICY_RANDOM = 0, } lb_policy_t; -typedef struct -{ - __u32 protocol; +typedef struct { + __u32 protocol; __u32 ipv4; __u32 port; } __attribute__((packed)) address_t; #endif // _WORKLOAD_COMMON_H_ - diff --git a/bpf/kmesh/workload/sendmsg.c b/bpf/kmesh/workload/sendmsg.c index 21510c795..21b22f743 100644 --- a/bpf/kmesh/workload/sendmsg.c +++ b/bpf/kmesh/workload/sendmsg.c @@ -33,19 +33,19 @@ * * When only the dst information needs to be transferred, the information * added to the payload is as follows: - * |0x01|8|[dst ip][dst port]| + * |0x01|8|[dst ip][dst port]| * ===> [dst ip] 4bytes, [dst port] 2bytes, data length 6 bytes, total 11 bytes * |0xfe| 0| * payload.. * total need add (1 + 4 + 4 + 2) + (1 + 4) = 16 bytes */ -#define TLV_TYPE_SIZE 1 +#define TLV_TYPE_SIZE 1 #define TLV_LENGTH_SIZE 4 #define TLV_DST_LENGTH 6 -#define TLV_DST_SIZE 11 -#define TLV_END_SIZE 5 +#define TLV_DST_SIZE 11 +#define TLV_END_SIZE 5 #define FORMAT_IP_LENGTH 16 @@ -149,13 +149,13 @@ static inline void encode_metadata_dst(struct sk_msg_md *msg, __u32 off) static inline void encode_metadata(struct sk_msg_md *msg, enum TLV_TYPE type, __u32 off) { - switch(type) { - case TLV_DST_INFO: { - encode_metadata_dst(msg, off); - break; - } - default: - break; + switch (type) { + case TLV_DST_INFO: { + encode_metadata_dst(msg, off); + break; + } + default: + break; } } diff --git a/bpf/kmesh/workload/sockops_tuple.c b/bpf/kmesh/workload/sockops_tuple.c index 4e95246a3..53385f578 100644 --- a/bpf/kmesh/workload/sockops_tuple.c +++ b/bpf/kmesh/workload/sockops_tuple.c @@ -23,198 +23,192 @@ #include "config.h" #include "encoder.h" -#define FORMAT_IP_LENGTH (16) +#define FORMAT_IP_LENGTH (16) enum family_type { - IPV4, - IPV6, + IPV4, + IPV6, }; struct ringbuf_msg_type { - __u32 type; - struct bpf_sock_tuple tuple; + __u32 type; + struct bpf_sock_tuple tuple; }; struct { - __uint(type, BPF_MAP_TYPE_SOCKHASH); - __type(key, struct bpf_sock_tuple); - __type(value, __u32); - __uint(max_entries, MAP_SIZE_OF_MANAGER); - __uint(map_flags, 0); + __uint(type, BPF_MAP_TYPE_SOCKHASH); + __type(key, struct bpf_sock_tuple); + __type(value, __u32); + __uint(max_entries, MAP_SIZE_OF_MANAGER); + __uint(map_flags, 0); } map_of_kmesh_hashmap SEC(".maps"); static inline bool is_managed_by_kmesh(__u32 ip) { - __u64 key = ip; - return bpf_map_lookup_elem(&map_of_manager, &key); + __u64 key = ip; + return bpf_map_lookup_elem(&map_of_manager, &key); } -static inline void extract_skops_to_tuple(struct bpf_sock_ops *skops, - struct bpf_sock_tuple *tuple_key) +static inline void extract_skops_to_tuple(struct bpf_sock_ops *skops, struct bpf_sock_tuple *tuple_key) { - tuple_key->ipv4.saddr = skops->local_ip4; - tuple_key->ipv4.daddr = skops->remote_ip4; - // local_port is host byteorder - tuple_key->ipv4.sport = bpf_htonl(skops->local_port) >> FORMAT_IP_LENGTH; - // remote_port is network byteorder - // openEuler 2303 convert remote port different than other linux vendor + tuple_key->ipv4.saddr = skops->local_ip4; + tuple_key->ipv4.daddr = skops->remote_ip4; + // local_port is host byteorder + tuple_key->ipv4.sport = bpf_htonl(skops->local_port) >> FORMAT_IP_LENGTH; + // remote_port is network byteorder + // openEuler 2303 convert remote port different than other linux vendor #if !OE_23_03 - tuple_key->ipv4.dport = skops->remote_port >> FORMAT_IP_LENGTH; + tuple_key->ipv4.dport = skops->remote_port >> FORMAT_IP_LENGTH; #else - tuple_key->ipv4.dport = skops->remote_port; + tuple_key->ipv4.dport = skops->remote_port; #endif } -static inline void extract_skops_to_tuple_reverse(struct bpf_sock_ops *skops, - struct bpf_sock_tuple *tuple_key) +static inline void extract_skops_to_tuple_reverse(struct bpf_sock_ops *skops, struct bpf_sock_tuple *tuple_key) { - tuple_key->ipv4.saddr = skops->remote_ip4; - tuple_key->ipv4.daddr = skops->local_ip4; - // remote_port is network byteorder - // openEuler 2303 convert remote port different than other linux vendor + tuple_key->ipv4.saddr = skops->remote_ip4; + tuple_key->ipv4.daddr = skops->local_ip4; + // remote_port is network byteorder + // openEuler 2303 convert remote port different than other linux vendor #if !OE_23_03 - tuple_key->ipv4.sport = skops->remote_port >> FORMAT_IP_LENGTH; + tuple_key->ipv4.sport = skops->remote_port >> FORMAT_IP_LENGTH; #else - tuple_key->ipv4.sport = skops->remote_port; + tuple_key->ipv4.sport = skops->remote_port; #endif - // local_port is host byteorder - tuple_key->ipv4.dport = bpf_htonl(skops->local_port) >> FORMAT_IP_LENGTH; + // local_port is host byteorder + tuple_key->ipv4.dport = bpf_htonl(skops->local_port) >> FORMAT_IP_LENGTH; } // clean map_of_auth static inline void clean_auth_map(struct bpf_sock_ops *skops) { - struct bpf_sock_tuple tuple_key = {0}; - // auth run PASSIVE ESTABLISHED CB now. In thie state cb - // tuple info src is server info, dst is client info - // During the auth, src must set the client info and dst set - // the server info when we transmitted to the kmesh auth info. - // In this way, auth can be performed normally. - extract_skops_to_tuple_reverse(skops, &tuple_key); - long ret = bpf_map_delete_elem(&map_of_auth, &tuple_key); - if(ret && ret != -ENOENT) - BPF_LOG(INFO, SOCKOPS, "map_of_auth bpf_map_delete_elem failed, ret: %d\n", ret); + struct bpf_sock_tuple tuple_key = {0}; + // auth run PASSIVE ESTABLISHED CB now. In thie state cb + // tuple info src is server info, dst is client info + // During the auth, src must set the client info and dst set + // the server info when we transmitted to the kmesh auth info. + // In this way, auth can be performed normally. + extract_skops_to_tuple_reverse(skops, &tuple_key); + long ret = bpf_map_delete_elem(&map_of_auth, &tuple_key); + if (ret && ret != -ENOENT) + BPF_LOG(INFO, SOCKOPS, "map_of_auth bpf_map_delete_elem failed, ret: %d\n", ret); } static inline void clean_dstinfo_map(struct bpf_sock_ops *skops) { __u32 *key = (__u32 *)skops->sk; long ret = bpf_map_delete_elem(&map_of_dst_info, &key); - if(ret && ret != -ENOENT) + if (ret && ret != -ENOENT) BPF_LOG(INFO, SOCKOPS, "bpf map delete destination info failed, ret: %d\n", ret); } // insert an IPv4 tuple into the ringbuf static inline void auth_ip_tuple(struct bpf_sock_ops *skops) { - struct ringbuf_msg_type *msg = bpf_ringbuf_reserve(&map_of_tuple, sizeof(*msg), 0); - if (!msg) { - BPF_LOG(WARN, SOCKOPS, "can not alloc new ringbuf in map_of_tuple"); - return; - } - // auth run PASSIVE ESTABLISHED CB now. In thie state cb - // tuple info src is server info, dst is client info - // During the auth, src must set the client info and dst set - // the server info when we transmitted to the kmesh auth info. - // In this way, auth can be performed normally. - extract_skops_to_tuple_reverse(skops, &(*msg).tuple); - (*msg).type = (__u32)IPV4; - bpf_ringbuf_submit(msg, 0); + struct ringbuf_msg_type *msg = bpf_ringbuf_reserve(&map_of_tuple, sizeof(*msg), 0); + if (!msg) { + BPF_LOG(WARN, SOCKOPS, "can not alloc new ringbuf in map_of_tuple"); + return; + } + // auth run PASSIVE ESTABLISHED CB now. In thie state cb + // tuple info src is server info, dst is client info + // During the auth, src must set the client info and dst set + // the server info when we transmitted to the kmesh auth info. + // In this way, auth can be performed normally. + extract_skops_to_tuple_reverse(skops, &(*msg).tuple); + (*msg).type = (__u32)IPV4; + bpf_ringbuf_submit(msg, 0); } static inline void enable_encoding_metadata(struct bpf_sock_ops *skops) { - int err; - struct bpf_sock_tuple tuple_info = {0}; - extract_skops_to_tuple(skops, &tuple_info); - err = bpf_sock_hash_update(skops, &map_of_kmesh_hashmap, &tuple_info, BPF_ANY); - if (err) - BPF_LOG(ERR, SOCKOPS, "enable encoding metadta failed!, err is %d\n", err); + int err; + struct bpf_sock_tuple tuple_info = {0}; + extract_skops_to_tuple(skops, &tuple_info); + err = bpf_sock_hash_update(skops, &map_of_kmesh_hashmap, &tuple_info, BPF_ANY); + if (err) + BPF_LOG(ERR, SOCKOPS, "enable encoding metadta failed!, err is %d\n", err); } static inline void record_ip(__u32 ip) { - int err; - __u32 value = 0; - __u64 key = ip; - err = bpf_map_update_elem(&map_of_manager, &key, &value, BPF_NOEXIST); - if (err) - BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); + int err; + __u32 value = 0; + __u64 key = ip; + err = bpf_map_update_elem(&map_of_manager, &key, &value, BPF_NOEXIST); + if (err) + BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); } static inline void remove_ip(__u32 ip) { - int err; - __u64 key = ip; - err = bpf_map_delete_elem(&map_of_manager, &key); - if (err && err != -ENOENT) - BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); + int err; + __u64 key = ip; + err = bpf_map_delete_elem(&map_of_manager, &key); + if (err && err != -ENOENT) + BPF_LOG(ERR, KMESH, "record netcookie failed!, err is %d\n", err); } - static inline bool conn_from_cni_sim_add(struct bpf_sock_ops *skops) { - // cni sim connect 0.0.0.1:929(0x3a1) - // 0x3a1 is the specific port handled by the cni for enable Kmesh + // cni sim connect 0.0.0.1:929(0x3a1) + // 0x3a1 is the specific port handled by the cni for enable Kmesh #if !OE_23_03 - return ((bpf_ntohl(skops->remote_ip4) == 1) && - (bpf_ntohl(skops->remote_port) == 0x3a1)); + return ((bpf_ntohl(skops->remote_ip4) == 1) && (bpf_ntohl(skops->remote_port) == 0x3a1)); #else - return ((bpf_ntohl(skops->remote_ip4) == 1) && - (bpf_ntohl(skops->remote_port) == 0xa1030000)); + return ((bpf_ntohl(skops->remote_ip4) == 1) && (bpf_ntohl(skops->remote_port) == 0xa1030000)); #endif } static inline bool conn_from_cni_sim_delete(struct bpf_sock_ops *skops) { - // cni sim connect 0.0.0.1:930(0x3a2) - // 0x3a2 is the specific port handled by the cni for disable Kmesh - return ((bpf_ntohl(skops->remote_ip4) == 1) && - (bpf_ntohl(skops->remote_port) == 0x3a2)); + // cni sim connect 0.0.0.1:930(0x3a2) + // 0x3a2 is the specific port handled by the cni for disable Kmesh + return ((bpf_ntohl(skops->remote_ip4) == 1) && (bpf_ntohl(skops->remote_port) == 0x3a2)); } static inline bool ipv4_mapped_addr(__u32 ip6[4]) { - return ip6[0] == 0 && ip6[1] == 0 && ip6[2] == 0xFFFF0000; + return ip6[0] == 0 && ip6[1] == 0 && ip6[2] == 0xFFFF0000; } SEC("sockops") int record_tuple(struct bpf_sock_ops *skops) { - if (skops->family != AF_INET && !ipv4_mapped_addr(skops->local_ip6)) - return 0; - switch (skops->op) { - case BPF_SOCK_OPS_TCP_CONNECT_CB: - if (conn_from_cni_sim_add(skops)) - record_ip(skops->local_ip4); - if (conn_from_cni_sim_delete(skops)) - remove_ip(skops->local_ip4); - break; - case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: - if (!is_managed_by_kmesh(skops->local_ip4)) // local ip4 is client ip - break; - if(bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) - BPF_LOG(ERR, SOCKOPS, "set sockops cb failed!\n"); - enable_encoding_metadata(skops); - break; - case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - if (!is_managed_by_kmesh(skops->local_ip4)) // local ip4 is server ip - break; - if(bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) - BPF_LOG(ERR, SOCKOPS, "set sockops cb failed!\n"); - auth_ip_tuple(skops); - break; - case BPF_SOCK_OPS_STATE_CB: - if (skops->args[1] == BPF_TCP_CLOSE || skops->args[1] == BPF_TCP_CLOSE_WAIT - || skops->args[1] == BPF_TCP_FIN_WAIT1) { - clean_auth_map(skops); - clean_dstinfo_map(skops); - } - break; - default: - break; - } - return 0; + if (skops->family != AF_INET && !ipv4_mapped_addr(skops->local_ip6)) + return 0; + switch (skops->op) { + case BPF_SOCK_OPS_TCP_CONNECT_CB: + if (conn_from_cni_sim_add(skops)) + record_ip(skops->local_ip4); + if (conn_from_cni_sim_delete(skops)) + remove_ip(skops->local_ip4); + break; + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + if (!is_managed_by_kmesh(skops->local_ip4)) // local ip4 is client ip + break; + if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) + BPF_LOG(ERR, SOCKOPS, "set sockops cb failed!\n"); + enable_encoding_metadata(skops); + break; + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + if (!is_managed_by_kmesh(skops->local_ip4)) // local ip4 is server ip + break; + if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) + BPF_LOG(ERR, SOCKOPS, "set sockops cb failed!\n"); + auth_ip_tuple(skops); + break; + case BPF_SOCK_OPS_STATE_CB: + if (skops->args[1] == BPF_TCP_CLOSE || skops->args[1] == BPF_TCP_CLOSE_WAIT + || skops->args[1] == BPF_TCP_FIN_WAIT1) { + clean_auth_map(skops); + clean_dstinfo_map(skops); + } + break; + default: + break; + } + return 0; } char _license[] SEC("license") = "GPL"; diff --git a/bpf/kmesh/workload/xdp.c b/bpf/kmesh/workload/xdp.c index fb5b254e8..7ec634e2a 100644 --- a/bpf/kmesh/workload/xdp.c +++ b/bpf/kmesh/workload/xdp.c @@ -25,10 +25,10 @@ #include "workload.h" #define AUTH_PASS 0 -#define AUTH_FORBID 1 +#define AUTH_FORBID 1 #define PARSER_FAILED 1 -#define PARSER_SUCC 0 +#define PARSER_SUCC 0 struct xdp_info { struct ethhdr *ethh; @@ -36,8 +36,7 @@ struct xdp_info { struct tcphdr *tcph; }; -static inline int get_hdr_ptr(struct xdp_md *ctx, struct ethhdr **ethh, - struct iphdr **iph, struct tcphdr **tcph) +static inline int get_hdr_ptr(struct xdp_md *ctx, struct ethhdr **ethh, struct iphdr **iph, struct tcphdr **tcph) { void *begin = (void *)(ctx->data); void *end = (void *)(ctx->data_end); @@ -57,7 +56,7 @@ static inline int get_hdr_ptr(struct xdp_md *ctx, struct ethhdr **ethh, *tcph = (struct tcphdr *)(*iph + 1); if ((void *)((*tcph) + 1) > end) return PARSER_FAILED; - + return PARSER_SUCC; } @@ -81,10 +80,13 @@ static inline void shutdown_tuple(struct xdp_info *info) static inline int should_shutdown(struct bpf_sock_tuple *tuple_info) { __u32 *value = bpf_map_lookup_elem(&map_of_auth, tuple_info); - if (value) - { - BPF_LOG(INFO, XDP, "auth denied, src ip: %u, port: %u\n", - bpf_ntohl(tuple_info->ipv4.saddr), bpf_ntohs(tuple_info->ipv4.sport)); + if (value) { + BPF_LOG( + INFO, + XDP, + "auth denied, src ip: %u, port: %u\n", + bpf_ntohl(tuple_info->ipv4.saddr), + bpf_ntohs(tuple_info->ipv4.sport)); bpf_map_delete_elem(&map_of_auth, tuple_info); return AUTH_FORBID; } @@ -107,9 +109,9 @@ int xdp_shutdown(struct xdp_md *ctx) // never failed parser_tuple(&info, &tuple_info); - if (should_shutdown(&tuple_info) == AUTH_FORBID) + if (should_shutdown(&tuple_info) == AUTH_FORBID) shutdown_tuple(&info); - + // If auth denied, it still returns XDP_PASS here, so next time when a client package is // sent to server, it will be shutdown since server's RST has been set return XDP_PASS; diff --git a/config/kmesh_marcos_def.h b/config/kmesh_marcos_def.h index d5a4cc478..4238080c0 100644 --- a/config/kmesh_marcos_def.h +++ b/config/kmesh_marcos_def.h @@ -14,34 +14,34 @@ * limitations under the License. */ -/* When the two ends use loopback addresses for communication, there is a - * low probability that link conflicts occur. The namespace cookie - * corresponding to each container is added to the hash key to avoid +/* When the two ends use loopback addresses for communication, there is a + * low probability that link conflicts occur. The namespace cookie + * corresponding to each container is added to the hash key to avoid * loopback address link conflicts. Obtains the namespace cookie of the * current container based on the bpf_get_netns_cookie auxiliary function. -*/ -#define MDA_LOOPBACK_ADDR 1 + */ +#define MDA_LOOPBACK_ADDR 1 -/* supports NAT acceleration. That is, acceleration can also be performed - * when iptables is used to forward traffic between service containers - * and sidecar containers. The bpf_sk_original_addr auxiliary function is +/* supports NAT acceleration. That is, acceleration can also be performed + * when iptables is used to forward traffic between service containers + * and sidecar containers. The bpf_sk_original_addr auxiliary function is * used to obtain the original destination address. -*/ -#define MDA_NAT_ACCEL 1 + */ +#define MDA_NAT_ACCEL 1 -/* supports acceleration function filtering based on GID and UID. - * That is, the GID or UID corresponding to the process to be accelerated - * is configured in the configuration file. The bpf_get_sockops_uid_gid - * auxiliary function is used to obtain the GID and UID of the current +/* supports acceleration function filtering based on GID and UID. + * That is, the GID or UID corresponding to the process to be accelerated + * is configured in the configuration file. The bpf_get_sockops_uid_gid + * auxiliary function is used to obtain the GID and UID of the current * process. -*/ -#define MDA_GID_UID_FILTER 1 + */ +#define MDA_GID_UID_FILTER 1 /* * openEuler-23.03 is an innovative version of openEuler, in the early time, we - * developed kmesh based on openEuler-23.03, and the implementation of kmesh - * was related to the openEuler-23.03 kernel. Now, the general implementation - * of kmesh differs from the previous openEuler-23.03 version, so we need to + * developed kmesh based on openEuler-23.03, and the implementation of kmesh + * was related to the openEuler-23.03 kernel. Now, the general implementation + * of kmesh differs from the previous openEuler-23.03 version, so we need to * use this macro to distinguish these differences. * The main differences between the general implementation of kmesh and the * openEuler-23.03 version are as follows: @@ -49,35 +49,35 @@ * 2. Use bpf__strncmp instead of bpf_strncmp for string comparison; * 3. Fix Port shift bug on openEuler-23.03.In the kernel network protocol * stack, the port is stored in u16, but in the bpf network module, the port - * is stored in u32. Therefore, after the endian conversion, the 16-bit port - * needs to be obtained from the 32-bit data structure. - * You need to find the position of the valid 16 bits. Generally, after the - * port is extended from 16 bits to 32 bits, the port is in the upper 16 - * bits after the endian conversion. Therefore, you need to offset the port - * before using the u16 RX port. In some specific kernels, the port stored + * is stored in u32. Therefore, after the endian conversion, the 16-bit port + * needs to be obtained from the 32-bit data structure. + * You need to find the position of the valid 16 bits. Generally, after the + * port is extended from 16 bits to 32 bits, the port is in the upper 16 + * bits after the endian conversion. Therefore, you need to offset the port + * before using the u16 RX port. In some specific kernels, the port stored * in sockops is in the lower 16 bits and does not need to be offset. */ -#define OE_23_03 0 +#define OE_23_03 0 /* * in kernel 6.x version, add the new iter type ITER_UBUF, and we need add code * for the corresponding scenarios. */ -#define ITER_TYPE_IS_UBUF 0 +#define ITER_TYPE_IS_UBUF 0 /* * Kmesh’s Layer 7 acceleration proxy capability relies on kernel enhancements. * It’s necessary to determine whether the current environment has an * enhanced kernel in order to enable Kmesh’s capabilities. */ -#define ENHANCED_KERNEL 0 +#define ENHANCED_KERNEL 0 /* - * Different versions of libbpf can be installed in different environments, - * and there are some incompatibilities in the function interfaces provided - * by different versions of libbpf. Considering compatibility issues, a new - * compilation macro is added. The value of this macro is set according to + * Different versions of libbpf can be installed in different environments, + * and there are some incompatibilities in the function interfaces provided + * by different versions of libbpf. Considering compatibility issues, a new + * compilation macro is added. The value of this macro is set according to * the libbpf version in the current environment, and the code in the project * is enabled accordingly. * */ -#define LIBBPF_HIGHER_0_6_0_VERSION 0 +#define LIBBPF_HIGHER_0_6_0_VERSION 0 diff --git a/depends/include/bpf_helper_defs_ext.h b/depends/include/bpf_helper_defs_ext.h index 330efe220..2af4cbc69 100644 --- a/depends/include/bpf_helper_defs_ext.h +++ b/depends/include/bpf_helper_defs_ext.h @@ -21,11 +21,11 @@ * functions will also be added here in the future. * * 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 long (*bpf_parse_header_msg)(struct bpf_mem_ptr *msg) = (void *)175; static void *(*bpf_get_msg_header_element)(void *name) = (void *)176; diff --git a/hack/format.sh b/hack/format.sh new file mode 100755 index 000000000..6929d9870 --- /dev/null +++ b/hack/format.sh @@ -0,0 +1,22 @@ +#!/bin/bash + + +function install_tool () { + tool=${1} + if command -v apt > /dev/null; then + sudo apt-get install -y $tool + elif command -v yum > /dev/null; then + # yum install + sudo yum install -y $tool + fi +} + +function install_clang_format () { + if command -v clang-format > /dev/null; then + echo "clang-format already installed" + else + install_tool clang-format + fi +} + +find ./ -path "./api/v2-c" -prune -o -name "*.[ch]" -exec clang-format -i {} \; \ No newline at end of file diff --git a/kernel/ko_src/kmesh/defer_connect.c b/kernel/ko_src/kmesh/defer_connect.c index 64554d49f..ef592543c 100644 --- a/kernel/ko_src/kmesh/defer_connect.c +++ b/kernel/ko_src/kmesh/defer_connect.c @@ -30,187 +30,189 @@ static struct proto *kmesh_defer_proto = NULL; static int defer_connect(struct sock *sk, struct msghdr *msg, size_t size) { - struct bpf_mem_ptr tmpMem = {0}; - void *kbuf = NULL; - size_t kbuf_size; - struct sockaddr_in addr_in; - long timeo = 1; - const struct iovec *iov; - struct bpf_sock_ops_kern sock_ops; - void __user *ubase; - int err; - u32 dport, daddr; - dport = sk->sk_dport; - daddr = sk->sk_daddr; - - if (iov_iter_is_kvec(&msg->msg_iter)) { - iov = (struct iovec *)msg->msg_iter.kvec; - ubase = iov->iov_base; - kbuf_size = iov->iov_len; - } else if (iter_is_iovec(&msg->msg_iter)) { - iov = msg->msg_iter.iov; - ubase = iov->iov_base; - kbuf_size = iov->iov_len; + struct bpf_mem_ptr tmpMem = {0}; + void *kbuf = NULL; + size_t kbuf_size; + struct sockaddr_in addr_in; + long timeo = 1; + const struct iovec *iov; + struct bpf_sock_ops_kern sock_ops; + void __user *ubase; + int err; + u32 dport, daddr; + dport = sk->sk_dport; + daddr = sk->sk_daddr; + + if (iov_iter_is_kvec(&msg->msg_iter)) { + iov = (struct iovec *)msg->msg_iter.kvec; + ubase = iov->iov_base; + kbuf_size = iov->iov_len; + } else if (iter_is_iovec(&msg->msg_iter)) { + iov = msg->msg_iter.iov; + ubase = iov->iov_base; + kbuf_size = iov->iov_len; #if ITER_TYPE_IS_UBUF - } else if (iter_is_ubuf(&msg->msg_iter)){ - ubase = msg->msg_iter.ubuf; - kbuf_size = msg->msg_iter.count; + } else if (iter_is_ubuf(&msg->msg_iter)) { + ubase = msg->msg_iter.ubuf; + kbuf_size = msg->msg_iter.count; #endif - } else - goto connect; + } else + goto connect; - kbuf = (void *)kmalloc(kbuf_size, GFP_KERNEL); - if (!kbuf) - return -EFAULT; + kbuf = (void *)kmalloc(kbuf_size, GFP_KERNEL); + if (!kbuf) + return -EFAULT; - if (copy_from_user(kbuf, ubase, kbuf_size)) { - err = -EFAULT; - goto out; - } - tmpMem.size = kbuf_size; - tmpMem.ptr = kbuf; + if (copy_from_user(kbuf, ubase, kbuf_size)) { + err = -EFAULT; + goto out; + } + tmpMem.size = kbuf_size; + tmpMem.ptr = kbuf; #if OE_23_03 - tcp_call_bpf_3arg(sk, BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB, - ((u64)(&tmpMem) & U32_MAX), - (((u64)(&tmpMem) >> 32) & U32_MAX), kbuf_size); - daddr = sk->sk_daddr; - dport = sk->sk_dport; + tcp_call_bpf_3arg( + sk, + BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB, + ((u64)(&tmpMem) & U32_MAX), + (((u64)(&tmpMem) >> 32) & U32_MAX), + kbuf_size); + daddr = sk->sk_daddr; + dport = sk->sk_dport; #else - memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); - if (sk_fullsock(sk)) { - sock_ops.is_fullsock = 1; - sock_owned_by_me(sk); - } - sock_ops.sk = sk; - sock_ops.op = BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB; - sock_ops.args[0] = ((u64)(&tmpMem) & U32_MAX); - sock_ops.args[1] = (((u64)(&tmpMem) >> 32) & U32_MAX); - - (void)BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops); - if (sock_ops.replylong[2] && sock_ops.replylong[3]) { - daddr = sock_ops.replylong[2]; - dport = sock_ops.replylong[3]; - } + memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); + if (sk_fullsock(sk)) { + sock_ops.is_fullsock = 1; + sock_owned_by_me(sk); + } + sock_ops.sk = sk; + sock_ops.op = BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB; + sock_ops.args[0] = ((u64)(&tmpMem) & U32_MAX); + sock_ops.args[1] = (((u64)(&tmpMem) >> 32) & U32_MAX); + + (void)BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops); + if (sock_ops.replylong[2] && sock_ops.replylong[3]) { + daddr = sock_ops.replylong[2]; + dport = sock_ops.replylong[3]; + } #endif connect: - addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = daddr; - addr_in.sin_port = dport; - err = sk->sk_prot->connect(sk, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in)); - inet_sk(sk)->bpf_defer_connect = 0; - if (unlikely(err)) { - tcp_set_state(sk, TCP_CLOSE); - sk->sk_route_caps = 0; - inet_sk(sk)->inet_dport = 0; - goto out; - } - - if ((((__u32)1 << sk->sk_state) & ~(__u32)(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) - && !tcp_passive_fastopen(sk)) { - sk_stream_wait_connect(sk, &timeo); - } + addr_in.sin_family = AF_INET; + addr_in.sin_addr.s_addr = daddr; + addr_in.sin_port = dport; + err = sk->sk_prot->connect(sk, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in)); + inet_sk(sk)->bpf_defer_connect = 0; + if (unlikely(err)) { + tcp_set_state(sk, TCP_CLOSE); + sk->sk_route_caps = 0; + inet_sk(sk)->inet_dport = 0; + goto out; + } + + if ((((__u32)1 << sk->sk_state) & ~(__u32)(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && !tcp_passive_fastopen(sk)) { + sk_stream_wait_connect(sk, &timeo); + } out: - kfree(kbuf); - return err; + kfree(kbuf); + return err; } static int defer_connect_and_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { - struct socket *sock; - int err = 0; - - if (unlikely(inet_sk(sk)->bpf_defer_connect == 1)) { - lock_sock(sk); - inet_sk(sk)->defer_connect = 0; - - err = defer_connect(sk, msg, size); - if (err) { - release_sock(sk); - return -EAGAIN; - } - - sock = sk->sk_socket; - if (sock->ops->sendmsg_locked) - err = sock->ops->sendmsg_locked(sk, msg, size); - release_sock(sk); - } - return err; + struct socket *sock; + int err = 0; + + if (unlikely(inet_sk(sk)->bpf_defer_connect == 1)) { + lock_sock(sk); + inet_sk(sk)->defer_connect = 0; + + err = defer_connect(sk, msg, size); + if (err) { + release_sock(sk); + return -EAGAIN; + } + + sock = sk->sk_socket; + if (sock->ops->sendmsg_locked) + err = sock->ops->sendmsg_locked(sk, msg, size); + release_sock(sk); + } + return err; } static int defer_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { - int ret; + int ret; - ret = defer_connect_and_sendmsg(sk, msg, size); - if (ret) - return ret; + ret = defer_connect_and_sendmsg(sk, msg, size); + if (ret) + return ret; - return tcp_sendmsg(sk, msg, size); + return tcp_sendmsg(sk, msg, 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 - * epoll to be triggered normally. - */ - if (inet_sk(sk)->defer_connect == 1) - return -ENOTSUPP; - /* bpf_defer_connect is 0 when you first enter the connection. - * When you delay link establishment from sendmsg, the value - * of bpf_defer_connect should be 1 and the normal connect function - * needs to be used. - */ - if (inet_sk(sk)->bpf_defer_connect) - return tcp_v4_connect(sk, uaddr, addr_len); - inet_sk(sk)->bpf_defer_connect = 1; - inet_sk(sk)->defer_connect = 1; - sk->sk_dport = ((struct sockaddr_in *)uaddr)->sin_port; - sk_daddr_set(sk, ((struct sockaddr_in *)uaddr)->sin_addr.s_addr); - sk->sk_socket->state = SS_CONNECTING; - tcp_set_state(sk, TCP_SYN_SENT); - return KMESH_DELAY_ERROR; + /* 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. + */ + if (inet_sk(sk)->defer_connect == 1) + return -ENOTSUPP; + /* bpf_defer_connect is 0 when you first enter the connection. + * When you delay link establishment from sendmsg, the value + * of bpf_defer_connect should be 1 and the normal connect function + * needs to be used. + */ + if (inet_sk(sk)->bpf_defer_connect) + return tcp_v4_connect(sk, uaddr, addr_len); + inet_sk(sk)->bpf_defer_connect = 1; + inet_sk(sk)->defer_connect = 1; + sk->sk_dport = ((struct sockaddr_in *)uaddr)->sin_port; + sk_daddr_set(sk, ((struct sockaddr_in *)uaddr)->sin_addr.s_addr); + sk->sk_socket->state = SS_CONNECTING; + tcp_set_state(sk, TCP_SYN_SENT); + return KMESH_DELAY_ERROR; } static int kmesh_build_proto(struct sock *sk) { - if (sk->sk_family != AF_INET) - return 0; - WRITE_ONCE(sk->sk_prot, kmesh_defer_proto); - return 0; + if (sk->sk_family != AF_INET) + return 0; + WRITE_ONCE(sk->sk_prot, kmesh_defer_proto); + return 0; } static int kmesh_defer_init(struct sock *sk) { - kmesh_build_proto(sk); - return 0; + kmesh_build_proto(sk); + return 0; } static struct tcp_ulp_ops kmesh_defer_ulp_ops __read_mostly = { - .name = "kmesh_defer", - .owner = THIS_MODULE, - .init = kmesh_defer_init, + .name = "kmesh_defer", + .owner = THIS_MODULE, + .init = kmesh_defer_init, }; int __init defer_conn_init(void) { - kmesh_defer_proto = kmalloc(sizeof(struct proto), GFP_ATOMIC); - if (!kmesh_defer_proto) - return -ENOMEM; - *kmesh_defer_proto = tcp_prot; - kmesh_defer_proto->connect = defer_tcp_connect; - kmesh_defer_proto->sendmsg = defer_tcp_sendmsg; - tcp_register_ulp(&kmesh_defer_ulp_ops); - return 0; + kmesh_defer_proto = kmalloc(sizeof(struct proto), GFP_ATOMIC); + if (!kmesh_defer_proto) + return -ENOMEM; + *kmesh_defer_proto = tcp_prot; + kmesh_defer_proto->connect = defer_tcp_connect; + kmesh_defer_proto->sendmsg = defer_tcp_sendmsg; + tcp_register_ulp(&kmesh_defer_ulp_ops); + return 0; } void __exit defer_conn_exit(void) { - tcp_unregister_ulp(&kmesh_defer_ulp_ops); - if (kmesh_defer_proto) - kfree(kmesh_defer_proto); + tcp_unregister_ulp(&kmesh_defer_ulp_ops); + if (kmesh_defer_proto) + kfree(kmesh_defer_proto); } MODULE_LICENSE("GPL"); diff --git a/kernel/ko_src/kmesh/defer_connect.h b/kernel/ko_src/kmesh/defer_connect.h index bce87d04b..445593bde 100644 --- a/kernel/ko_src/kmesh/defer_connect.h +++ b/kernel/ko_src/kmesh/defer_connect.h @@ -14,5 +14,4 @@ int __init defer_conn_init(void); void __exit defer_conn_exit(void); - -#endif /* KMESH_DEFER_CONN_H */ +#endif /* KMESH_DEFER_CONN_H */ diff --git a/kernel/ko_src/kmesh/kmesh_main.c b/kernel/ko_src/kmesh/kmesh_main.c index 7befc778c..6c148b88f 100644 --- a/kernel/ko_src/kmesh/kmesh_main.c +++ b/kernel/ko_src/kmesh/kmesh_main.c @@ -23,24 +23,24 @@ static int __init kmesh_init(void) { - int ret; + int ret; - ret = defer_conn_init(); - if (ret) - return ret; + ret = defer_conn_init(); + if (ret) + return ret; - ret = proto_common_init(); - if (ret) - return ret; + ret = proto_common_init(); + if (ret) + return ret; - ret = kmesh_register_http_1_1_init(); - return ret; + ret = kmesh_register_http_1_1_init(); + return ret; } static void __exit kmesh_exit(void) { - defer_conn_exit(); - proto_common_exit(); + defer_conn_exit(); + proto_common_exit(); } module_init(kmesh_init); diff --git a/kernel/ko_src/kmesh/kmesh_parse_http_1_1.c b/kernel/ko_src/kmesh/kmesh_parse_http_1_1.c index e861949ab..2789cd8eb 100644 --- a/kernel/ko_src/kmesh/kmesh_parse_http_1_1.c +++ b/kernel/ko_src/kmesh/kmesh_parse_http_1_1.c @@ -9,427 +9,429 @@ */ #include "kmesh_parse_http_1_1.h" -#define LF (char)'\n' -#define CR (char)'\r' +#define LF (char)'\n' +#define CR (char)'\r' #define FIELD_SPLIT ':' -#define SPACE ' ' +#define SPACE ' ' -#define METHOD_STRING_LENGTH 7 -#define URI_STRING_LENGTH 4 +#define METHOD_STRING_LENGTH 7 +#define URI_STRING_LENGTH 4 #define VERSION_STRING_LENGTH 8 -#define STATUS_STRING_LENGTH 7 -#define REASON_STRING_LENGTH 7 +#define STATUS_STRING_LENGTH 7 +#define REASON_STRING_LENGTH 7 enum state { - ST_START, - ST_VERSION, - ST_NEW_LINE, - // request - ST_METHOD, - ST_SPACE_BEFORE_URI, - ST_URI, - ST_SPACE_BEFORE_VERSION, - // respose - ST_SPACE_BEFORE_STATUS_CODE, - ST_STATUS_CODE, - ST_SPACE_BEFORE_REASON, - ST_REASON, - // field - ST_FIELD_NAME_START, - ST_FIELD_NAME, - ST_FIELD_VALUE_START, - ST_FIELD_VALUE, - ST_HEAD_END + ST_START, + ST_VERSION, + ST_NEW_LINE, + // request + ST_METHOD, + ST_SPACE_BEFORE_URI, + ST_URI, + ST_SPACE_BEFORE_VERSION, + // respose + ST_SPACE_BEFORE_STATUS_CODE, + ST_STATUS_CODE, + ST_SPACE_BEFORE_REASON, + ST_REASON, + // field + ST_FIELD_NAME_START, + ST_FIELD_NAME, + ST_FIELD_VALUE_START, + ST_FIELD_VALUE, + ST_HEAD_END }; u32 parse_http_1_1_request(const struct bpf_mem_ptr *msg); u32 parse_http_1_1_respond(const struct bpf_mem_ptr *msg); - -static enum state __parse_request_startline(const struct bpf_mem_ptr *msg, - struct bpf_mem_ptr *context, - struct kmesh_data_node *method, - struct kmesh_data_node *URI, - struct kmesh_data_node *http_version) +static enum state __parse_request_startline( + const struct bpf_mem_ptr *msg, + struct bpf_mem_ptr *context, + struct kmesh_data_node *method, + struct kmesh_data_node *URI, + struct kmesh_data_node *http_version) { - enum state current_state = ST_START; - u32 start = 0; - char *pstart = NULL; - bool end_parse_startline = false; - u32 i; - char ch; - - for (i = 0; !end_parse_startline && i < msg->size; ++i) { - ch = ((char *)msg->ptr)[i]; - switch (current_state) { - case ST_START: - if ((ch < 'A' || ch > 'Z')) { - goto failed; - } - start = i; - pstart = (char *)msg->ptr; - current_state = ST_METHOD; - break; - case ST_METHOD: - if (ch == SPACE) { - method->value.ptr = pstart; - method->value.size = i - start; - (void)strncpy(method->keystring, "METHOD", METHOD_STRING_LENGTH); - current_state = ST_SPACE_BEFORE_URI; - break; - } - if (ch < 'A' || ch > 'Z') - goto failed; - break; - case ST_SPACE_BEFORE_URI: - pstart = msg->ptr + i; - start = i; - current_state = ST_URI; - break; - case ST_URI: - if (ch == SPACE) { - URI->value.ptr = pstart; - URI->value.size = i - start; - (void)strncpy(URI->keystring, "URI", URI_STRING_LENGTH); - current_state = ST_SPACE_BEFORE_VERSION; - } - break; - case ST_SPACE_BEFORE_VERSION: - pstart = msg->ptr + i; - start = i; - current_state = ST_VERSION; - break; - case ST_VERSION: - if (unlikely(ch == CR)) { - http_version->value.ptr = pstart; - http_version->value.size = i - start; - if (strncmp((char *)http_version->value.ptr, "HTTP/1.1", strlen("HTTP/1.1"))) - goto failed; - (void)strncpy(http_version->keystring, "VERSION", VERSION_STRING_LENGTH); - current_state = ST_NEW_LINE; - } - break; - case ST_NEW_LINE: - if (unlikely(ch != LF)) - goto failed; - current_state = ST_FIELD_NAME_START; - break; - case ST_FIELD_NAME_START: - context->ptr = msg->ptr + i; - context->size = msg->size - i; - end_parse_startline = true; - break; - default: - // It's not going to get here - break; - } - } + enum state current_state = ST_START; + u32 start = 0; + char *pstart = NULL; + bool end_parse_startline = false; + u32 i; + char ch; + + for (i = 0; !end_parse_startline && i < msg->size; ++i) { + ch = ((char *)msg->ptr)[i]; + switch (current_state) { + case ST_START: + if ((ch < 'A' || ch > 'Z')) { + goto failed; + } + start = i; + pstart = (char *)msg->ptr; + current_state = ST_METHOD; + break; + case ST_METHOD: + if (ch == SPACE) { + method->value.ptr = pstart; + method->value.size = i - start; + (void)strncpy(method->keystring, "METHOD", METHOD_STRING_LENGTH); + current_state = ST_SPACE_BEFORE_URI; + break; + } + if (ch < 'A' || ch > 'Z') + goto failed; + break; + case ST_SPACE_BEFORE_URI: + pstart = msg->ptr + i; + start = i; + current_state = ST_URI; + break; + case ST_URI: + if (ch == SPACE) { + URI->value.ptr = pstart; + URI->value.size = i - start; + (void)strncpy(URI->keystring, "URI", URI_STRING_LENGTH); + current_state = ST_SPACE_BEFORE_VERSION; + } + break; + case ST_SPACE_BEFORE_VERSION: + pstart = msg->ptr + i; + start = i; + current_state = ST_VERSION; + break; + case ST_VERSION: + if (unlikely(ch == CR)) { + http_version->value.ptr = pstart; + http_version->value.size = i - start; + if (strncmp((char *)http_version->value.ptr, "HTTP/1.1", strlen("HTTP/1.1"))) + goto failed; + (void)strncpy(http_version->keystring, "VERSION", VERSION_STRING_LENGTH); + current_state = ST_NEW_LINE; + } + break; + case ST_NEW_LINE: + if (unlikely(ch != LF)) + goto failed; + current_state = ST_FIELD_NAME_START; + break; + case ST_FIELD_NAME_START: + context->ptr = msg->ptr + i; + context->size = msg->size - i; + end_parse_startline = true; + break; + default: + // It's not going to get here + break; + } + } failed: - return current_state; + return current_state; } static bool parse_request_startline(const struct bpf_mem_ptr *msg, struct bpf_mem_ptr *context) { - enum state current_state; - struct kmesh_data_node *method = new_kmesh_data_node(METHOD_STRING_LENGTH); - struct kmesh_data_node *URI = new_kmesh_data_node(URI_STRING_LENGTH); - struct kmesh_data_node *http_version = new_kmesh_data_node(VERSION_STRING_LENGTH); - - if (IS_ERR(method) || IS_ERR(URI) || IS_ERR(http_version)) - goto failed; - - current_state = __parse_request_startline(msg, context, method, URI, http_version); - if (current_state != ST_FIELD_NAME_START) - goto failed; - if (!kmesh_protocol_data_insert(method)) - delete_kmesh_data_node(&method); // the value inserted before prevails. - if (!kmesh_protocol_data_insert(URI)) - delete_kmesh_data_node(&URI); - if (!kmesh_protocol_data_insert(http_version)) - delete_kmesh_data_node(&http_version); - - return true; + enum state current_state; + struct kmesh_data_node *method = new_kmesh_data_node(METHOD_STRING_LENGTH); + struct kmesh_data_node *URI = new_kmesh_data_node(URI_STRING_LENGTH); + struct kmesh_data_node *http_version = new_kmesh_data_node(VERSION_STRING_LENGTH); + + if (IS_ERR(method) || IS_ERR(URI) || IS_ERR(http_version)) + goto failed; + + current_state = __parse_request_startline(msg, context, method, URI, http_version); + if (current_state != ST_FIELD_NAME_START) + goto failed; + if (!kmesh_protocol_data_insert(method)) + delete_kmesh_data_node(&method); // the value inserted before prevails. + if (!kmesh_protocol_data_insert(URI)) + delete_kmesh_data_node(&URI); + if (!kmesh_protocol_data_insert(http_version)) + delete_kmesh_data_node(&http_version); + + return true; failed: - delete_kmesh_data_node(&method); - delete_kmesh_data_node(&URI); - delete_kmesh_data_node(&http_version); - return false; + delete_kmesh_data_node(&method); + delete_kmesh_data_node(&URI); + delete_kmesh_data_node(&http_version); + return false; } -static enum state __parse_respose_startline(const struct bpf_mem_ptr *msg, - struct bpf_mem_ptr *context, - struct kmesh_data_node *http_version, - struct kmesh_data_node *status_code, - struct kmesh_data_node *reason) +static enum state __parse_respose_startline( + const struct bpf_mem_ptr *msg, + struct bpf_mem_ptr *context, + struct kmesh_data_node *http_version, + struct kmesh_data_node *status_code, + struct kmesh_data_node *reason) { - enum state current_state = ST_START; - u32 start = 0; - char *pstart = NULL; - bool end_parse_startline = false; - u32 i; - char ch; - - for (i = 0; !end_parse_startline && i < msg->size; ++i) { - ch = ((char *)msg->ptr)[i]; - switch(current_state) { - case ST_START: - if (ch != 'H') - goto failed; - start = i; - pstart = (char *)msg->ptr; - current_state = ST_VERSION; - break; - case ST_VERSION: - if (ch == SPACE) { - http_version->value.ptr = pstart; - http_version->value.size = i - start; - if (strncmp((char *)http_version->value.ptr, "HTTP/1.1", strlen("HTTP/1.1"))) - goto failed; - (void)strncpy(http_version->keystring, "VERSION", VERSION_STRING_LENGTH); - current_state = ST_SPACE_BEFORE_STATUS_CODE; - } - break; - case ST_SPACE_BEFORE_STATUS_CODE: - if (ch < '0' || ch > '9') - goto failed; - pstart = msg->ptr + i; - start = i; - current_state = ST_STATUS_CODE; - break; - case ST_STATUS_CODE: - if (ch < '0' || ch > '9') - goto failed; - if (ch == SPACE) { - status_code->value.ptr = pstart; - status_code->value.size = i - start; - (void)strncpy(status_code->keystring, "STATUS", STATUS_STRING_LENGTH); - current_state = ST_SPACE_BEFORE_REASON; - } - break; - case ST_SPACE_BEFORE_REASON: - pstart = msg->ptr + i; - start = i; - current_state = ST_REASON; - break; - case ST_REASON: - if (ch == LF) { - reason->value.ptr = pstart; - reason->value.size = i - start; - (void)strncpy(reason->keystring, "REASON", REASON_STRING_LENGTH); - current_state = ST_NEW_LINE; - } - break; - case ST_NEW_LINE: - if (unlikely(ch != LF)) - goto failed; - current_state = ST_FIELD_NAME_START; - break; - case ST_FIELD_NAME_START: - context->ptr = msg->ptr + i; - context->size = msg->size - i; - end_parse_startline = true; - break; - default: - // It's not going to get here - break; - } - } + enum state current_state = ST_START; + u32 start = 0; + char *pstart = NULL; + bool end_parse_startline = false; + u32 i; + char ch; + + for (i = 0; !end_parse_startline && i < msg->size; ++i) { + ch = ((char *)msg->ptr)[i]; + switch (current_state) { + case ST_START: + if (ch != 'H') + goto failed; + start = i; + pstart = (char *)msg->ptr; + current_state = ST_VERSION; + break; + case ST_VERSION: + if (ch == SPACE) { + http_version->value.ptr = pstart; + http_version->value.size = i - start; + if (strncmp((char *)http_version->value.ptr, "HTTP/1.1", strlen("HTTP/1.1"))) + goto failed; + (void)strncpy(http_version->keystring, "VERSION", VERSION_STRING_LENGTH); + current_state = ST_SPACE_BEFORE_STATUS_CODE; + } + break; + case ST_SPACE_BEFORE_STATUS_CODE: + if (ch < '0' || ch > '9') + goto failed; + pstart = msg->ptr + i; + start = i; + current_state = ST_STATUS_CODE; + break; + case ST_STATUS_CODE: + if (ch < '0' || ch > '9') + goto failed; + if (ch == SPACE) { + status_code->value.ptr = pstart; + status_code->value.size = i - start; + (void)strncpy(status_code->keystring, "STATUS", STATUS_STRING_LENGTH); + current_state = ST_SPACE_BEFORE_REASON; + } + break; + case ST_SPACE_BEFORE_REASON: + pstart = msg->ptr + i; + start = i; + current_state = ST_REASON; + break; + case ST_REASON: + if (ch == LF) { + reason->value.ptr = pstart; + reason->value.size = i - start; + (void)strncpy(reason->keystring, "REASON", REASON_STRING_LENGTH); + current_state = ST_NEW_LINE; + } + break; + case ST_NEW_LINE: + if (unlikely(ch != LF)) + goto failed; + current_state = ST_FIELD_NAME_START; + break; + case ST_FIELD_NAME_START: + context->ptr = msg->ptr + i; + context->size = msg->size - i; + end_parse_startline = true; + break; + default: + // It's not going to get here + break; + } + } failed: - return current_state; + return current_state; } static bool parse_respose_startline(const struct bpf_mem_ptr *msg, struct bpf_mem_ptr *context) { - enum state current_state; - struct kmesh_data_node *http_version = new_kmesh_data_node(VERSION_STRING_LENGTH); - struct kmesh_data_node *status_code = new_kmesh_data_node(STATUS_STRING_LENGTH); - struct kmesh_data_node *reason = new_kmesh_data_node(REASON_STRING_LENGTH); - - if (IS_ERR(http_version) || IS_ERR(status_code) || IS_ERR(reason)) - goto failed; - - current_state = __parse_respose_startline(msg, context, http_version, status_code, reason); - if (current_state != ST_FIELD_NAME_START) - goto failed; - if (!kmesh_protocol_data_insert(http_version)) - delete_kmesh_data_node(&http_version); - if (!kmesh_protocol_data_insert(status_code)) - delete_kmesh_data_node(&status_code); - if (!kmesh_protocol_data_insert(reason)) - delete_kmesh_data_node(&reason); - - return true; + enum state current_state; + struct kmesh_data_node *http_version = new_kmesh_data_node(VERSION_STRING_LENGTH); + struct kmesh_data_node *status_code = new_kmesh_data_node(STATUS_STRING_LENGTH); + struct kmesh_data_node *reason = new_kmesh_data_node(REASON_STRING_LENGTH); + + if (IS_ERR(http_version) || IS_ERR(status_code) || IS_ERR(reason)) + goto failed; + + current_state = __parse_respose_startline(msg, context, http_version, status_code, reason); + if (current_state != ST_FIELD_NAME_START) + goto failed; + if (!kmesh_protocol_data_insert(http_version)) + delete_kmesh_data_node(&http_version); + if (!kmesh_protocol_data_insert(status_code)) + delete_kmesh_data_node(&status_code); + if (!kmesh_protocol_data_insert(reason)) + delete_kmesh_data_node(&reason); + + return true; failed: - delete_kmesh_data_node(&http_version); - delete_kmesh_data_node(&status_code); - delete_kmesh_data_node(&reason); - return false; + delete_kmesh_data_node(&http_version); + delete_kmesh_data_node(&status_code); + delete_kmesh_data_node(&reason); + return false; } static bool parse_header(struct bpf_mem_ptr *context) { - enum state current_state = ST_FIELD_NAME_START; - bool head_end = false; - u32 field_name_begin_position = 0; - u32 field_name_end_position = 0; - u32 field_value_begin_position = 0; - u32 field_value_end_position = 0; - u32 i; - char ch; - struct kmesh_data_node *old_field = NULL; - struct kmesh_data_node *new_field = NULL; - for (i = 0; !head_end && i < context->size; ++i) { - ch = ((char *)context->ptr)[i]; - switch(current_state) { - case ST_FIELD_NAME_START: - if (ch == FIELD_SPLIT) - return false; - if (ch == CR) { - current_state = ST_HEAD_END; - break; - } - if (ch == SPACE) - continue; - field_name_begin_position = i; - field_name_end_position = i; - current_state = ST_FIELD_NAME; - break; - case ST_FIELD_NAME: - if (ch != SPACE && ch != FIELD_SPLIT) - field_name_end_position = i; - if (ch == FIELD_SPLIT) - current_state = ST_FIELD_VALUE_START; - break; - case ST_FIELD_VALUE_START: - if (ch == SPACE) - continue; - field_value_begin_position = i; - field_value_end_position = i; - if (ch == CR) - current_state = ST_NEW_LINE; - else - current_state = ST_FIELD_VALUE; - break; - case ST_FIELD_VALUE: - if (ch != SPACE) - field_value_end_position = i; - - if (unlikely(ch == CR)) - current_state = ST_NEW_LINE; - break; - case ST_NEW_LINE: - if (unlikely(ch != LF)) - return false; - if (field_name_end_position < field_name_begin_position) - return false; - if (field_value_end_position < field_value_begin_position) - return false; - new_field = new_kmesh_data_node(field_name_end_position - field_name_begin_position + 2); - if (IS_ERR(new_field)) - return false; - (void)strncpy(new_field->keystring, ((char *)context->ptr) + field_name_begin_position, - field_name_end_position - field_name_begin_position + 1); - old_field = kmesh_protocol_data_search(new_field->keystring); - if (unlikely(old_field)) { - old_field->value.ptr = context->ptr + field_value_begin_position; - old_field->value.size = field_value_end_position - field_value_begin_position; - delete_kmesh_data_node(&new_field); - old_field = NULL; - } else { - new_field->value.ptr = context->ptr + field_value_begin_position; - new_field->value.size = field_value_end_position - field_value_begin_position; - - if (!kmesh_protocol_data_insert(new_field)) { - delete_kmesh_data_node(&new_field); - break; - } - new_field = NULL; - } - current_state = ST_FIELD_NAME_START; - break; - case ST_HEAD_END: - if (ch != LF) - return false; - head_end = true; - break; - default: - // It's not going to get here - break; - } - } - if (current_state != ST_HEAD_END) - return false; - - return true; + enum state current_state = ST_FIELD_NAME_START; + bool head_end = false; + u32 field_name_begin_position = 0; + u32 field_name_end_position = 0; + u32 field_value_begin_position = 0; + u32 field_value_end_position = 0; + u32 i; + char ch; + struct kmesh_data_node *old_field = NULL; + struct kmesh_data_node *new_field = NULL; + for (i = 0; !head_end && i < context->size; ++i) { + ch = ((char *)context->ptr)[i]; + switch (current_state) { + case ST_FIELD_NAME_START: + if (ch == FIELD_SPLIT) + return false; + if (ch == CR) { + current_state = ST_HEAD_END; + break; + } + if (ch == SPACE) + continue; + field_name_begin_position = i; + field_name_end_position = i; + current_state = ST_FIELD_NAME; + break; + case ST_FIELD_NAME: + if (ch != SPACE && ch != FIELD_SPLIT) + field_name_end_position = i; + if (ch == FIELD_SPLIT) + current_state = ST_FIELD_VALUE_START; + break; + case ST_FIELD_VALUE_START: + if (ch == SPACE) + continue; + field_value_begin_position = i; + field_value_end_position = i; + if (ch == CR) + current_state = ST_NEW_LINE; + else + current_state = ST_FIELD_VALUE; + break; + case ST_FIELD_VALUE: + if (ch != SPACE) + field_value_end_position = i; + + if (unlikely(ch == CR)) + current_state = ST_NEW_LINE; + break; + case ST_NEW_LINE: + if (unlikely(ch != LF)) + return false; + if (field_name_end_position < field_name_begin_position) + return false; + if (field_value_end_position < field_value_begin_position) + return false; + new_field = new_kmesh_data_node(field_name_end_position - field_name_begin_position + 2); + if (IS_ERR(new_field)) + return false; + (void)strncpy( + new_field->keystring, + ((char *)context->ptr) + field_name_begin_position, + field_name_end_position - field_name_begin_position + 1); + old_field = kmesh_protocol_data_search(new_field->keystring); + if (unlikely(old_field)) { + old_field->value.ptr = context->ptr + field_value_begin_position; + old_field->value.size = field_value_end_position - field_value_begin_position; + delete_kmesh_data_node(&new_field); + old_field = NULL; + } else { + new_field->value.ptr = context->ptr + field_value_begin_position; + new_field->value.size = field_value_end_position - field_value_begin_position; + + if (!kmesh_protocol_data_insert(new_field)) { + delete_kmesh_data_node(&new_field); + break; + } + new_field = NULL; + } + current_state = ST_FIELD_NAME_START; + break; + case ST_HEAD_END: + if (ch != LF) + return false; + head_end = true; + break; + default: + // It's not going to get here + break; + } + } + if (current_state != ST_HEAD_END) + return false; + + return true; } u32 parse_http_1_1_request(const struct bpf_mem_ptr *msg) { - struct bpf_mem_ptr context = {0}; - u32 ret = 0; - if (parse_request_startline(msg, &context) == false) { - kmesh_protocol_data_clean_all(); - return PROTO_UNKNOW; - } - - // Parse the rest of the header - if (parse_header(&context) == false) { - kmesh_protocol_data_clean_all(); - return PROTO_UNKNOW; - } - - SET_RET_PROTO_TYPE(ret, PROTO_HTTP_1_1); - SET_RET_MSG_TYPE(ret, MSG_REQUEST); - - return ret; + struct bpf_mem_ptr context = {0}; + u32 ret = 0; + if (parse_request_startline(msg, &context) == false) { + kmesh_protocol_data_clean_all(); + return PROTO_UNKNOW; + } + + // Parse the rest of the header + if (parse_header(&context) == false) { + kmesh_protocol_data_clean_all(); + return PROTO_UNKNOW; + } + + SET_RET_PROTO_TYPE(ret, PROTO_HTTP_1_1); + SET_RET_MSG_TYPE(ret, MSG_REQUEST); + + return ret; } u32 parse_http_1_1_respond(const struct bpf_mem_ptr *msg) { - struct bpf_mem_ptr context = {0}; - u32 ret = 0; - if (parse_respose_startline(msg, &context) == false) { - kmesh_protocol_data_clean_all(); - return PROTO_UNKNOW; - } - - // Parse the rest of the header - if (parse_header(&context) == false) { - kmesh_protocol_data_clean_all(); - return PROTO_UNKNOW; - } - - SET_RET_PROTO_TYPE(ret, PROTO_HTTP_1_1); - SET_RET_MSG_TYPE(ret, MSG_FINAL_RESPONSE); - - return ret; + struct bpf_mem_ptr context = {0}; + u32 ret = 0; + if (parse_respose_startline(msg, &context) == false) { + kmesh_protocol_data_clean_all(); + return PROTO_UNKNOW; + } + + // Parse the rest of the header + if (parse_header(&context) == false) { + kmesh_protocol_data_clean_all(); + return PROTO_UNKNOW; + } + + SET_RET_PROTO_TYPE(ret, PROTO_HTTP_1_1); + SET_RET_MSG_TYPE(ret, MSG_FINAL_RESPONSE); + + return ret; } static struct msg_protocol http_1_1_request = { - .parse_protocol_msg = parse_http_1_1_request, + .parse_protocol_msg = parse_http_1_1_request, }; static struct msg_protocol http_1_1_respose = { - .parse_protocol_msg = parse_http_1_1_respond, + .parse_protocol_msg = parse_http_1_1_respond, }; static void register_http_1_1_request(void) { - list_add_tail(&http_1_1_request.list, &g_protocol_list_head); + list_add_tail(&http_1_1_request.list, &g_protocol_list_head); } static void register_http_1_1_repose(void) { - list_add_tail(&http_1_1_respose.list, &g_protocol_list_head); + list_add_tail(&http_1_1_respose.list, &g_protocol_list_head); } int __init kmesh_register_http_1_1_init(void) { - register_http_1_1_request(); - register_http_1_1_repose(); + register_http_1_1_request(); + register_http_1_1_repose(); - return 0; + return 0; } - diff --git a/kernel/ko_src/kmesh/kmesh_parse_http_1_1.h b/kernel/ko_src/kmesh/kmesh_parse_http_1_1.h index d4eec4bc7..020fa735b 100644 --- a/kernel/ko_src/kmesh/kmesh_parse_http_1_1.h +++ b/kernel/ko_src/kmesh/kmesh_parse_http_1_1.h @@ -16,4 +16,3 @@ int __init kmesh_register_http_1_1_init(void); #endif /* KMESH_REGISTER_HTTP_1_1_H */ - diff --git a/kernel/ko_src/kmesh/kmesh_parse_protocol_data.c b/kernel/ko_src/kmesh/kmesh_parse_protocol_data.c index 650df8ae5..3f9ca128e 100644 --- a/kernel/ko_src/kmesh/kmesh_parse_protocol_data.c +++ b/kernel/ko_src/kmesh/kmesh_parse_protocol_data.c @@ -12,159 +12,159 @@ struct rb_root __percpu *g_kmesh_data_root; struct list_head g_protocol_list_head = LIST_HEAD_INIT(g_protocol_list_head); -struct kmesh_data_node* new_kmesh_data_node(u32 name_field_length) +struct kmesh_data_node *new_kmesh_data_node(u32 name_field_length) { - struct kmesh_data_node *new = (struct kmesh_data_node *)kmalloc(sizeof(struct kmesh_data_node), GFP_ATOMIC); - if (unlikely(!new)) { - (void)pr_err("[kmesh data node] alloc data node memory failed! no memory!\n"); - return ERR_PTR(-ENOMEM); - } - (void)memset(new, 0x0, sizeof(struct kmesh_data_node)); - new->keystring = (char *)kmalloc(name_field_length * sizeof(char), GFP_ATOMIC); - if (unlikely(!new->keystring)) { - kfree(new); - (void)pr_err("[kmesh data node] alloc data node key memory failed! no memory!\n"); - return ERR_PTR(-ENOMEM); - } - (void)memset(new->keystring, 0x0, sizeof(char) * name_field_length); - return new; + struct kmesh_data_node *new = (struct kmesh_data_node *)kmalloc(sizeof(struct kmesh_data_node), GFP_ATOMIC); + if (unlikely(!new)) { + (void)pr_err("[kmesh data node] alloc data node memory failed! no memory!\n"); + return ERR_PTR(-ENOMEM); + } + (void)memset(new, 0x0, sizeof(struct kmesh_data_node)); + new->keystring = (char *)kmalloc(name_field_length * sizeof(char), GFP_ATOMIC); + if (unlikely(!new->keystring)) { + kfree(new); + (void)pr_err("[kmesh data node] alloc data node key memory failed! no memory!\n"); + return ERR_PTR(-ENOMEM); + } + (void)memset(new->keystring, 0x0, sizeof(char) * name_field_length); + return new; } void delete_kmesh_data_node(struct kmesh_data_node **data) { - if (!data) - return; - if ((*data)->keystring) - kfree((*data)->keystring); - kfree(*data); - *data = NULL; + if (!data) + return; + if ((*data)->keystring) + kfree((*data)->keystring); + kfree(*data); + *data = NULL; } -struct kmesh_data_node* kmesh_protocol_data_search(const char* key) +struct kmesh_data_node *kmesh_protocol_data_search(const char *key) { - struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); - struct rb_node *node = kmesh_data_root->rb_node; - int cmp_result; - while (node) { - struct kmesh_data_node *data = rb_entry(node, struct kmesh_data_node, node); - cmp_result = strcmp(data->keystring, key); - - if (cmp_result > 0) - node = node->rb_left; - else if (cmp_result < 0) - node = node->rb_right; - else - return data; - } - return NULL; + struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); + struct rb_node *node = kmesh_data_root->rb_node; + int cmp_result; + while (node) { + struct kmesh_data_node *data = rb_entry(node, struct kmesh_data_node, node); + cmp_result = strcmp(data->keystring, key); + + if (cmp_result > 0) + node = node->rb_left; + else if (cmp_result < 0) + node = node->rb_right; + else + return data; + } + return NULL; } -bool kmesh_protocol_data_insert(struct kmesh_data_node* data) +bool kmesh_protocol_data_insert(struct kmesh_data_node *data) { - struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); - struct rb_node **new = &(kmesh_data_root->rb_node); - struct rb_node *parent = NULL; - - while (*new) { - struct kmesh_data_node *this = rb_entry(*new, struct kmesh_data_node, node); - int cmp_result = strcmp(data->keystring, this->keystring); - parent = *new; - if (cmp_result < 0) - new = &((*new)->rb_left); - else if (cmp_result > 0) - new = &((*new)->rb_right); - else - return false; - } - rb_link_node(&data->node, parent, new); - rb_insert_color(&data->node, kmesh_data_root); - - return true; + struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); + struct rb_node **new = &(kmesh_data_root->rb_node); + struct rb_node *parent = NULL; + + while (*new) { + struct kmesh_data_node *this = rb_entry(*new, struct kmesh_data_node, node); + int cmp_result = strcmp(data->keystring, this->keystring); + parent = *new; + if (cmp_result < 0) + new = &((*new)->rb_left); + else if (cmp_result > 0) + new = &((*new)->rb_right); + else + return false; + } + rb_link_node(&data->node, parent, new); + rb_insert_color(&data->node, kmesh_data_root); + + return true; } -void kmesh_protocol_data_delete(const char* key) +void kmesh_protocol_data_delete(const char *key) { - struct kmesh_data_node* data = kmesh_protocol_data_search(key); + struct kmesh_data_node *data = kmesh_protocol_data_search(key); - if (data != NULL) { - struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); - rb_erase(&data->node, kmesh_data_root); - delete_kmesh_data_node(&data); - } + if (data != NULL) { + struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); + rb_erase(&data->node, kmesh_data_root); + delete_kmesh_data_node(&data); + } } static void kmesh_protocol_clean_all(struct rb_root *kmesh_data_root) { - struct kmesh_data_node* data = NULL; - struct kmesh_data_node* n = NULL; - if (!kmesh_data_root) - return; - rbtree_postorder_for_each_entry_safe(data, n, kmesh_data_root, node) - delete_kmesh_data_node(&data); + struct kmesh_data_node *data = NULL; + struct kmesh_data_node *n = NULL; + if (!kmesh_data_root) + return; + rbtree_postorder_for_each_entry_safe(data, n, kmesh_data_root, node) delete_kmesh_data_node(&data); } void kmesh_protocol_data_clean_all(void) { - struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); - kmesh_protocol_clean_all(kmesh_data_root); - kmesh_data_root->rb_node = NULL; + struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, raw_smp_processor_id()); + kmesh_protocol_clean_all(kmesh_data_root); + kmesh_data_root->rb_node = NULL; } void kmesh_protocol_data_clean_allcpu(void) { - int cpu_num; - for_each_possible_cpu(cpu_num) { - struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, cpu_num); - kmesh_protocol_clean_all(kmesh_data_root); - } + int cpu_num; + for_each_possible_cpu(cpu_num) + { + struct rb_root *kmesh_data_root = per_cpu_ptr(g_kmesh_data_root, cpu_num); + kmesh_protocol_clean_all(kmesh_data_root); + } } -typedef u32 (*bpf_parse_protocol_func)(struct bpf_mem_ptr* msg); +typedef u32 (*bpf_parse_protocol_func)(struct bpf_mem_ptr *msg); extern bpf_parse_protocol_func parse_protocol_func; -typedef struct bpf_mem_ptr* (*bpf_get_protocol_element_func)(char *key); +typedef struct bpf_mem_ptr *(*bpf_get_protocol_element_func)(char *key); extern bpf_get_protocol_element_func get_protocol_element_func; -static u32 -parse_protocol_impl(struct bpf_mem_ptr* msg) +static u32 parse_protocol_impl(struct bpf_mem_ptr *msg) { - u32 ret; - struct msg_protocol *cur; - kmesh_protocol_data_clean_all(); - list_for_each_entry(cur, &g_protocol_list_head, list) { - if (!cur->parse_protocol_msg) - continue; - ret = cur->parse_protocol_msg(msg); - if (ret) - break; - } - return ret; + u32 ret; + struct msg_protocol *cur; + kmesh_protocol_data_clean_all(); + list_for_each_entry(cur, &g_protocol_list_head, list) + { + if (!cur->parse_protocol_msg) + continue; + ret = cur->parse_protocol_msg(msg); + if (ret) + break; + } + return ret; } -static struct bpf_mem_ptr* get_protocol_element_impl(char *key) +static struct bpf_mem_ptr *get_protocol_element_impl(char *key) { - struct kmesh_data_node *data = kmesh_protocol_data_search(key); - if (!data) - return NULL; - return &data->value; + struct kmesh_data_node *data = kmesh_protocol_data_search(key); + if (!data) + return NULL; + return &data->value; } int __init proto_common_init(void) { - parse_protocol_func = parse_protocol_impl; - get_protocol_element_func = get_protocol_element_impl; - /* add protocol list */ - g_kmesh_data_root = alloc_percpu(struct rb_root); - if (!g_kmesh_data_root) - return -ENOMEM; - - return 0; + parse_protocol_func = parse_protocol_impl; + get_protocol_element_func = get_protocol_element_impl; + /* add protocol list */ + g_kmesh_data_root = alloc_percpu(struct rb_root); + if (!g_kmesh_data_root) + return -ENOMEM; + + return 0; } void __exit proto_common_exit(void) { - parse_protocol_func = NULL; - get_protocol_element_func = NULL; - kmesh_protocol_data_clean_allcpu(); - free_percpu(g_kmesh_data_root); + parse_protocol_func = NULL; + get_protocol_element_func = NULL; + kmesh_protocol_data_clean_allcpu(); + free_percpu(g_kmesh_data_root); } diff --git a/kernel/ko_src/kmesh/kmesh_parse_protocol_data.h b/kernel/ko_src/kmesh/kmesh_parse_protocol_data.h index 66a4c9420..eaf75aa4c 100644 --- a/kernel/ko_src/kmesh/kmesh_parse_protocol_data.h +++ b/kernel/ko_src/kmesh/kmesh_parse_protocol_data.h @@ -15,36 +15,27 @@ #include #include -enum kmesh_l7_proto_type { - PROTO_UNKNOW = 0, - PROTO_HTTP_1_1, - PROTO_HTTP_2_0 -}; +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_l7_msg_type { MSG_UNKNOW = 0, MSG_REQUEST, MSG_MID_REPONSE, MSG_FINAL_RESPONSE }; #define KMESH_PROTO_TYPE_WIDTH (8) -#define SET_RET_PROTO_TYPE(n, type) (n) = (((n) & 0xff00) | ((u32)(type) & 0xff )) -#define GET_RET_PROTO_TYPE(n) ((n) & 0xff) +#define SET_RET_PROTO_TYPE(n, type) (n) = (((n)&0xff00) | ((u32)(type)&0xff)) +#define GET_RET_PROTO_TYPE(n) ((n)&0xff) -#define SET_RET_MSG_TYPE(n, type) (n) = (((n) & 0xff) | (((u32)(type) & 0xff) << KMESH_PROTO_TYPE_WIDTH)) -#define GET_RET_MSG_TYPE(n) (((n) >> KMESH_PROTO_TYPE_WIDTH) & 0xff) +#define SET_RET_MSG_TYPE(n, type) (n) = (((n)&0xff) | (((u32)(type)&0xff) << KMESH_PROTO_TYPE_WIDTH)) +#define GET_RET_MSG_TYPE(n) (((n) >> KMESH_PROTO_TYPE_WIDTH) & 0xff) struct kmesh_data_node { - struct rb_node node; - char *keystring; - struct bpf_mem_ptr value; + struct rb_node node; + char *keystring; + struct bpf_mem_ptr value; }; struct msg_protocol { - struct list_head list; - u32 (*parse_protocol_msg)(const struct bpf_mem_ptr *msg); + struct list_head list; + u32 (*parse_protocol_msg)(const struct bpf_mem_ptr *msg); }; extern struct rb_root *g_kmesh_data_root; @@ -64,4 +55,3 @@ int __init proto_common_init(void); void __exit proto_common_exit(void); #endif /* KMESH_PARSE_PROTOCOL_DATA */ - diff --git a/oncn-mda/cli_src/func/chain.c b/oncn-mda/cli_src/func/chain.c index c7d18ee5d..41a1e110e 100644 --- a/oncn-mda/cli_src/func/chain.c +++ b/oncn-mda/cli_src/func/chain.c @@ -18,295 +18,294 @@ #include "macli.h" static const struct option g_chain_options[] = { - {"ip", required_argument, NULL, 'i'}, - {"ports", required_argument, NULL, 'p'}, + {"ip", required_argument, NULL, 'i'}, + {"ports", required_argument, NULL, 'p'}, #if MDA_GID_UID_FILTER - {"uid-owner", required_argument, NULL, 'u'}, - {"gid-owner", required_argument, NULL, 'g'}, + {"uid-owner", required_argument, NULL, 'u'}, + {"gid-owner", required_argument, NULL, 'g'}, #endif - {"jump", required_argument, NULL, 'j'}, - {NULL} -}; + {"jump", required_argument, NULL, 'j'}, + {NULL}}; static void chain_usage(void) { - (void)printf("config file usage: chain {OPTIONS}\n"); - (void)printf(" OPTIONS: -i|--ip: filter cidr:ip/mask\n"); - (void)printf(" -p|--ports: filter ports,eg:15001-15006\n"); + (void)printf("config file usage: chain {OPTIONS}\n"); + (void)printf(" OPTIONS: -i|--ip: filter cidr:ip/mask\n"); + (void)printf(" -p|--ports: filter ports,eg:15001-15006\n"); #if MDA_GID_UID_FILTER - (void)printf(" -u|--uid-owner: filter uids,eg:1337\n"); - (void)printf(" -g|--gid-owner: filter gids,eg:1337\n"); + (void)printf(" -u|--uid-owner: filter uids,eg:1337\n"); + (void)printf(" -g|--gid-owner: filter gids,eg:1337\n"); #endif - (void)printf(" -j|--jump: RETURN or ACCEPT,eg:accept/return\n"); + (void)printf(" -j|--jump: RETURN or ACCEPT,eg:accept/return\n"); } -static int get_input_ip(const char* const src, struct input_filter_rule* const input_filter_rules) +static int get_input_ip(const char *const src, struct input_filter_rule *const input_filter_rules) { - if (input_filter_rules->input_ip_num >= MAX_PARAM_LENGTH) { - macli_log(ERR, "over the max cidrs set num, max is %d\n", MAX_PARAM_LENGTH); - return FAILED; - } - int ret = strcpy_s(input_filter_rules->input_ip[(input_filter_rules->input_ip_num)++], MAX_CIDR_LENGTH, src); - if (ret == ERANGE_AND_RESET) { - macli_log(ERR, "input cidr string too long!\n"); - return FAILED; - } else if (ret != EOK) { - macli_log(ERR, "get filter rules failed! errno:%d\n", ret); - return FAILED; - } - return SUCCESS; + if (input_filter_rules->input_ip_num >= MAX_PARAM_LENGTH) { + macli_log(ERR, "over the max cidrs set num, max is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + int ret = strcpy_s(input_filter_rules->input_ip[(input_filter_rules->input_ip_num)++], MAX_CIDR_LENGTH, src); + if (ret == ERANGE_AND_RESET) { + macli_log(ERR, "input cidr string too long!\n"); + return FAILED; + } else if (ret != EOK) { + macli_log(ERR, "get filter rules failed! errno:%d\n", ret); + return FAILED; + } + return SUCCESS; } -static int get_input_port(const char* const src, struct input_filter_rule* const input_filter_rules) +static int get_input_port(const char *const src, struct input_filter_rule *const input_filter_rules) { - if (input_filter_rules->input_port_num >= MAX_PARAM_LENGTH) { - macli_log(ERR, "over the max ports set num, max is %d\n", MAX_PARAM_LENGTH); - return FAILED; - } - int ret = strcpy_s(input_filter_rules->input_port[(input_filter_rules->input_port_num)++], - MAX_PORT_RANGE_LENGTH, src); - if (ret == ERANGE_AND_RESET) { - macli_log(ERR, "input port string is too long!\n"); - return FAILED; - } else if (ret != EOK) { - macli_log(ERR, "get filter rules failed! errno:%d\n", ret); - return FAILED; - } - return SUCCESS; + if (input_filter_rules->input_port_num >= MAX_PARAM_LENGTH) { + macli_log(ERR, "over the max ports set num, max is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + int ret = + strcpy_s(input_filter_rules->input_port[(input_filter_rules->input_port_num)++], MAX_PORT_RANGE_LENGTH, src); + if (ret == ERANGE_AND_RESET) { + macli_log(ERR, "input port string is too long!\n"); + return FAILED; + } else if (ret != EOK) { + macli_log(ERR, "get filter rules failed! errno:%d\n", ret); + return FAILED; + } + return SUCCESS; } -static int set_cidr_filter_rule(struct input_cidr* const p, __u32 ipv4, __u32 mask) +static int set_cidr_filter_rule(struct input_cidr *const p, __u32 ipv4, __u32 mask) { - if (p->current_cidr_num + 1 > MAX_PARAM_LENGTH) { - macli_log(ERR, "can not set accept ip rule, because the rule is too much! max rule num is %d\n", - MAX_PARAM_LENGTH); - return FAILED; - } + if (p->current_cidr_num + 1 > MAX_PARAM_LENGTH) { + macli_log( + ERR, "can not set accept ip rule, because the rule is too much! max rule num is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } - p->cidrs[p->current_cidr_num].ip4 = ipv4; - p->cidrs[p->current_cidr_num].mask = - (__u32)(pow(MASK_BASE_NUM, MASK_LENGTH) - pow(MASK_BASE_NUM, MASK_LENGTH - mask)); - p->current_cidr_num++; - macli_log(DEBUG, "add ip:%u, mask:%u to filter\n", ipv4, mask); - return SUCCESS; + p->cidrs[p->current_cidr_num].ip4 = ipv4; + p->cidrs[p->current_cidr_num].mask = + (__u32)(pow(MASK_BASE_NUM, MASK_LENGTH) - pow(MASK_BASE_NUM, MASK_LENGTH - mask)); + p->current_cidr_num++; + macli_log(DEBUG, "add ip:%u, mask:%u to filter\n", ipv4, mask); + return SUCCESS; } -static int set_port_filter_rule(struct input_port* const p, __u32 begin_port, __u32 end_port) +static int set_port_filter_rule(struct input_port *const p, __u32 begin_port, __u32 end_port) { - if (p->current_port_num + 1 > MAX_PARAM_LENGTH) { - macli_log(ERR, "can not set accept ports rule, because the rule is too much! max rule num is %d\n", - MAX_PARAM_LENGTH); - return FAILED; - } - p->ports[p->current_port_num].begin_port = begin_port; - p->ports[p->current_port_num].end_port = end_port; - p->current_port_num++; - macli_log(DEBUG, "add beginport:%u, endport:%u to filter\n", begin_port, end_port); - return SUCCESS; + if (p->current_port_num + 1 > MAX_PARAM_LENGTH) { + macli_log( + ERR, "can not set accept ports rule, because the rule is too much! max rule num is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + p->ports[p->current_port_num].begin_port = begin_port; + p->ports[p->current_port_num].end_port = end_port; + p->current_port_num++; + macli_log(DEBUG, "add beginport:%u, endport:%u to filter\n", begin_port, end_port); + return SUCCESS; } -static int init_cidr_param(struct sock_param* const filter_rules, - const struct input_filter_rule* const input_filter_rules, bool is_accept) +static int init_cidr_param( + struct sock_param *const filter_rules, const struct input_filter_rule *const input_filter_rules, bool is_accept) { - struct input_cidr* p = NULL; - if (is_accept) - p = &filter_rules->accept_cidrs; - else - p = &filter_rules->return_cidrs; + struct input_cidr *p = NULL; + if (is_accept) + p = &filter_rules->accept_cidrs; + else + p = &filter_rules->return_cidrs; - for (int i = 0; i < input_filter_rules->input_ip_num; ++i) { - __u32 ipv4 = 0; - __u32 mask = 0; - if (check_cidr(input_filter_rules->input_ip[i], &ipv4, &mask)) { - macli_log(ERR, "check ipv4 failed! input cidrs is %s\n", input_filter_rules->input_ip[i]); - return FAILED; - } - if (set_cidr_filter_rule(p, ipv4, mask) != SUCCESS) - return FAILED; - } - return SUCCESS; + for (int i = 0; i < input_filter_rules->input_ip_num; ++i) { + __u32 ipv4 = 0; + __u32 mask = 0; + if (check_cidr(input_filter_rules->input_ip[i], &ipv4, &mask)) { + macli_log(ERR, "check ipv4 failed! input cidrs is %s\n", input_filter_rules->input_ip[i]); + return FAILED; + } + if (set_cidr_filter_rule(p, ipv4, mask) != SUCCESS) + return FAILED; + } + return SUCCESS; } -static int init_port_param(struct sock_param* const filter_rules, - const struct input_filter_rule* const input_filter_rules, bool is_accept) +static int init_port_param( + struct sock_param *const filter_rules, const struct input_filter_rule *const input_filter_rules, bool is_accept) { - struct input_port* p = NULL; - if (is_accept) - p = &filter_rules->accept_ports; - else - p = &filter_rules->return_ports; - for (int i = 0; i < input_filter_rules->input_port_num; ++i) { - __u32 begin_port = 0; - __u32 end_port = 0; - if (check_port(input_filter_rules->input_port[i], &begin_port, &end_port)) { - macli_log(ERR, "check ports failed! input ports is %s\n", input_filter_rules->input_port[i]); - return FAILED; - } - if (set_port_filter_rule(p, begin_port, end_port)) - return FAILED; - } - return SUCCESS; + struct input_port *p = NULL; + if (is_accept) + p = &filter_rules->accept_ports; + else + p = &filter_rules->return_ports; + for (int i = 0; i < input_filter_rules->input_port_num; ++i) { + __u32 begin_port = 0; + __u32 end_port = 0; + if (check_port(input_filter_rules->input_port[i], &begin_port, &end_port)) { + macli_log(ERR, "check ports failed! input ports is %s\n", input_filter_rules->input_port[i]); + return FAILED; + } + if (set_port_filter_rule(p, begin_port, end_port)) + return FAILED; + } + return SUCCESS; } #if MDA_GID_UID_FILTER -static int get_input_uid(const char* const src, struct input_filter_rule* const input_filter_rules) +static int get_input_uid(const char *const src, struct input_filter_rule *const input_filter_rules) { - if (input_filter_rules->input_uid_num >= MAX_UID_GID_LENGTH) { - macli_log(ERR, "over the max uids set num, max is %d\n", MAX_PARAM_LENGTH); - return FAILED; - } - __u32 tmp_uid; - if (get_u32_num(src, &tmp_uid) != SUCCESS) { - macli_log(ERR, "not a valid uids! you input:%s\n", src); - return FAILED; - } - input_filter_rules->input_uid[(input_filter_rules->input_uid_num)++] = tmp_uid; + if (input_filter_rules->input_uid_num >= MAX_UID_GID_LENGTH) { + macli_log(ERR, "over the max uids set num, max is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + __u32 tmp_uid; + if (get_u32_num(src, &tmp_uid) != SUCCESS) { + macli_log(ERR, "not a valid uids! you input:%s\n", src); + return FAILED; + } + input_filter_rules->input_uid[(input_filter_rules->input_uid_num)++] = tmp_uid; - return SUCCESS; + return SUCCESS; } -static int get_input_gid(const char* const src, struct input_filter_rule* const input_filter_rules) +static int get_input_gid(const char *const src, struct input_filter_rule *const input_filter_rules) { - if (input_filter_rules->input_gid_num >= MAX_UID_GID_LENGTH) { - macli_log(ERR, "over the max gids set num, max is %d\n", MAX_PARAM_LENGTH); - return FAILED; - } - __u32 tmp_gid; - if (get_u32_num(src, &tmp_gid) != SUCCESS) { - macli_log(ERR, "not a valid gids! you input:%s\n", src); - return FAILED; - } - input_filter_rules->input_gid[(input_filter_rules->input_gid_num)++] = tmp_gid; + if (input_filter_rules->input_gid_num >= MAX_UID_GID_LENGTH) { + macli_log(ERR, "over the max gids set num, max is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + __u32 tmp_gid; + if (get_u32_num(src, &tmp_gid) != SUCCESS) { + macli_log(ERR, "not a valid gids! you input:%s\n", src); + return FAILED; + } + input_filter_rules->input_gid[(input_filter_rules->input_gid_num)++] = tmp_gid; - return SUCCESS; + return SUCCESS; } -static int set_uid_filter_rule(struct input_uid* const p, __u32 input_uid) +static int set_uid_filter_rule(struct input_uid *const p, __u32 input_uid) { - if (p->current_uid_num + 1 > MAX_PARAM_LENGTH) { - macli_log(ERR, "can not set accept uids rule, because the rule is too much! max rule num is %d\n", - MAX_PARAM_LENGTH); - return FAILED; - } - p->uids[p->current_uid_num] = input_uid; - p->current_uid_num++; - macli_log(DEBUG, "add uids:%u to filter\n", input_uid); - return SUCCESS; + if (p->current_uid_num + 1 > MAX_PARAM_LENGTH) { + macli_log( + ERR, "can not set accept uids rule, because the rule is too much! max rule num is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + p->uids[p->current_uid_num] = input_uid; + p->current_uid_num++; + macli_log(DEBUG, "add uids:%u to filter\n", input_uid); + return SUCCESS; } -static int set_gid_filter_rule(struct input_gid* const p, __u32 input_gid) +static int set_gid_filter_rule(struct input_gid *const p, __u32 input_gid) { - if (p->current_gid_num + 1 > MAX_PARAM_LENGTH) { - macli_log(ERR, "can not set accept gids rule, because the rule is too much! max rule num is %d\n", - MAX_PARAM_LENGTH); - return FAILED; - } - p->gids[p->current_gid_num] = input_gid; - p->current_gid_num++; - macli_log(DEBUG, "add gids:%u to accept filter\n", input_gid); - return SUCCESS; + if (p->current_gid_num + 1 > MAX_PARAM_LENGTH) { + macli_log( + ERR, "can not set accept gids rule, because the rule is too much! max rule num is %d\n", MAX_PARAM_LENGTH); + return FAILED; + } + p->gids[p->current_gid_num] = input_gid; + p->current_gid_num++; + macli_log(DEBUG, "add gids:%u to accept filter\n", input_gid); + return SUCCESS; } -static int init_gid_param(struct sock_param* const filter_rules, - const struct input_filter_rule* const input_filter_rules, bool is_accept) +static int init_gid_param( + struct sock_param *const filter_rules, const struct input_filter_rule *const input_filter_rules, bool is_accept) { - struct input_gid* p = NULL; - if (is_accept) - p = &filter_rules->accept_gids; - else - p = &filter_rules->return_gids; - for (int i = 0; i < input_filter_rules->input_gid_num; ++i) { - if (set_gid_filter_rule(p, input_filter_rules->input_gid[i])) - return FAILED; - } - return SUCCESS; + struct input_gid *p = NULL; + if (is_accept) + p = &filter_rules->accept_gids; + else + p = &filter_rules->return_gids; + for (int i = 0; i < input_filter_rules->input_gid_num; ++i) { + if (set_gid_filter_rule(p, input_filter_rules->input_gid[i])) + return FAILED; + } + return SUCCESS; } -static int init_uid_param(struct sock_param* const filter_rules, - const struct input_filter_rule* const input_filter_rules, bool is_accept) +static int init_uid_param( + struct sock_param *const filter_rules, const struct input_filter_rule *const input_filter_rules, bool is_accept) { - struct input_uid* p = NULL; - if (is_accept) - p = &filter_rules->accept_uids; - else - p = &filter_rules->return_uids; - for (int i = 0; i < input_filter_rules->input_uid_num; ++i) { - if (set_uid_filter_rule(p, input_filter_rules->input_uid[i])) - return FAILED; - } - return SUCCESS; + struct input_uid *p = NULL; + if (is_accept) + p = &filter_rules->accept_uids; + else + p = &filter_rules->return_uids; + for (int i = 0; i < input_filter_rules->input_uid_num; ++i) { + if (set_uid_filter_rule(p, input_filter_rules->input_uid[i])) + return FAILED; + } + return SUCCESS; } #endif -static int set_filter_rule(struct sock_param* const filter_rules, - const struct input_filter_rule* const input_filter_rules, bool is_accept) +static int set_filter_rule( + struct sock_param *const filter_rules, const struct input_filter_rule *const input_filter_rules, bool is_accept) { - macli_log(DEBUG, "begin set_filter_rule\n"); - if (init_cidr_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) - return FAILED; + macli_log(DEBUG, "begin set_filter_rule\n"); + if (init_cidr_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) + return FAILED; - if (init_port_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) - return FAILED; + if (init_port_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) + return FAILED; #if MDA_GID_UID_FILTER - if (init_uid_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) - return FAILED; + if (init_uid_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) + return FAILED; - if (init_gid_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) - return FAILED; + if (init_gid_param(filter_rules, input_filter_rules, is_accept) != SUCCESS) + return FAILED; #endif - return SUCCESS; + return SUCCESS; } -static int chain_get_opt(int argc, char* const *argv, - struct input_filter_rule* const input_filter_rules, bool* is_accept) +static int +chain_get_opt(int argc, char *const *argv, struct input_filter_rule *const input_filter_rules, bool *is_accept) { - int opt; - // To use getopt_long, optind must be set to 1 - optind = 1; - while ((opt = getopt_long(argc, argv, "i:p:u:g:j:", g_chain_options, NULL)) >= 0) { - switch (opt) { - case 'i': - if (get_input_ip(optarg, input_filter_rules) != SUCCESS) - return FAILED; - break; - case 'p': - if (get_input_port(optarg, input_filter_rules) != SUCCESS) - return FAILED; - break; + int opt; + // To use getopt_long, optind must be set to 1 + optind = 1; + while ((opt = getopt_long(argc, argv, "i:p:u:g:j:", g_chain_options, NULL)) >= 0) { + switch (opt) { + case 'i': + if (get_input_ip(optarg, input_filter_rules) != SUCCESS) + return FAILED; + break; + case 'p': + if (get_input_port(optarg, input_filter_rules) != SUCCESS) + return FAILED; + break; #if MDA_GID_UID_FILTER - case 'u': - if (get_input_uid(optarg, input_filter_rules) != SUCCESS) - return FAILED; - break; - case 'g': - if (get_input_gid(optarg, input_filter_rules) != SUCCESS) - return FAILED; - break; + case 'u': + if (get_input_uid(optarg, input_filter_rules) != SUCCESS) + return FAILED; + break; + case 'g': + if (get_input_gid(optarg, input_filter_rules) != SUCCESS) + return FAILED; + break; #endif - case 'j': - if (strcmp("ACCEPT", optarg) == 0 || strcmp("accept", optarg) == 0) { - *is_accept = true; - } else if (strcmp("RETURN", optarg) == 0 || strcmp("return", optarg) == 0) { - *is_accept = false; - } else { - macli_log(ERR, "-j need param 'ACCEPT' or 'RETURN'!\n"); - return FAILED; - } - break; - case '?': - default: - chain_usage(); - return FAILED; - } - } - if (optind != argc) { - macli_log(ERR, "unknown param!\n"); - chain_usage(); - return FAILED; - } - return SUCCESS; + case 'j': + if (strcmp("ACCEPT", optarg) == 0 || strcmp("accept", optarg) == 0) { + *is_accept = true; + } else if (strcmp("RETURN", optarg) == 0 || strcmp("return", optarg) == 0) { + *is_accept = false; + } else { + macli_log(ERR, "-j need param 'ACCEPT' or 'RETURN'!\n"); + return FAILED; + } + break; + case '?': + default: + chain_usage(); + return FAILED; + } + } + if (optind != argc) { + macli_log(ERR, "unknown param!\n"); + chain_usage(); + return FAILED; + } + return SUCCESS; } /* @@ -319,22 +318,22 @@ static int chain_get_opt(int argc, char* const *argv, * return: SUCCESS * FAILED */ -int do_chain(int argc, char* const *argv, struct sock_param* const filter_rules) +int do_chain(int argc, char *const *argv, struct sock_param *const filter_rules) { - if (argc <= 1 || (strcmp("chain", argv[0]) != 0)) { - chain_usage(); - return FAILED; - } + if (argc <= 1 || (strcmp("chain", argv[0]) != 0)) { + chain_usage(); + return FAILED; + } - struct input_filter_rule input_filter_rules = {0}; + struct input_filter_rule input_filter_rules = {0}; - bool is_accept = true; - // You need to save the content and add it to the filtering structure only when it is read as Accept or reject - if (chain_get_opt(argc, argv, &input_filter_rules, &is_accept) != SUCCESS) - return FAILED; + bool is_accept = true; + // You need to save the content and add it to the filtering structure only when it is read as Accept or reject + if (chain_get_opt(argc, argv, &input_filter_rules, &is_accept) != SUCCESS) + return FAILED; - if (set_filter_rule(filter_rules, &input_filter_rules, is_accept)) - return FAILED; + if (set_filter_rule(filter_rules, &input_filter_rules, is_accept)) + return FAILED; - return SUCCESS; + return SUCCESS; } diff --git a/oncn-mda/cli_src/func/global.c b/oncn-mda/cli_src/func/global.c index 850f9fa58..896356cbf 100644 --- a/oncn-mda/cli_src/func/global.c +++ b/oncn-mda/cli_src/func/global.c @@ -21,345 +21,372 @@ #define TMP_BUF_SIZE 50 const char pinmap_file_path[][PATH_MAX] = { - "/sys/fs/bpf/meshAccelerate/sock_ops_map", + "/sys/fs/bpf/meshAccelerate/sock_ops_map", #if MDA_GID_UID_FILTER - "/sys/fs/bpf/meshAccelerate/sock_helper_map", + "/sys/fs/bpf/meshAccelerate/sock_helper_map", #endif - "/sys/fs/bpf/meshAccelerate/sock_param_map", - "/sys/fs/bpf/meshAccelerate/sock_proxy_map", - "/sys/fs/bpf/meshAccelerate/sock_dump_map", - "/sys/fs/bpf/meshAccelerate/sock_dump_data_map" -}; + "/sys/fs/bpf/meshAccelerate/sock_param_map", + "/sys/fs/bpf/meshAccelerate/sock_proxy_map", + "/sys/fs/bpf/meshAccelerate/sock_dump_map", + "/sys/fs/bpf/meshAccelerate/sock_dump_data_map"}; const char pinprog_file_path[][PATH_MAX] = { - "/sys/fs/bpf/meshAccelerate/sock_ops_ip4", - "/sys/fs/bpf/meshAccelerate/sock_redirect", + "/sys/fs/bpf/meshAccelerate/sock_ops_ip4", + "/sys/fs/bpf/meshAccelerate/sock_redirect", }; struct bpf_create_map_attr g_sock_param_map_xattr = { - .name = to_str(SOCK_PARAM_MAP_NAME), - .map_type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(__u32), - .value_size = sizeof(struct sock_param), - .max_entries = 1, + .name = to_str(SOCK_PARAM_MAP_NAME), + .map_type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(struct sock_param), + .max_entries = 1, }; struct bpf_create_map_attr g_sock_ops_map_xattr = { - .name = to_str(SOCK_OPS_MAP_NAME), - .map_type = BPF_MAP_TYPE_SOCKHASH, - .key_size = sizeof(struct sock_key), - .value_size = sizeof(int), - .max_entries = SKOPS_MAP_SIZE, + .name = to_str(SOCK_OPS_MAP_NAME), + .map_type = BPF_MAP_TYPE_SOCKHASH, + .key_size = sizeof(struct sock_key), + .value_size = sizeof(int), + .max_entries = SKOPS_MAP_SIZE, }; #if MDA_GID_UID_FILTER struct bpf_create_map_attr g_sock_ops_helper_map_xattr = { - .name = to_str(SOCK_OPS_HELPER_MAP_NAME), - .map_type = BPF_MAP_TYPE_HASH, - .key_size = sizeof(struct sock_key), - .value_size = sizeof(struct uid_gid_info), - .max_entries = SKOPS_MAP_SIZE, + .name = to_str(SOCK_OPS_HELPER_MAP_NAME), + .map_type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(struct sock_key), + .value_size = sizeof(struct uid_gid_info), + .max_entries = SKOPS_MAP_SIZE, }; #endif struct bpf_create_map_attr g_sock_ops_proxy_map_xattr = { - .name = to_str(SOCK_OPS_PROXY_MAP_NAME), - .map_type = BPF_MAP_TYPE_HASH, - .key_size = sizeof(struct sock_key), - .value_size = sizeof(struct sock_key), - .max_entries = SKOPS_MAP_SIZE, + .name = to_str(SOCK_OPS_PROXY_MAP_NAME), + .map_type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(struct sock_key), + .value_size = sizeof(struct sock_key), + .max_entries = SKOPS_MAP_SIZE, }; struct bpf_create_map_attr g_sock_dump_map = { - .name = to_str(SOCK_DUMP_MAP_I_NAME), - .map_type = BPF_MAP_TYPE_QUEUE, - .key_size = 0, - .value_size = sizeof(struct dump_data), - .max_entries = DUMP_QUEUE_LENGTH, + .name = to_str(SOCK_DUMP_MAP_I_NAME), + .map_type = BPF_MAP_TYPE_QUEUE, + .key_size = 0, + .value_size = sizeof(struct dump_data), + .max_entries = DUMP_QUEUE_LENGTH, }; struct bpf_create_map_attr g_sock_dump_data_map = { - .name = to_str(SOCK_DUMP_CPU_ARRAY_NAME), - .map_type = BPF_MAP_TYPE_PERCPU_ARRAY, - .key_size = sizeof(__u32), - .value_size = sizeof(struct dump_data), - .max_entries = 1, + .name = to_str(SOCK_DUMP_CPU_ARRAY_NAME), + .map_type = BPF_MAP_TYPE_PERCPU_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(struct dump_data), + .max_entries = 1, }; struct bpf_object_open_attr g_sock_ops_xattr = { - .prog_type = BPF_PROG_TYPE_SOCK_OPS, - .file = SOCK_OPS_PATH_INIT, + .prog_type = BPF_PROG_TYPE_SOCK_OPS, + .file = SOCK_OPS_PATH_INIT, }; struct bpf_object_open_attr g_sock_redirect_xattr = { - .prog_type = BPF_PROG_TYPE_SK_MSG, - .file = SOCK_REDIRECT_PATH_INIT, + .prog_type = BPF_PROG_TYPE_SK_MSG, + .file = SOCK_REDIRECT_PATH_INIT, }; -static int get_prog_fd(const char* const prog_name, int* const fd) +static int get_prog_fd(const char *const prog_name, int *const fd) { - *fd = ERROR; - struct bpf_prog_info prog_info = {0}; - __u32 obj_id = 0; - __u32 info_length = sizeof(struct bpf_prog_info); - while (true) { - if (memset_s(&prog_info, info_length, 0x0, info_length) != EOK) { - macli_log(ERR, "system memset failed!\n"); - return FAILED; - } - if (bpf_prog_get_next_id(obj_id, &obj_id)) { - if (errno == ENOENT) - break; - macli_log(ERR, "can not read bpf prog info! errno:%d\n", errno); - return FAILED; - } - int obj_fd = bpf_prog_get_fd_by_id(obj_id); - if (obj_fd < 0) { - if (errno == ENOENT) - continue; - macli_log(ERR, "can not read bpf prog info! errno:%d\n", errno); - return FAILED; - } - if (bpf_obj_get_info_by_fd(obj_fd, &prog_info, &info_length)) { - macli_log(ERR, "can not read bpf prog info! errno:%d\n", errno); - (void)close(obj_fd); - return FAILED; - } - if (strcmp(prog_info.name, prog_name) == 0) { - *fd = obj_fd; - return SUCCESS; - } - (void)close(obj_fd); - } - return SUCCESS; + *fd = ERROR; + struct bpf_prog_info prog_info = {0}; + __u32 obj_id = 0; + __u32 info_length = sizeof(struct bpf_prog_info); + while (true) { + if (memset_s(&prog_info, info_length, 0x0, info_length) != EOK) { + macli_log(ERR, "system memset failed!\n"); + return FAILED; + } + if (bpf_prog_get_next_id(obj_id, &obj_id)) { + if (errno == ENOENT) + break; + macli_log(ERR, "can not read bpf prog info! errno:%d\n", errno); + return FAILED; + } + int obj_fd = bpf_prog_get_fd_by_id(obj_id); + if (obj_fd < 0) { + if (errno == ENOENT) + continue; + macli_log(ERR, "can not read bpf prog info! errno:%d\n", errno); + return FAILED; + } + if (bpf_obj_get_info_by_fd(obj_fd, &prog_info, &info_length)) { + macli_log(ERR, "can not read bpf prog info! errno:%d\n", errno); + (void)close(obj_fd); + return FAILED; + } + if (strcmp(prog_info.name, prog_name) == 0) { + *fd = obj_fd; + return SUCCESS; + } + (void)close(obj_fd); + } + return SUCCESS; } -static int get_map_fd(const char* const map_name, int* const fd) +static int get_map_fd(const char *const map_name, int *const fd) { - *fd = ERROR; - struct bpf_map_info map_info = {0}; - __u32 obj_id = 0; - __u32 info_length = sizeof(struct bpf_map_info); - while (true) { - if (memset_s(&map_info, info_length, 0x0, info_length) != EOK) { - macli_log(ERR, "system memset failed!\n"); - return FAILED; - } - if (bpf_map_get_next_id(obj_id, &obj_id)) { - if (errno == ENOENT) - break; - macli_log(ERR, "can not read bpf map info! errno:%d\n", errno); - return FAILED; - } - int obj_fd = bpf_map_get_fd_by_id(obj_id); - if (obj_fd < 0) { - if (errno == ENOENT) - continue; - macli_log(ERR, "can not read bpf map info! errno:%d\n", errno); - return FAILED; - } - if (bpf_obj_get_info_by_fd(obj_fd, &map_info, &info_length)) { - macli_log(ERR, "can not read bpf map info! errno:%d\n", errno); - (void)close(obj_fd); - return FAILED; - } - if (strcmp(map_info.name, map_name) == 0) { - *fd = obj_fd; - return SUCCESS; - } - (void)close(obj_fd); - } - return SUCCESS; + *fd = ERROR; + struct bpf_map_info map_info = {0}; + __u32 obj_id = 0; + __u32 info_length = sizeof(struct bpf_map_info); + while (true) { + if (memset_s(&map_info, info_length, 0x0, info_length) != EOK) { + macli_log(ERR, "system memset failed!\n"); + return FAILED; + } + if (bpf_map_get_next_id(obj_id, &obj_id)) { + if (errno == ENOENT) + break; + macli_log(ERR, "can not read bpf map info! errno:%d\n", errno); + return FAILED; + } + int obj_fd = bpf_map_get_fd_by_id(obj_id); + if (obj_fd < 0) { + if (errno == ENOENT) + continue; + macli_log(ERR, "can not read bpf map info! errno:%d\n", errno); + return FAILED; + } + if (bpf_obj_get_info_by_fd(obj_fd, &map_info, &info_length)) { + macli_log(ERR, "can not read bpf map info! errno:%d\n", errno); + (void)close(obj_fd); + return FAILED; + } + if (strcmp(map_info.name, map_name) == 0) { + *fd = obj_fd; + return SUCCESS; + } + (void)close(obj_fd); + } + return SUCCESS; } -static int init_mesh_map(struct mesh_map_info* const fds_map, const char* const pin_file_path, - const char* const map_name, struct bpf_create_map_attr* const map_attr) +static int init_mesh_map( + struct mesh_map_info *const fds_map, + const char *const pin_file_path, + const char *const map_name, + struct bpf_create_map_attr *const map_attr) { - int ret = EOK; - ret += strcpy_s(fds_map->name, BPF_OBJ_NAME_LEN, map_name); - ret += strcpy_s(fds_map->pin_file_path, PATH_MAX, pin_file_path); - if (ret != EOK) { - macli_log(ERR, "system copy string failed!"); - return FAILED; - } - if (get_map_fd(fds_map->name, &(fds_map->fd)) != SUCCESS) - return FAILED; - fds_map->xattr = map_attr; - return SUCCESS; + int ret = EOK; + ret += strcpy_s(fds_map->name, BPF_OBJ_NAME_LEN, map_name); + ret += strcpy_s(fds_map->pin_file_path, PATH_MAX, pin_file_path); + if (ret != EOK) { + macli_log(ERR, "system copy string failed!"); + return FAILED; + } + if (get_map_fd(fds_map->name, &(fds_map->fd)) != SUCCESS) + return FAILED; + fds_map->xattr = map_attr; + return SUCCESS; } -static int init_mesh_prog(struct mesh_prog_info* const fds_prog, const char* const prog_name, - struct bpf_object_open_attr* const prog_attr, - enum bpf_attach_type attach_type, int attach_fd) +static int init_mesh_prog( + struct mesh_prog_info *const fds_prog, + const char *const prog_name, + struct bpf_object_open_attr *const prog_attr, + enum bpf_attach_type attach_type, + int attach_fd) { - int ret = EOK; - ret = strcpy_s(fds_prog->name, BPF_OBJ_NAME_LEN, prog_name); - if (ret != EOK) { - macli_log(ERR, "system copy string failed!"); - return FAILED; - } - if (get_prog_fd(fds_prog->name, &(fds_prog->fd)) != SUCCESS) - return FAILED; - fds_prog->attach_type = attach_type; - fds_prog->attach_fd = attach_fd; - fds_prog->xattr = prog_attr; - return SUCCESS; + int ret = EOK; + ret = strcpy_s(fds_prog->name, BPF_OBJ_NAME_LEN, prog_name); + if (ret != EOK) { + macli_log(ERR, "system copy string failed!"); + return FAILED; + } + if (get_prog_fd(fds_prog->name, &(fds_prog->fd)) != SUCCESS) + return FAILED; + fds_prog->attach_type = attach_type; + fds_prog->attach_fd = attach_fd; + fds_prog->xattr = prog_attr; + return SUCCESS; } -static int init_mesh_prog_pin_file(struct mesh_prog_info* const fds_prog, const char* const pin_file_path) +static int init_mesh_prog_pin_file(struct mesh_prog_info *const fds_prog, const char *const pin_file_path) { - int ret = EOK; - ret = strcpy_s(fds_prog->pin_file_path, PATH_MAX, pin_file_path); - if (ret != EOK) { - macli_log(ERR, "system copy string failed!"); - return FAILED; - } + int ret = EOK; + ret = strcpy_s(fds_prog->pin_file_path, PATH_MAX, pin_file_path); + if (ret != EOK) { + macli_log(ERR, "system copy string failed!"); + return FAILED; + } - return SUCCESS; + return SUCCESS; } -int init_fds(struct mesh_service_info* const fds, int cgroup_fd) +int init_fds(struct mesh_service_info *const fds, int cgroup_fd) { - int ret = SUCCESS; - ret += init_mesh_map(&fds->map_fds[MESH_MAP_OPS_MAP], pinmap_file_path[MESH_MAP_OPS_MAP], - to_str(SOCK_OPS_MAP_NAME), &g_sock_ops_map_xattr); + int ret = SUCCESS; + ret += init_mesh_map( + &fds->map_fds[MESH_MAP_OPS_MAP], + pinmap_file_path[MESH_MAP_OPS_MAP], + to_str(SOCK_OPS_MAP_NAME), + &g_sock_ops_map_xattr); #if MDA_GID_UID_FILTER - ret += init_mesh_map(&fds->map_fds[MESH_MAP_OPS_HELPER_MAP], pinmap_file_path[MESH_MAP_OPS_HELPER_MAP], - to_str(SOCK_OPS_HELPER_MAP_NAME), &g_sock_ops_helper_map_xattr); + ret += init_mesh_map( + &fds->map_fds[MESH_MAP_OPS_HELPER_MAP], + pinmap_file_path[MESH_MAP_OPS_HELPER_MAP], + to_str(SOCK_OPS_HELPER_MAP_NAME), + &g_sock_ops_helper_map_xattr); #endif - ret += init_mesh_map(&fds->map_fds[MESH_MAP_OPS_PARAM_MAP], pinmap_file_path[MESH_MAP_OPS_PARAM_MAP], - to_str(SOCK_PARAM_MAP_NAME), &g_sock_param_map_xattr); - ret += init_mesh_map(&fds->map_fds[MESH_MAP_OPS_PROXY_MAP], pinmap_file_path[MESH_MAP_OPS_PROXY_MAP], - to_str(SOCK_OPS_PROXY_MAP_NAME), &g_sock_ops_proxy_map_xattr); - ret += init_mesh_map(&fds->map_fds[MESH_MAP_OPS_DUMP_I_MAP], pinmap_file_path[MESH_MAP_OPS_DUMP_I_MAP], - to_str(SOCK_DUMP_MAP_I_NAME), &g_sock_dump_map); - ret += init_mesh_map(&fds->map_fds[MESH_MAP_OPS_DUMP_DATA_MAP], pinmap_file_path[MESH_MAP_OPS_DUMP_DATA_MAP], - to_str(SOCK_DUMP_CPU_ARRAY_NAME), &g_sock_dump_data_map); - ret += init_mesh_prog(&fds->prog_fds[MESH_PROG_OPS], to_str(SOCK_OPS_NAME), &g_sock_ops_xattr, - BPF_CGROUP_SOCK_OPS, cgroup_fd); - ret += init_mesh_prog_pin_file(&fds->prog_fds[MESH_PROG_OPS], pinprog_file_path[MESH_PROG_OPS]); - ret += init_mesh_prog(&fds->prog_fds[MESH_PROG_REDIRECT], to_str(SOCK_REDIRECT_NAME), &g_sock_redirect_xattr, - BPF_SK_MSG_VERDICT, fds->map_fds[MESH_MAP_OPS_MAP].fd); - ret += init_mesh_prog_pin_file(&fds->prog_fds[MESH_PROG_REDIRECT], pinprog_file_path[MESH_PROG_REDIRECT]); - if (ret != SUCCESS) - return FAILED; - return SUCCESS; + ret += init_mesh_map( + &fds->map_fds[MESH_MAP_OPS_PARAM_MAP], + pinmap_file_path[MESH_MAP_OPS_PARAM_MAP], + to_str(SOCK_PARAM_MAP_NAME), + &g_sock_param_map_xattr); + ret += init_mesh_map( + &fds->map_fds[MESH_MAP_OPS_PROXY_MAP], + pinmap_file_path[MESH_MAP_OPS_PROXY_MAP], + to_str(SOCK_OPS_PROXY_MAP_NAME), + &g_sock_ops_proxy_map_xattr); + ret += init_mesh_map( + &fds->map_fds[MESH_MAP_OPS_DUMP_I_MAP], + pinmap_file_path[MESH_MAP_OPS_DUMP_I_MAP], + to_str(SOCK_DUMP_MAP_I_NAME), + &g_sock_dump_map); + ret += init_mesh_map( + &fds->map_fds[MESH_MAP_OPS_DUMP_DATA_MAP], + pinmap_file_path[MESH_MAP_OPS_DUMP_DATA_MAP], + to_str(SOCK_DUMP_CPU_ARRAY_NAME), + &g_sock_dump_data_map); + ret += init_mesh_prog( + &fds->prog_fds[MESH_PROG_OPS], to_str(SOCK_OPS_NAME), &g_sock_ops_xattr, BPF_CGROUP_SOCK_OPS, cgroup_fd); + ret += init_mesh_prog_pin_file(&fds->prog_fds[MESH_PROG_OPS], pinprog_file_path[MESH_PROG_OPS]); + ret += init_mesh_prog( + &fds->prog_fds[MESH_PROG_REDIRECT], + to_str(SOCK_REDIRECT_NAME), + &g_sock_redirect_xattr, + BPF_SK_MSG_VERDICT, + fds->map_fds[MESH_MAP_OPS_MAP].fd); + ret += init_mesh_prog_pin_file(&fds->prog_fds[MESH_PROG_REDIRECT], pinprog_file_path[MESH_PROG_REDIRECT]); + if (ret != SUCCESS) + return FAILED; + return SUCCESS; } int get_cgroup_root_fd(void) { - int cgroup_fd = ERROR; - FILE* f = fopen("/proc/mounts", "r"); - if (f == NULL) { - macli_log(ERR, "open /proc/mounts failed! search cgroup root path failed! errno:%d\n", errno); - return ERROR; - } + int cgroup_fd = ERROR; + FILE *f = fopen("/proc/mounts", "r"); + if (f == NULL) { + macli_log(ERR, "open /proc/mounts failed! search cgroup root path failed! errno:%d\n", errno); + return ERROR; + } - struct mntent* mnt = NULL; - while ((mnt = getmntent(f)) != NULL) { - if (strcmp(mnt->mnt_type, "cgroup2") != 0) - continue; - cgroup_fd = open(mnt->mnt_dir, O_RDONLY); - if (cgroup_fd < 0) - macli_log(ERR, "cgroup:%s open failed! errno:%d\n", mnt->mnt_dir, errno); - break; - } - if (fclose(f) != 0) - macli_log(ERR, "can not close the file: /proc/mounts!\n"); - if (cgroup_fd < 0) - macli_log(ERR, "maybe you need mount a cgroup2 root\n"); - return cgroup_fd; + struct mntent *mnt = NULL; + while ((mnt = getmntent(f)) != NULL) { + if (strcmp(mnt->mnt_type, "cgroup2") != 0) + continue; + cgroup_fd = open(mnt->mnt_dir, O_RDONLY); + if (cgroup_fd < 0) + macli_log(ERR, "cgroup:%s open failed! errno:%d\n", mnt->mnt_dir, errno); + break; + } + if (fclose(f) != 0) + macli_log(ERR, "can not close the file: /proc/mounts!\n"); + if (cgroup_fd < 0) + macli_log(ERR, "maybe you need mount a cgroup2 root\n"); + return cgroup_fd; } -int get_u32_num(const char* const src, __u32* const ret) +int get_u32_num(const char *const src, __u32 *const ret) { - const int convert_base = 10; - char tmp_buff[TMP_BUF_SIZE] = {0}; - unsigned long tmp = strtoul(src, NULL, convert_base); - if (sprintf_s(tmp_buff, sizeof(tmp_buff), "%lu", tmp) < 0) { - macli_log(ERR, "system sprintf string failed!\n"); - return FAILED; - } - if (strcmp(src, tmp_buff) != 0 || tmp > UINT32_MAX) { - macli_log(ERR, "input num error, need a unsigned 32 bit num! input:%s\n", src); - return FAILED; - } - *ret = (__u32)tmp; - return SUCCESS; + const int convert_base = 10; + char tmp_buff[TMP_BUF_SIZE] = {0}; + unsigned long tmp = strtoul(src, NULL, convert_base); + if (sprintf_s(tmp_buff, sizeof(tmp_buff), "%lu", tmp) < 0) { + macli_log(ERR, "system sprintf string failed!\n"); + return FAILED; + } + if (strcmp(src, tmp_buff) != 0 || tmp > UINT32_MAX) { + macli_log(ERR, "input num error, need a unsigned 32 bit num! input:%s\n", src); + return FAILED; + } + *ret = (__u32)tmp; + return SUCCESS; } -int check_cidr(const char* const src, __u32* const ip, __u32* const mask) +int check_cidr(const char *const src, __u32 *const ip, __u32 *const mask) { - int ret = EOK; - char tmp_buff[MAX_CIDR_LENGTH] = {0}; - if ((ret = strcpy_s(tmp_buff, sizeof(tmp_buff), src)) != EOK) { - macli_log(ERR, "system copy string failed! errno:%d\n", ret); - return FAILED; - } - char* ip_part = tmp_buff; - char* p = strrchr(tmp_buff, '/'); - if (p == NULL) - return FAILED; - *p = '\0'; - char* mask_part = p + 1; + int ret = EOK; + char tmp_buff[MAX_CIDR_LENGTH] = {0}; + if ((ret = strcpy_s(tmp_buff, sizeof(tmp_buff), src)) != EOK) { + macli_log(ERR, "system copy string failed! errno:%d\n", ret); + return FAILED; + } + char *ip_part = tmp_buff; + char *p = strrchr(tmp_buff, '/'); + if (p == NULL) + return FAILED; + *p = '\0'; + char *mask_part = p + 1; - const int max_mask = 32; - struct in_addr dst; - if (inet_pton(AF_INET, ip_part, (void*)&dst) <= 0) - return FAILED; - *ip = ntohl(dst.s_addr); - if (get_u32_num(mask_part, mask) != SUCCESS || *mask > max_mask) - return FAILED; + const int max_mask = 32; + struct in_addr dst; + if (inet_pton(AF_INET, ip_part, (void *)&dst) <= 0) + return FAILED; + *ip = ntohl(dst.s_addr); + if (get_u32_num(mask_part, mask) != SUCCESS || *mask > max_mask) + return FAILED; - return SUCCESS; + return SUCCESS; } -int check_port(const char* const src, __u32* const begin_port, __u32* const end_port) +int check_port(const char *const src, __u32 *const begin_port, __u32 *const end_port) { - int ret = EOK; - char tmp_buff[MAX_PORT_RANGE_LENGTH] = {0}; - if ((ret = strcpy_s(tmp_buff, sizeof(tmp_buff), src)) != EOK) { - macli_log(ERR, "system copy string failed! errno:%d\n", ret); - return FAILED; - } - // support 80-90 - // support 80 - char* num1 = tmp_buff; - const __u32 max_port = 65535; - char* p = strrchr(tmp_buff, '-'); - if (p == NULL) { - if (get_u32_num(num1, begin_port) != SUCCESS) - return FAILED; - if (*begin_port > max_port) { - macli_log(ERR, "ports over range!, max ports is %u, you input:%s\n", max_port, src); - return FAILED; - } - *end_port = *begin_port; - } else { - *p = '\0'; - char* num2 = p + 1; - if (get_u32_num(num1, begin_port) != SUCCESS) - return FAILED; - if (get_u32_num(num2, end_port) != SUCCESS) - return FAILED; - if (*begin_port > max_port || *end_port > max_port) { - macli_log(ERR, "ports over range!, max ports is %u, you input:%s\n", max_port, src); - return FAILED; - } - if (*begin_port > *end_port) { - macli_log(ERR, "end ports large than begin ports! you input:%s\n", src); - return FAILED; - } - } - return SUCCESS; + int ret = EOK; + char tmp_buff[MAX_PORT_RANGE_LENGTH] = {0}; + if ((ret = strcpy_s(tmp_buff, sizeof(tmp_buff), src)) != EOK) { + macli_log(ERR, "system copy string failed! errno:%d\n", ret); + return FAILED; + } + // support 80-90 + // support 80 + char *num1 = tmp_buff; + const __u32 max_port = 65535; + char *p = strrchr(tmp_buff, '-'); + if (p == NULL) { + if (get_u32_num(num1, begin_port) != SUCCESS) + return FAILED; + if (*begin_port > max_port) { + macli_log(ERR, "ports over range!, max ports is %u, you input:%s\n", max_port, src); + return FAILED; + } + *end_port = *begin_port; + } else { + *p = '\0'; + char *num2 = p + 1; + if (get_u32_num(num1, begin_port) != SUCCESS) + return FAILED; + if (get_u32_num(num2, end_port) != SUCCESS) + return FAILED; + if (*begin_port > max_port || *end_port > max_port) { + macli_log(ERR, "ports over range!, max ports is %u, you input:%s\n", max_port, src); + return FAILED; + } + if (*begin_port > *end_port) { + macli_log(ERR, "end ports large than begin ports! you input:%s\n", src); + return FAILED; + } + } + return SUCCESS; } -int get_map_filter_rule(const struct mesh_map_info* const param_map_info, struct sock_param* const param_list) +int get_map_filter_rule(const struct mesh_map_info *const param_map_info, struct sock_param *const param_list) { - int key = 0; - if (bpf_map_lookup_elem(param_map_info->fd, &key, param_list)) { - macli_log(ERR, "look up dump param failed! errno:%d\n", errno); - return FAILED; - } - return SUCCESS; + int key = 0; + if (bpf_map_lookup_elem(param_map_info->fd, &key, param_list)) { + macli_log(ERR, "look up dump param failed! errno:%d\n", errno); + return FAILED; + } + return SUCCESS; } diff --git a/oncn-mda/cli_src/func/log.c b/oncn-mda/cli_src/func/log.c index d007c0a37..b7430958b 100644 --- a/oncn-mda/cli_src/func/log.c +++ b/oncn-mda/cli_src/func/log.c @@ -18,32 +18,26 @@ static const enum LOG_LEVEL level_set = INFO; #define MAX_FMT_STR_LENGTH 2048 -const char log_level_str [][6] = { - "FATAL", - "ERROR", - "WARN", - "INFO", - "DEBUG" -}; +const char log_level_str[][6] = {"FATAL", "ERROR", "WARN", "INFO", "DEBUG"}; static enum LOG_LEVEL get_log_level(void) { - return level_set; + return level_set; } -void ma_log(enum LOG_LEVEL level, const char* format, ...) +void ma_log(enum LOG_LEVEL level, const char *format, ...) { - if (level > get_log_level()) - return; + if (level > get_log_level()) + return; - va_list ap; - va_start(ap, format); - char fmt_str[MAX_FMT_STR_LENGTH] = {0}; - if (vsnprintf_s(fmt_str, sizeof(fmt_str), sizeof(fmt_str) - 1, format, ap) == -1) { - va_end(ap); - return; - } - va_end(ap); + va_list ap; + va_start(ap, format); + char fmt_str[MAX_FMT_STR_LENGTH] = {0}; + if (vsnprintf_s(fmt_str, sizeof(fmt_str), sizeof(fmt_str) - 1, format, ap) == -1) { + va_end(ap); + return; + } + va_end(ap); - (void)fprintf(stderr, "%s", fmt_str); + (void)fprintf(stderr, "%s", fmt_str); } diff --git a/oncn-mda/cli_src/func/query.c b/oncn-mda/cli_src/func/query.c index 9aa5d9fc7..cea76c7c6 100644 --- a/oncn-mda/cli_src/func/query.c +++ b/oncn-mda/cli_src/func/query.c @@ -18,136 +18,131 @@ static void query_usage(void) { - (void)printf("usage: mdacore query {OPTIONS}\n"); - (void)printf(" OPTIONS: -h|--help: print usage\n"); + (void)printf("usage: mdacore query {OPTIONS}\n"); + (void)printf(" OPTIONS: -h|--help: print usage\n"); } -static const struct option query_options[] = { - {"help", no_argument, NULL, 'h'}, - {NULL} -}; +static const struct option query_options[] = {{"help", no_argument, NULL, 'h'}, {NULL}}; -static int query_get_opt(int argc, char* const *argv, bool* const is_help) +static int query_get_opt(int argc, char *const *argv, bool *const is_help) { - optind = 1; - int opt; - while ((opt = getopt_long(argc, argv, "h", query_options, NULL)) >= 0) { - switch (opt) { - case 'h': - query_usage(); - *is_help = true; - break; - case '?': - default: - query_usage(); - return FAILED; - } - } - if (optind != argc) { - macli_log(ERR, "unknown param!\n"); - query_usage(); - return FAILED; - } - return SUCCESS; + optind = 1; + int opt; + while ((opt = getopt_long(argc, argv, "h", query_options, NULL)) >= 0) { + switch (opt) { + case 'h': + query_usage(); + *is_help = true; + break; + case '?': + default: + query_usage(); + return FAILED; + } + } + if (optind != argc) { + macli_log(ERR, "unknown param!\n"); + query_usage(); + return FAILED; + } + return SUCCESS; } -static int get_attach_prog_fd(int attach_fd, enum bpf_attach_type type, const char* const prog_name) +static int get_attach_prog_fd(int attach_fd, enum bpf_attach_type type, const char *const prog_name) { - __u32 prog_ids[10] = {0}; - __u32 prog_cnt = 10; - if (attach_fd < 0) - return ERROR; - if (bpf_prog_query(attach_fd, type, 0, NULL, prog_ids, &prog_cnt)) { - macli_log(ERR, "bpf prog query failed! errno:%d\n", errno); - return ERROR; - } - for (__u32 iter = 0; iter < prog_cnt; ++iter) { - struct bpf_prog_info info = {}; - __u32 info_len = sizeof(info); - int prog_fd = bpf_prog_get_fd_by_id(prog_ids[iter]); - if (prog_fd < 0) { - macli_log(ERR, "get prog fd failed! errno:%d\n", errno); - return ERROR; - } - if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) { - macli_log(ERR, "read bpf info failed! errno:%d\n", errno); - (void)close(prog_fd); - return ERROR; - } - if (strcmp(info.name, prog_name) == 0) - return prog_fd; - (void)close(prog_fd); - } - return ERROR; + __u32 prog_ids[10] = {0}; + __u32 prog_cnt = 10; + if (attach_fd < 0) + return ERROR; + if (bpf_prog_query(attach_fd, type, 0, NULL, prog_ids, &prog_cnt)) { + macli_log(ERR, "bpf prog query failed! errno:%d\n", errno); + return ERROR; + } + for (__u32 iter = 0; iter < prog_cnt; ++iter) { + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); + int prog_fd = bpf_prog_get_fd_by_id(prog_ids[iter]); + if (prog_fd < 0) { + macli_log(ERR, "get prog fd failed! errno:%d\n", errno); + return ERROR; + } + if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) { + macli_log(ERR, "read bpf info failed! errno:%d\n", errno); + (void)close(prog_fd); + return ERROR; + } + if (strcmp(info.name, prog_name) == 0) + return prog_fd; + (void)close(prog_fd); + } + return ERROR; } -static int query_prog_attach(int attach_fd, enum bpf_attach_type type, const char* const prog_name) +static int query_prog_attach(int attach_fd, enum bpf_attach_type type, const char *const prog_name) { - /* - * query whether an EBPF program is mounted under a FD - * param: attach_fd: The mounted FD can be a Cgroup FD or a Map FD - * type: mount type - * prog_name: ebpf program name - */ - int fd = get_attach_prog_fd(attach_fd, type, prog_name); - if (fd < 0) - return FALSE; - (void)close(fd); - return TRUE; + /* + * query whether an EBPF program is mounted under a FD + * param: attach_fd: The mounted FD can be a Cgroup FD or a Map FD + * type: mount type + * prog_name: ebpf program name + */ + int fd = get_attach_prog_fd(attach_fd, type, prog_name); + if (fd < 0) + return FALSE; + (void)close(fd); + return TRUE; } -int check_accelerating_on(const struct mesh_service_info* const fds) +int check_accelerating_on(const struct mesh_service_info *const fds) { - /* - * Check that the acceleration function is enabled - * param: struct mesh_service_info - * return: TRUE - * FALSE - * ERROR - */ - unsigned int success_num = 0; - for (unsigned int i = 0; i < MESH_PROG_NUM; ++i) { - if (query_prog_attach(fds->prog_fds[i].attach_fd, - fds->prog_fds[i].attach_type, - fds->prog_fds[i].name) == TRUE) - success_num++; - } - if (success_num == 0) - return FALSE; - else if (success_num == MESH_PROG_NUM) - return TRUE; - return ERROR; + /* + * Check that the acceleration function is enabled + * param: struct mesh_service_info + * return: TRUE + * FALSE + * ERROR + */ + unsigned int success_num = 0; + for (unsigned int i = 0; i < MESH_PROG_NUM; ++i) { + if (query_prog_attach(fds->prog_fds[i].attach_fd, fds->prog_fds[i].attach_type, fds->prog_fds[i].name) == TRUE) + success_num++; + } + if (success_num == 0) + return FALSE; + else if (success_num == MESH_PROG_NUM) + return TRUE; + return ERROR; } -int do_query(int argc, char* const *argv) +int do_query(int argc, char *const *argv) { - bool is_help = false; - if (query_get_opt(argc, argv, &is_help)) - return ERROR; + bool is_help = false; + if (query_get_opt(argc, argv, &is_help)) + return ERROR; - if (is_help) - return SUCCESS; + if (is_help) + return SUCCESS; - int cgroup_fd = get_cgroup_root_fd(); - if (cgroup_fd < 0) { - macli_log(ERR, "query failed!\n"); - return ERROR; - } + int cgroup_fd = get_cgroup_root_fd(); + if (cgroup_fd < 0) { + macli_log(ERR, "query failed!\n"); + return ERROR; + } - struct mesh_service_info fds; - if (init_fds(&fds, cgroup_fd) != SUCCESS) { - close_fds(cgroup_fd, &fds); - return ERROR; - } + struct mesh_service_info fds; + if (init_fds(&fds, cgroup_fd) != SUCCESS) { + close_fds(cgroup_fd, &fds); + return ERROR; + } - int ret = check_accelerating_on(&fds); - close_fds(cgroup_fd, &fds); - if (ret == TRUE) - macli_log(INFO, "serviceMesh accelerating is enabled!\n"); - else if (ret == FALSE) - macli_log(INFO, "serviceMesh accelerating is disabled!\n"); - else - macli_log(INFO, "serviceMesh accelerating get some error!\n"); + int ret = check_accelerating_on(&fds); + close_fds(cgroup_fd, &fds); + if (ret == TRUE) + macli_log(INFO, "serviceMesh accelerating is enabled!\n"); + else if (ret == FALSE) + macli_log(INFO, "serviceMesh accelerating is disabled!\n"); + else + macli_log(INFO, "serviceMesh accelerating get some error!\n"); - return ret; + return ret; } diff --git a/oncn-mda/cli_src/func/switch.c b/oncn-mda/cli_src/func/switch.c index 2ee696f98..cab2723b4 100644 --- a/oncn-mda/cli_src/func/switch.c +++ b/oncn-mda/cli_src/func/switch.c @@ -21,599 +21,591 @@ #define MAX_BUFSIZE 2048 static const struct option g_enable_options[] = { - {"config", required_argument, NULL, 'c'}, - {"help", no_argument, NULL, 'h'}, - {NULL} -}; + {"config", required_argument, NULL, 'c'}, {"help", no_argument, NULL, 'h'}, {NULL}}; -static const struct option g_disable_options[] = { - {"help", no_argument, NULL, 'h'}, - {NULL} -}; +static const struct option g_disable_options[] = {{"help", no_argument, NULL, 'h'}, {NULL}}; static int set_rlimit(void) { - struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; + struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; - if (setrlimit(RLIMIT_MEMLOCK, &r) != 0) { - macli_log(ERR, "setrlimit(RLIMIT_MEMLOCK) failed!, errno:%d\n", errno); - return FAILED; - } - return SUCCESS; + if (setrlimit(RLIMIT_MEMLOCK, &r) != 0) { + macli_log(ERR, "setrlimit(RLIMIT_MEMLOCK) failed!, errno:%d\n", errno); + return FAILED; + } + return SUCCESS; } -static void del_sock_file(const struct mesh_service_info* const fds) +static void del_sock_file(const struct mesh_service_info *const fds) { - for (unsigned int i = 0; i < MESH_PROG_NUM; ++i) { - if (remove(fds->prog_fds[i].pin_file_path) && errno != ENOENT) - macli_log(WARN, "delete the pinned file:%s failed! errno:%d, please delete manual\n", - fds->prog_fds[i].pin_file_path, errno); - } - for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { - if (remove(fds->map_fds[i].pin_file_path) && errno != ENOENT) - macli_log(WARN, "delete the pinned file:%s failed! errno:%d, please delete manual\n", - fds->map_fds[i].pin_file_path, errno); - } - if (remove(BPF_PIN_FOLDER) && errno != ENOENT) - macli_log(WARN, "delete the pinned file:%s failed! errno:%d, please delete manual\n", - BPF_PIN_FOLDER, errno); + for (unsigned int i = 0; i < MESH_PROG_NUM; ++i) { + if (remove(fds->prog_fds[i].pin_file_path) && errno != ENOENT) + macli_log( + WARN, + "delete the pinned file:%s failed! errno:%d, please delete manual\n", + fds->prog_fds[i].pin_file_path, + errno); + } + for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { + if (remove(fds->map_fds[i].pin_file_path) && errno != ENOENT) + macli_log( + WARN, + "delete the pinned file:%s failed! errno:%d, please delete manual\n", + fds->map_fds[i].pin_file_path, + errno); + } + if (remove(BPF_PIN_FOLDER) && errno != ENOENT) + macli_log(WARN, "delete the pinned file:%s failed! errno:%d, please delete manual\n", BPF_PIN_FOLDER, errno); } -void close_fds(int cgroup_fd, const struct mesh_service_info* const fds) +void close_fds(int cgroup_fd, const struct mesh_service_info *const fds) { - for (unsigned int i = 0; i < MESH_PROG_NUM; ++i) { - if (fds->prog_fds[i].fd > 0) - (void)close(fds->prog_fds[i].fd); - } - for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { - if (fds->map_fds[i].fd > 0) - (void)close(fds->map_fds[i].fd); - } - (void)close(cgroup_fd); - if (fds->prog_fds[MESH_PROG_REDIRECT].attach_fd != fds->map_fds[MESH_MAP_OPS_MAP].fd) - (void)close(fds->prog_fds[MESH_PROG_REDIRECT].attach_fd); + for (unsigned int i = 0; i < MESH_PROG_NUM; ++i) { + if (fds->prog_fds[i].fd > 0) + (void)close(fds->prog_fds[i].fd); + } + for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { + if (fds->map_fds[i].fd > 0) + (void)close(fds->map_fds[i].fd); + } + (void)close(cgroup_fd); + if (fds->prog_fds[MESH_PROG_REDIRECT].attach_fd != fds->map_fds[MESH_MAP_OPS_MAP].fd) + (void)close(fds->prog_fds[MESH_PROG_REDIRECT].attach_fd); } -static struct bpf_object* get_program_object(struct mesh_prog_info* const prog_info) +static struct bpf_object *get_program_object(struct mesh_prog_info *const prog_info) { - if (access(prog_info->xattr->file, R_OK)) { - macli_log(ERR, "object file miss! please reinstall the rpm package!\n"); - return NULL; - } - - struct bpf_object* obj = bpf_object__open_xattr(prog_info->xattr); - if (obj == NULL) { - macli_log(ERR, "can not open bpf program, path:%s, errno:%d\n", - prog_info->xattr->file, errno); - return NULL; - } - return obj; + if (access(prog_info->xattr->file, R_OK)) { + macli_log(ERR, "object file miss! please reinstall the rpm package!\n"); + return NULL; + } + + struct bpf_object *obj = bpf_object__open_xattr(prog_info->xattr); + if (obj == NULL) { + macli_log(ERR, "can not open bpf program, path:%s, errno:%d\n", prog_info->xattr->file, errno); + return NULL; + } + return obj; } -static int set_program_type(const struct mesh_prog_info* const prog_info, const struct bpf_object* const obj) +static int set_program_type(const struct mesh_prog_info *const prog_info, const struct bpf_object *const obj) { - enum bpf_prog_type prog_type = prog_info->xattr->prog_type; - enum bpf_attach_type expected_attach_type = prog_info->attach_type; - struct bpf_program* pos = bpf_program__next(NULL, obj); - if (pos == NULL) { - macli_log(ERR, "obj:%s not contain a ebpf program!\n", prog_info->xattr->file); - return FAILED; - } - bpf_program__set_type(pos, prog_type); - bpf_program__set_expected_attach_type(pos, expected_attach_type); - return SUCCESS; + enum bpf_prog_type prog_type = prog_info->xattr->prog_type; + enum bpf_attach_type expected_attach_type = prog_info->attach_type; + struct bpf_program *pos = bpf_program__next(NULL, obj); + if (pos == NULL) { + macli_log(ERR, "obj:%s not contain a ebpf program!\n", prog_info->xattr->file); + return FAILED; + } + bpf_program__set_type(pos, prog_type); + bpf_program__set_expected_attach_type(pos, expected_attach_type); + return SUCCESS; } -static int reuse_program_map(const struct mesh_service_info* const fds, const struct bpf_object* const obj) +static int reuse_program_map(const struct mesh_service_info *const fds, const struct bpf_object *const obj) { - struct bpf_map* map = NULL; - bpf_map__for_each(map, obj) { - for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { - if (strcmp(bpf_map__name(map), fds->map_fds[i].name)) - continue; - if (bpf_map__reuse_fd(map, fds->map_fds[i].fd)) { - macli_log(ERR, "map:%s reused failed! errno:%d\n", fds->map_fds[i].name, errno); - return FAILED; - } - } - } - return SUCCESS; + struct bpf_map *map = NULL; + bpf_map__for_each(map, obj) + { + for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { + if (strcmp(bpf_map__name(map), fds->map_fds[i].name)) + continue; + if (bpf_map__reuse_fd(map, fds->map_fds[i].fd)) { + macli_log(ERR, "map:%s reused failed! errno:%d\n", fds->map_fds[i].name, errno); + return FAILED; + } + } + } + return SUCCESS; } -static int pinned_program_file(const struct mesh_prog_info* const prog_info, struct bpf_object* const obj) +static int pinned_program_file(const struct mesh_prog_info *const prog_info, struct bpf_object *const obj) { - struct bpf_program* prog = NULL; - if (bpf_object__load(obj) != 0) { - macli_log(ERR, "open bpf obj:%s failed! errno:%d\n", prog_info->xattr->file, errno); - return FAILED; - } - prog = bpf_program__next(NULL, obj); - if (!prog) { - macli_log(ERR, "object file:%s doesn't contain any bpf program\n", prog_info->xattr->file); - return FAILED; - } - - int fd = bpf_program__fd(prog); - if (fd < 0) { - macli_log(ERR, "get program %s fd failed! errno:%d\n", prog_info->name, errno); - return FAILED; - } - - if (bpf_obj_pin(fd, prog_info->pin_file_path)) { - macli_log(ERR, "pin file %s failed! errno:%d\n", prog_info->xattr->file, errno); - return FAILED; - } - return SUCCESS; + struct bpf_program *prog = NULL; + if (bpf_object__load(obj) != 0) { + macli_log(ERR, "open bpf obj:%s failed! errno:%d\n", prog_info->xattr->file, errno); + return FAILED; + } + prog = bpf_program__next(NULL, obj); + if (!prog) { + macli_log(ERR, "object file:%s doesn't contain any bpf program\n", prog_info->xattr->file); + return FAILED; + } + + int fd = bpf_program__fd(prog); + if (fd < 0) { + macli_log(ERR, "get program %s fd failed! errno:%d\n", prog_info->name, errno); + return FAILED; + } + + if (bpf_obj_pin(fd, prog_info->pin_file_path)) { + macli_log(ERR, "pin file %s failed! errno:%d\n", prog_info->xattr->file, errno); + return FAILED; + } + return SUCCESS; } -static int create_program_and_pinned(struct mesh_prog_info* const prog_info, - const struct mesh_service_info* const fds) +static int create_program_and_pinned(struct mesh_prog_info *const prog_info, const struct mesh_service_info *const fds) { - struct bpf_object* obj = get_program_object(prog_info); - if (obj == NULL) - goto FAIL; - if (set_program_type(prog_info, obj) != SUCCESS) - goto FAIL; - - if (reuse_program_map(fds, obj) != SUCCESS) - goto FAIL; - - if (pinned_program_file(prog_info, obj) != SUCCESS) - goto FAIL; - bpf_object__close(obj); - return SUCCESS; + struct bpf_object *obj = get_program_object(prog_info); + if (obj == NULL) + goto FAIL; + if (set_program_type(prog_info, obj) != SUCCESS) + goto FAIL; + + if (reuse_program_map(fds, obj) != SUCCESS) + goto FAIL; + + if (pinned_program_file(prog_info, obj) != SUCCESS) + goto FAIL; + bpf_object__close(obj); + return SUCCESS; FAIL: - bpf_object__close(obj); - return FAILED; + bpf_object__close(obj); + return FAILED; } -static int create_map(struct mesh_service_info* const fds) +static int create_map(struct mesh_service_info *const fds) { - for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { - if (fds->map_fds[i].fd == -1) { - fds->map_fds[i].fd = bpf_create_map_xattr(fds->map_fds[i].xattr); - if (fds->map_fds[i].fd < 0) { - macli_log(ERR, "create %s failed! errno:%d\n", fds->map_fds[i].name, errno); - return FAILED; - } - } - if (access(fds->map_fds[i].pin_file_path, W_OK) == 0) - continue; - if (bpf_obj_pin(fds->map_fds[i].fd, fds->map_fds[i].pin_file_path)) { - macli_log(ERR, "pin bpf map file:%s failed! errno:%d\n", - fds->map_fds[i].pin_file_path, errno); - return FAILED; - } - } - return SUCCESS; + for (unsigned int i = 0; i < MESH_MAP_NUM; ++i) { + if (fds->map_fds[i].fd == -1) { + fds->map_fds[i].fd = bpf_create_map_xattr(fds->map_fds[i].xattr); + if (fds->map_fds[i].fd < 0) { + macli_log(ERR, "create %s failed! errno:%d\n", fds->map_fds[i].name, errno); + return FAILED; + } + } + if (access(fds->map_fds[i].pin_file_path, W_OK) == 0) + continue; + if (bpf_obj_pin(fds->map_fds[i].fd, fds->map_fds[i].pin_file_path)) { + macli_log(ERR, "pin bpf map file:%s failed! errno:%d\n", fds->map_fds[i].pin_file_path, errno); + return FAILED; + } + } + return SUCCESS; } -static int load_program(struct mesh_service_info* const fds) +static int load_program(struct mesh_service_info *const fds) { - for (unsigned int i = MESH_PROG_OPS; i < MESH_PROG_NUM; ++i) { - if (fds->prog_fds[i].fd == -1) { - if (create_program_and_pinned(&fds->prog_fds[i], fds) != SUCCESS) - return FAILED; - fds->prog_fds[i].fd = bpf_obj_get(fds->prog_fds[i].pin_file_path); - } - // redirect mount on map - if (strcmp(fds->prog_fds[i].name, to_str(SOCK_REDIRECT_NAME)) == 0) - fds->prog_fds[i].attach_fd = fds->map_fds[MESH_MAP_OPS_MAP].fd; - if (access(fds->prog_fds[i].pin_file_path, W_OK) == 0) - continue; - if (bpf_obj_pin(fds->prog_fds[i].fd, fds->prog_fds[i].pin_file_path)) { - macli_log(ERR, "pin file %s failed! errno:%d\n", fds->prog_fds[i].pin_file_path, errno); - return FAILED; - } - } - return SUCCESS; + for (unsigned int i = MESH_PROG_OPS; i < MESH_PROG_NUM; ++i) { + if (fds->prog_fds[i].fd == -1) { + if (create_program_and_pinned(&fds->prog_fds[i], fds) != SUCCESS) + return FAILED; + fds->prog_fds[i].fd = bpf_obj_get(fds->prog_fds[i].pin_file_path); + } + // redirect mount on map + if (strcmp(fds->prog_fds[i].name, to_str(SOCK_REDIRECT_NAME)) == 0) + fds->prog_fds[i].attach_fd = fds->map_fds[MESH_MAP_OPS_MAP].fd; + if (access(fds->prog_fds[i].pin_file_path, W_OK) == 0) + continue; + if (bpf_obj_pin(fds->prog_fds[i].fd, fds->prog_fds[i].pin_file_path)) { + macli_log(ERR, "pin file %s failed! errno:%d\n", fds->prog_fds[i].pin_file_path, errno); + return FAILED; + } + } + return SUCCESS; } -static int attach_program(const struct mesh_service_info* const fds) +static int attach_program(const struct mesh_service_info *const fds) { - unsigned int flags; - for (int i = (int)MESH_PROG_NUM - 1; i >= 0; --i) { - flags = 0; - if (strcmp(fds->prog_fds[i].name, to_str(SOCK_OPS_NAME)) == 0) - flags = BPF_F_ALLOW_MULTI; - if (bpf_prog_attach(fds->prog_fds[i].fd, fds->prog_fds[i].attach_fd, - fds->prog_fds[i].attach_type, flags)) { - macli_log(ERR, "failed to attach %s, errno:%d\n", - fds->prog_fds[i].pin_file_path, errno); - return FAILED; - } - } - return SUCCESS; + unsigned int flags; + for (int i = (int)MESH_PROG_NUM - 1; i >= 0; --i) { + flags = 0; + if (strcmp(fds->prog_fds[i].name, to_str(SOCK_OPS_NAME)) == 0) + flags = BPF_F_ALLOW_MULTI; + if (bpf_prog_attach(fds->prog_fds[i].fd, fds->prog_fds[i].attach_fd, fds->prog_fds[i].attach_type, flags)) { + macli_log(ERR, "failed to attach %s, errno:%d\n", fds->prog_fds[i].pin_file_path, errno); + return FAILED; + } + } + return SUCCESS; } -static int detach_program(const struct mesh_service_info* const fds) +static int detach_program(const struct mesh_service_info *const fds) { - for (int i = (int)MESH_PROG_NUM - 1; i >= 0; --i) { - // if prog fd == -1,If attach fd is -1, detach is not mounted - if (fds->prog_fds[i].fd != -1 && fds->prog_fds[i].attach_fd != -1) { - if (bpf_prog_detach2(fds->prog_fds[i].fd, - fds->prog_fds[i].attach_fd, - fds->prog_fds[i].attach_type) && errno != ENOENT) { - macli_log(ERR, "failed to detach %s, errno:%d\n", fds->prog_fds[i].name, errno); - return FAILED; - } - } - } - return SUCCESS; + for (int i = (int)MESH_PROG_NUM - 1; i >= 0; --i) { + // if prog fd == -1,If attach fd is -1, detach is not mounted + if (fds->prog_fds[i].fd != -1 && fds->prog_fds[i].attach_fd != -1) { + if (bpf_prog_detach2(fds->prog_fds[i].fd, fds->prog_fds[i].attach_fd, fds->prog_fds[i].attach_type) + && errno != ENOENT) { + macli_log(ERR, "failed to detach %s, errno:%d\n", fds->prog_fds[i].name, errno); + return FAILED; + } + } + } + return SUCCESS; } static void enable_usage(void) { - (void)printf("usage: mdacore enable {OPTIONS}\n"); - (void)printf(" OPTIONS: -c|--config: config path,eg:/etc/oncn-mda/oncn-mda.conf\n"); - (void)printf(" OPTIONS: -h|--help: print usage\n"); + (void)printf("usage: mdacore enable {OPTIONS}\n"); + (void)printf(" OPTIONS: -c|--config: config path,eg:/etc/oncn-mda/oncn-mda.conf\n"); + (void)printf(" OPTIONS: -h|--help: print usage\n"); } -static int enable_get_opt(int argc, char* const *argv, char* const config_path, bool* const is_help) +static int enable_get_opt(int argc, char *const *argv, char *const config_path, bool *const is_help) { - int opt; - while ((opt = getopt_long(argc, argv, "c:h", g_enable_options, NULL)) >= 0) { - switch (opt) { - case 'c': - if (realpath(optarg, config_path) == NULL) { - macli_log(ERR, "input config path %s error! errno:%d\n", optarg, errno); - return FAILED; - } - break; - case 'h': - enable_usage(); - *is_help = true; - break; - case '?': - default: - enable_usage(); - return FAILED; - } - } - if (optind != argc) { - macli_log(ERR, "unknown param!\n"); - enable_usage(); - return FAILED; - } - return SUCCESS; + int opt; + while ((opt = getopt_long(argc, argv, "c:h", g_enable_options, NULL)) >= 0) { + switch (opt) { + case 'c': + if (realpath(optarg, config_path) == NULL) { + macli_log(ERR, "input config path %s error! errno:%d\n", optarg, errno); + return FAILED; + } + break; + case 'h': + enable_usage(); + *is_help = true; + break; + case '?': + default: + enable_usage(); + return FAILED; + } + } + if (optind != argc) { + macli_log(ERR, "unknown param!\n"); + enable_usage(); + return FAILED; + } + return SUCCESS; } static void disable_usage(void) { - (void)printf("usage: mdacore disable\n"); - (void)printf(" OPTIONS: -h|--help: print usage\n"); + (void)printf("usage: mdacore disable\n"); + (void)printf(" OPTIONS: -h|--help: print usage\n"); } -static int disable_get_opt(int argc, char* const *argv, bool* const is_help) +static int disable_get_opt(int argc, char *const *argv, bool *const is_help) { - int opt; - while ((opt = getopt_long(argc, argv, "h", g_disable_options, NULL)) >= 0) { - switch (opt) { - case 'h': - disable_usage(); - *is_help = true; - break; - case '?': - default: - disable_usage(); - return FAILED; - } - } - if (optind != argc) { - macli_log(ERR, "unknown param!\n"); - disable_usage(); - } - return SUCCESS; + int opt; + while ((opt = getopt_long(argc, argv, "h", g_disable_options, NULL)) >= 0) { + switch (opt) { + case 'h': + disable_usage(); + *is_help = true; + break; + case '?': + default: + disable_usage(); + return FAILED; + } + } + if (optind != argc) { + macli_log(ERR, "unknown param!\n"); + disable_usage(); + } + return SUCCESS; } -static int update_param_map(const struct sock_param* const filter_rules, const struct mesh_service_info* const fds) +static int update_param_map(const struct sock_param *const filter_rules, const struct mesh_service_info *const fds) { - int key = 0; - if (bpf_map_update_elem(fds->map_fds[MESH_MAP_OPS_PARAM_MAP].fd, - &key, filter_rules, BPF_ANY)) { - macli_log(ERR, "key:%d, errno:%d\n", key, errno); - return FAILED; - } - return SUCCESS; + int key = 0; + if (bpf_map_update_elem(fds->map_fds[MESH_MAP_OPS_PARAM_MAP].fd, &key, filter_rules, BPF_ANY)) { + macli_log(ERR, "key:%d, errno:%d\n", key, errno); + return FAILED; + } + return SUCCESS; } -static int parser_arg(char* const buff, int buff_length, int* const chain_argc, char* chain_argv[]) +static int parser_arg(char *const buff, int buff_length, int *const chain_argc, char *chain_argv[]) { - char* p = buff; - bool is_new_string = true; - for (; p - buff < buff_length; ++p) { - if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') { - is_new_string = true; - *p = '\0'; - continue; - } - if (*chain_argc == MAX_INPUT - 1) { - macli_log(ERR, "Too many configuration items!\n"); - return FAILED; - } - if (is_new_string) { - chain_argv[(*chain_argc)++] = p; - is_new_string = false; - } - } - return SUCCESS; + char *p = buff; + bool is_new_string = true; + for (; p - buff < buff_length; ++p) { + if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') { + is_new_string = true; + *p = '\0'; + continue; + } + if (*chain_argc == MAX_INPUT - 1) { + macli_log(ERR, "Too many configuration items!\n"); + return FAILED; + } + if (is_new_string) { + chain_argv[(*chain_argc)++] = p; + is_new_string = false; + } + } + return SUCCESS; } -static void init_dump_param(struct dump_prarm* const filter_rules) +static void init_dump_param(struct dump_prarm *const filter_rules) { - filter_rules->current_cidr_num = 0; - filter_rules->current_port_num = 0; - filter_rules->switch_on = FALSE; + filter_rules->current_cidr_num = 0; + filter_rules->current_port_num = 0; + filter_rules->switch_on = FALSE; } -static int check_file_access(const char* const config_path) +static int check_file_access(const char *const config_path) { - struct stat buf; - if (lstat(config_path, &buf) < 0) { - macli_log(ERR, "check config path %s failed!\n", config_path); - return FAILED; - } - if (!S_ISREG(buf.st_mode)) { - macli_log(ERR, "the config you input is not a text file!\n"); - return FAILED; - } - // Check whether configuration file permissions are unique to root - if (((buf.st_mode) & (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH)) != 0) { - macli_log(ERR, "the config you input not unique to root, please modify permission of the config\n"); - return FAILED; - } - return SUCCESS; + struct stat buf; + if (lstat(config_path, &buf) < 0) { + macli_log(ERR, "check config path %s failed!\n", config_path); + return FAILED; + } + if (!S_ISREG(buf.st_mode)) { + macli_log(ERR, "the config you input is not a text file!\n"); + return FAILED; + } + // Check whether configuration file permissions are unique to root + if (((buf.st_mode) & (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH)) != 0) { + macli_log(ERR, "the config you input not unique to root, please modify permission of the config\n"); + return FAILED; + } + return SUCCESS; } -static int read_chain_config(const char* const config_path, struct sock_param* const filter_rules) +static int read_chain_config(const char *const config_path, struct sock_param *const filter_rules) { - int ret; - if (check_file_access(config_path) != SUCCESS) - return FAILED; - FILE* config_file = fopen(config_path, "r"); - if (config_file == NULL) { - macli_log(ERR, "can not open the config file! path:%s, errno:%d\n", config_path, errno); - return FAILED; - } - char buf[MAX_BUFSIZE] = {0}; - char buf_save[MAX_BUFSIZE] = {0}; - while (fgets(buf, sizeof(buf), config_file) != NULL) { - // check is it begin with "#" - char* p = buf; - while (((p - buf) < MAX_BUFSIZE - 1) && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) - p++; - // fgets guarantees the last char is '\0' - if (*p == '#' || *p == '\0') - continue; - - if ((ret = strcpy_s(buf_save, sizeof(buf_save), buf)) != EOK) { - macli_log(ERR, "system copy string failed! errno:%d\n", ret); - continue; - } - char* chain_argv[MAX_INPUT] = {0}; - int chain_argc = 0; - if (parser_arg(buf, (int)strlen(buf), &chain_argc, chain_argv) != SUCCESS) - goto err; - if (do_chain(chain_argc, chain_argv, filter_rules) != SUCCESS) { - macli_log(ERR, "error input param:%s\n", buf_save); - goto err; - } - } - - if (fclose(config_file) != 0) - macli_log(ERR, "close config file failed!\n"); - return SUCCESS; - - err: - if (fclose(config_file)) - macli_log(ERR, "close config file failed!\n"); - return FAILED; + int ret; + if (check_file_access(config_path) != SUCCESS) + return FAILED; + FILE *config_file = fopen(config_path, "r"); + if (config_file == NULL) { + macli_log(ERR, "can not open the config file! path:%s, errno:%d\n", config_path, errno); + return FAILED; + } + char buf[MAX_BUFSIZE] = {0}; + char buf_save[MAX_BUFSIZE] = {0}; + while (fgets(buf, sizeof(buf), config_file) != NULL) { + // check is it begin with "#" + char *p = buf; + while (((p - buf) < MAX_BUFSIZE - 1) && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) + p++; + // fgets guarantees the last char is '\0' + if (*p == '#' || *p == '\0') + continue; + + if ((ret = strcpy_s(buf_save, sizeof(buf_save), buf)) != EOK) { + macli_log(ERR, "system copy string failed! errno:%d\n", ret); + continue; + } + char *chain_argv[MAX_INPUT] = {0}; + int chain_argc = 0; + if (parser_arg(buf, (int)strlen(buf), &chain_argc, chain_argv) != SUCCESS) + goto err; + if (do_chain(chain_argc, chain_argv, filter_rules) != SUCCESS) { + macli_log(ERR, "error input param:%s\n", buf_save); + goto err; + } + } + + if (fclose(config_file) != 0) + macli_log(ERR, "close config file failed!\n"); + return SUCCESS; + +err: + if (fclose(config_file)) + macli_log(ERR, "close config file failed!\n"); + return FAILED; } -static int enable_service(struct mesh_service_info* fds, const struct sock_param* const filter_rules) +static int enable_service(struct mesh_service_info *fds, const struct sock_param *const filter_rules) { - /* - * start ServiceMesh acclerating - * param: fds:ServiceMesh's map collection - * filter_rules: - * return: SUCCESS - * FAILED - */ - if (update_param_map(filter_rules, fds) != SUCCESS) { - macli_log(ERR, "update the param map failed!\n"); - return FAILED; - } - - if (load_program(fds) != SUCCESS) { - macli_log(ERR, "load program failed!\n"); - return FAILED; - } - - if (attach_program(fds) != SUCCESS) { - macli_log(ERR, "program attach cgroup2 failed!\n"); - return FAILED; - } - return SUCCESS; + /* + * start ServiceMesh acclerating + * param: fds:ServiceMesh's map collection + * filter_rules: + * return: SUCCESS + * FAILED + */ + if (update_param_map(filter_rules, fds) != SUCCESS) { + macli_log(ERR, "update the param map failed!\n"); + return FAILED; + } + + if (load_program(fds) != SUCCESS) { + macli_log(ERR, "load program failed!\n"); + return FAILED; + } + + if (attach_program(fds) != SUCCESS) { + macli_log(ERR, "program attach cgroup2 failed!\n"); + return FAILED; + } + return SUCCESS; } static int create_accelerate_fold(void) { - /* - * Create a place directory for pin files to be used for acceleration - * param: NA - * return SUCCESS - * FAILED - */ - if (access(BPF_PIN_FOLDER, W_OK) == 0) - return SUCCESS; - if (errno != ENOENT) { - macli_log(ERR, "can not write the folder %s, errno:%d\n", BPF_PIN_FOLDER, errno); - return FAILED; - } - if (mkdir(BPF_PIN_FOLDER, S_IRWXU)) { - macli_log(ERR, "can not create the folder %s, errno:%d\n", BPF_PIN_FOLDER, errno); - return FAILED; - } - return SUCCESS; + /* + * Create a place directory for pin files to be used for acceleration + * param: NA + * return SUCCESS + * FAILED + */ + if (access(BPF_PIN_FOLDER, W_OK) == 0) + return SUCCESS; + if (errno != ENOENT) { + macli_log(ERR, "can not write the folder %s, errno:%d\n", BPF_PIN_FOLDER, errno); + return FAILED; + } + if (mkdir(BPF_PIN_FOLDER, S_IRWXU)) { + macli_log(ERR, "can not create the folder %s, errno:%d\n", BPF_PIN_FOLDER, errno); + return FAILED; + } + return SUCCESS; } -static int clean_proxy_map(const struct mesh_service_info* const fds) +static int clean_proxy_map(const struct mesh_service_info *const fds) { - /* - * Clear the remaining data in the Sock proxy map to preventing data residue - * param: serviceMesh’s map prog infomation - * return: SUCCESS - * FAILED - */ - if (fds->map_fds[MESH_MAP_OPS_MAP].fd < 0) - return SUCCESS; - struct sock_key* prev_ey = NULL; - struct sock_key key; - while (bpf_map_get_next_key(fds->map_fds[MESH_MAP_OPS_PROXY_MAP].fd, prev_ey, &key) == 0) { - prev_ey = &key; - if (bpf_map_delete_elem(fds->map_fds[MESH_MAP_OPS_PROXY_MAP].fd, &key) && errno != ENOENT) { - macli_log(ERR, "can not delete the key! errno:%d\n", errno); - return FAILED; - } - } - if (errno != ENOENT) { - macli_log(ERR, "clean the map key failed! errno:%d\n", errno); - return FAILED; - } - return SUCCESS; + /* + * Clear the remaining data in the Sock proxy map to preventing data residue + * param: serviceMesh’s map prog infomation + * return: SUCCESS + * FAILED + */ + if (fds->map_fds[MESH_MAP_OPS_MAP].fd < 0) + return SUCCESS; + struct sock_key *prev_ey = NULL; + struct sock_key key; + while (bpf_map_get_next_key(fds->map_fds[MESH_MAP_OPS_PROXY_MAP].fd, prev_ey, &key) == 0) { + prev_ey = &key; + if (bpf_map_delete_elem(fds->map_fds[MESH_MAP_OPS_PROXY_MAP].fd, &key) && errno != ENOENT) { + macli_log(ERR, "can not delete the key! errno:%d\n", errno); + return FAILED; + } + } + if (errno != ENOENT) { + macli_log(ERR, "clean the map key failed! errno:%d\n", errno); + return FAILED; + } + return SUCCESS; } -static void reset_filter_rules(struct sock_param* const filter_rules, const struct sock_param* const old_param) +static void reset_filter_rules(struct sock_param *const filter_rules, const struct sock_param *const old_param) { - filter_rules->dump_params.switch_on = (*old_param).dump_params.switch_on; - filter_rules->dump_params.current_cidr_num = (*old_param).dump_params.current_cidr_num; - filter_rules->dump_params.current_port_num = (*old_param).dump_params.current_port_num; - for (int i = 0; i < (*old_param).dump_params.current_cidr_num; ++i) { - filter_rules->dump_params.dump_cidr[i].ip4 = (*old_param).dump_params.dump_cidr[i].ip4; - filter_rules->dump_params.dump_cidr[i].mask = (*old_param).dump_params.dump_cidr[i].mask; - } - for (int i = 0; i < (*old_param).dump_params.current_port_num; ++i) { - filter_rules->dump_params.dump_port[i].begin_port = (*old_param).dump_params.dump_port[i].begin_port; - filter_rules->dump_params.dump_port[i].end_port = (*old_param).dump_params.dump_port[i].end_port; - } + filter_rules->dump_params.switch_on = (*old_param).dump_params.switch_on; + filter_rules->dump_params.current_cidr_num = (*old_param).dump_params.current_cidr_num; + filter_rules->dump_params.current_port_num = (*old_param).dump_params.current_port_num; + for (int i = 0; i < (*old_param).dump_params.current_cidr_num; ++i) { + filter_rules->dump_params.dump_cidr[i].ip4 = (*old_param).dump_params.dump_cidr[i].ip4; + filter_rules->dump_params.dump_cidr[i].mask = (*old_param).dump_params.dump_cidr[i].mask; + } + for (int i = 0; i < (*old_param).dump_params.current_port_num; ++i) { + filter_rules->dump_params.dump_port[i].begin_port = (*old_param).dump_params.dump_port[i].begin_port; + filter_rules->dump_params.dump_port[i].end_port = (*old_param).dump_params.dump_port[i].end_port; + } } -static int reset_param_map(struct sock_param* const filter_rules, const struct mesh_service_info* const fds) +static int reset_param_map(struct sock_param *const filter_rules, const struct mesh_service_info *const fds) { - struct sock_param old_param; - if (get_map_filter_rule(&fds->map_fds[MESH_MAP_OPS_PARAM_MAP], &old_param) != SUCCESS) - return FAILED; - reset_filter_rules(filter_rules, &old_param); - if (update_param_map(filter_rules, fds) != SUCCESS) - return FAILED; - return SUCCESS; + struct sock_param old_param; + if (get_map_filter_rule(&fds->map_fds[MESH_MAP_OPS_PARAM_MAP], &old_param) != SUCCESS) + return FAILED; + reset_filter_rules(filter_rules, &old_param); + if (update_param_map(filter_rules, fds) != SUCCESS) + return FAILED; + return SUCCESS; } -int do_enable(int argc, char* const *argv) +int do_enable(int argc, char *const *argv) { - /* - * start mesh accelerating - * param: -c configfile - * return: SUCCESS - * FAILED - */ - bool is_help = false; - char config_path[PATH_MAX] = {0}; - struct sock_param filter_rules = {0}; - struct mesh_service_info fds = {0}; - int ret; - - if (set_rlimit() != SUCCESS) - return FAILED; - - if ((ret = strcpy_s(config_path, PATH_MAX, CONFIGFILE_PATH)) != EOK) { - macli_log(ERR, "system copy string failed! errno:%d\n", ret); - return FAILED; - } - - if (enable_get_opt(argc, argv, config_path, &is_help) != SUCCESS) - return FAILED; - - if (is_help) - return SUCCESS; - - int cgroup2_fd = get_cgroup_root_fd(); - if (cgroup2_fd < 0) - goto FINISH; - - // Read the configuration file and put the data into the map - if (read_chain_config(config_path, &filter_rules) != SUCCESS) - goto CLOSE_PINNED_FD; - - if (init_fds(&fds, cgroup2_fd) != SUCCESS) - goto CLOSE_PINNED_FD; - - if (check_accelerating_on(&fds) == TRUE) { - macli_log(INFO, "mesh service is enabled!\n"); - if (reset_param_map(&filter_rules, &fds) != SUCCESS) { - macli_log(ERR, "reset mesh param failed!\n"); - goto CLOSE_PINNED_FD; - } - goto ENABLE_SUCCESS; - } - if (create_accelerate_fold() != SUCCESS) - goto DELETE_FILE; - if (create_map(&fds) != SUCCESS) - goto DELETE_FILE; - - init_dump_param(&filter_rules.dump_params); - - if (enable_service(&fds, &filter_rules) != SUCCESS) - goto DETACH; + /* + * start mesh accelerating + * param: -c configfile + * return: SUCCESS + * FAILED + */ + bool is_help = false; + char config_path[PATH_MAX] = {0}; + struct sock_param filter_rules = {0}; + struct mesh_service_info fds = {0}; + int ret; + + if (set_rlimit() != SUCCESS) + return FAILED; + + if ((ret = strcpy_s(config_path, PATH_MAX, CONFIGFILE_PATH)) != EOK) { + macli_log(ERR, "system copy string failed! errno:%d\n", ret); + return FAILED; + } + + if (enable_get_opt(argc, argv, config_path, &is_help) != SUCCESS) + return FAILED; + + if (is_help) + return SUCCESS; + + int cgroup2_fd = get_cgroup_root_fd(); + if (cgroup2_fd < 0) + goto FINISH; + + // Read the configuration file and put the data into the map + if (read_chain_config(config_path, &filter_rules) != SUCCESS) + goto CLOSE_PINNED_FD; + + if (init_fds(&fds, cgroup2_fd) != SUCCESS) + goto CLOSE_PINNED_FD; + + if (check_accelerating_on(&fds) == TRUE) { + macli_log(INFO, "mesh service is enabled!\n"); + if (reset_param_map(&filter_rules, &fds) != SUCCESS) { + macli_log(ERR, "reset mesh param failed!\n"); + goto CLOSE_PINNED_FD; + } + goto ENABLE_SUCCESS; + } + if (create_accelerate_fold() != SUCCESS) + goto DELETE_FILE; + if (create_map(&fds) != SUCCESS) + goto DELETE_FILE; + + init_dump_param(&filter_rules.dump_params); + + if (enable_service(&fds, &filter_rules) != SUCCESS) + goto DETACH; ENABLE_SUCCESS: - close_fds(cgroup2_fd, &fds); - macli_log(INFO, "enable serviceMesh accelerating success!\n"); - return SUCCESS; + close_fds(cgroup2_fd, &fds); + macli_log(INFO, "enable serviceMesh accelerating success!\n"); + return SUCCESS; DETACH: - (void)detach_program(&fds); + (void)detach_program(&fds); DELETE_FILE: - del_sock_file(&fds); + del_sock_file(&fds); CLOSE_PINNED_FD: - close_fds(cgroup2_fd, &fds); + close_fds(cgroup2_fd, &fds); FINISH: - macli_log(ERR, "enable serviceMesh accelerating failed!\n"); - return FAILED; + macli_log(ERR, "enable serviceMesh accelerating failed!\n"); + return FAILED; } -int do_disable(int argc, char* const *argv) +int do_disable(int argc, char *const *argv) { - int cgroup2_fd; - bool is_help = false; - if (disable_get_opt(argc, argv, &is_help)) - return FAILED; - - if (is_help) - return SUCCESS; - - cgroup2_fd = get_cgroup_root_fd(); - if (cgroup2_fd < 0) { - macli_log(ERR, "disable serviceMesh accelerating failed!\n"); - return FAILED; - } - - struct mesh_service_info fds; - if (init_fds(&fds, cgroup2_fd) != SUCCESS) - goto CLOSE_PINNED_FD; - - if (detach_program(&fds) != SUCCESS) - goto CLOSE_PINNED_FD; - // clean proxy map data - if (clean_proxy_map(&fds) != SUCCESS) - goto CLOSE_PINNED_FD; - close_fds(cgroup2_fd, &fds); - del_sock_file(&fds); - macli_log(INFO, "disable serviceMesh accelerating success!\n"); - return SUCCESS; + int cgroup2_fd; + bool is_help = false; + if (disable_get_opt(argc, argv, &is_help)) + return FAILED; + + if (is_help) + return SUCCESS; + + cgroup2_fd = get_cgroup_root_fd(); + if (cgroup2_fd < 0) { + macli_log(ERR, "disable serviceMesh accelerating failed!\n"); + return FAILED; + } + + struct mesh_service_info fds; + if (init_fds(&fds, cgroup2_fd) != SUCCESS) + goto CLOSE_PINNED_FD; + + if (detach_program(&fds) != SUCCESS) + goto CLOSE_PINNED_FD; + // clean proxy map data + if (clean_proxy_map(&fds) != SUCCESS) + goto CLOSE_PINNED_FD; + close_fds(cgroup2_fd, &fds); + del_sock_file(&fds); + macli_log(INFO, "disable serviceMesh accelerating success!\n"); + return SUCCESS; CLOSE_PINNED_FD: - close_fds(cgroup2_fd, &fds); - del_sock_file(&fds); - macli_log(ERR, "disable serviceMesh accelerating failed!\n"); - return FAILED; + close_fds(cgroup2_fd, &fds); + del_sock_file(&fds); + macli_log(ERR, "disable serviceMesh accelerating failed!\n"); + return FAILED; } - diff --git a/oncn-mda/cli_src/mdacore.c b/oncn-mda/cli_src/mdacore.c index 46ef5a03d..bc07207fa 100644 --- a/oncn-mda/cli_src/mdacore.c +++ b/oncn-mda/cli_src/mdacore.c @@ -18,47 +18,45 @@ static void usage(void) { - (void)printf("Usage: mdacore {COMMAND}\n"); - (void)printf(" COMMAND: enable enable serviceMesh accelerating\n"); - (void)printf(" disable disable serviceMesh accelerating\n"); - (void)printf(" query check program state\n"); + (void)printf("Usage: mdacore {COMMAND}\n"); + (void)printf(" COMMAND: enable enable serviceMesh accelerating\n"); + (void)printf(" disable disable serviceMesh accelerating\n"); + (void)printf(" query check program state\n"); } -static int do_help(int argc, char* const *argv) +static int do_help(int argc, char *const *argv) { - usage(); - return 0; + usage(); + return 0; } const struct cmd mda_cmds[] = { - {"help", do_help}, // help message - {"enable", do_enable}, // enable service - {"disable", do_disable}, // disable service - {"query", do_query}, // query service is enabled - {NULL} -}; + {"help", do_help}, // help message + {"enable", do_enable}, // enable service + {"disable", do_disable}, // disable service + {"query", do_query}, // query service is enabled + {NULL}}; -static int cmd_select(const struct cmd* cmds, int argc, char* const *argv, - int(*help)(int argc, char* const *argv)) +static int cmd_select(const struct cmd *cmds, int argc, char *const *argv, int (*help)(int argc, char *const *argv)) { - for (int i = 0; cmds[i].func; ++i) { - if (strcmp(*argv, cmds[i].cmd) == 0) - return cmds[i].func(argc, argv); - } + for (int i = 0; cmds[i].func; ++i) { + if (strcmp(*argv, cmds[i].cmd) == 0) + return cmds[i].func(argc, argv); + } - help(argc - 1, argv + 1); + help(argc - 1, argv + 1); - return ERROR; + return ERROR; } -int main(int argc, char** argv) +int main(int argc, char **argv) { - argc -= optind; - argv += optind; - if (argc <= 0) { - usage(); - return FAILED; - } - (void)libbpf_set_print(NULL); - return cmd_select(mda_cmds, argc, argv, do_help); + argc -= optind; + argv += optind; + if (argc <= 0) { + usage(); + return FAILED; + } + (void)libbpf_set_print(NULL); + return cmd_select(mda_cmds, argc, argv, do_help); } diff --git a/oncn-mda/ebpf_src/sock_ops.c b/oncn-mda/ebpf_src/sock_ops.c index 6577e477b..3bb348931 100644 --- a/oncn-mda/ebpf_src/sock_ops.c +++ b/oncn-mda/ebpf_src/sock_ops.c @@ -20,406 +20,413 @@ #include #include "mesh_accelerate.h" -static bool is_accept_ip(__u32 ip4, const struct cidr* const param, bool filter_option) +static bool is_accept_ip(__u32 ip4, const struct cidr *const param, bool filter_option) { - __u32 mask = bpf_htonl(param->mask); - __u32 cidr_net = bpf_htonl(param->ip4) & mask; - __u32 cidr_net_ip4 = ip4 & mask; - bpf_log(DEBUG, "param ip:%u, mask:%u\n", bpf_htonl(param->ip4), mask); - bpf_log(DEBUG, "ip: cidrs:%u, cidr_net:%u\n", cidr_net, cidr_net_ip4); - if (cidr_net == cidr_net_ip4) - return filter_option; - return !filter_option; + __u32 mask = bpf_htonl(param->mask); + __u32 cidr_net = bpf_htonl(param->ip4) & mask; + __u32 cidr_net_ip4 = ip4 & mask; + bpf_log(DEBUG, "param ip:%u, mask:%u\n", bpf_htonl(param->ip4), mask); + bpf_log(DEBUG, "ip: cidrs:%u, cidr_net:%u\n", cidr_net, cidr_net_ip4); + if (cidr_net == cidr_net_ip4) + return filter_option; + return !filter_option; } -static bool is_accept_port(const struct sock_key* const key, const struct sock_key* const peer_key, - const struct port_range* const param, bool filter_option) +static bool is_accept_port( + const struct sock_key *const key, + const struct sock_key *const peer_key, + const struct port_range *const param, + bool filter_option) { - __u32 begin_port = param->begin_port; - __u32 end_port = param->end_port; - __u32 input_sport = bpf_ntohl((key->sport) << FORMAT_IP_LENGTH); - __u32 input_dport = bpf_ntohl((key->dport) << FORMAT_IP_LENGTH); - __u32 input_peer_sport = bpf_ntohl((peer_key->sport) << FORMAT_IP_LENGTH); - __u32 input_peer_dport = bpf_ntohl((peer_key->dport) << FORMAT_IP_LENGTH); - bool sport = (begin_port <= input_sport) && (end_port >= input_sport); - bool dport = (begin_port <= input_dport) && (end_port >= input_dport); - bool peer_sport = (begin_port <= input_peer_sport) && (end_port >= input_peer_sport); - bool peer_dport = (begin_port <= input_peer_dport) && (end_port >= input_peer_dport); - if (sport || dport || peer_sport || peer_dport) - return filter_option; - return !filter_option; + __u32 begin_port = param->begin_port; + __u32 end_port = param->end_port; + __u32 input_sport = bpf_ntohl((key->sport) << FORMAT_IP_LENGTH); + __u32 input_dport = bpf_ntohl((key->dport) << FORMAT_IP_LENGTH); + __u32 input_peer_sport = bpf_ntohl((peer_key->sport) << FORMAT_IP_LENGTH); + __u32 input_peer_dport = bpf_ntohl((peer_key->dport) << FORMAT_IP_LENGTH); + bool sport = (begin_port <= input_sport) && (end_port >= input_sport); + bool dport = (begin_port <= input_dport) && (end_port >= input_dport); + bool peer_sport = (begin_port <= input_peer_sport) && (end_port >= input_peer_sport); + bool peer_dport = (begin_port <= input_peer_dport) && (end_port >= input_peer_dport); + if (sport || dport || peer_sport || peer_dport) + return filter_option; + return !filter_option; } -static bool adj_filter_ip(__u32 ip4, const struct input_cidr* const param, bool filter_flag) +static bool adj_filter_ip(__u32 ip4, const struct input_cidr *const param, bool filter_flag) { - for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { - if (i >= param->current_cidr_num) - break; - if (is_accept_ip(ip4, ¶m->cidrs[i], filter_flag) == filter_flag) - return filter_flag; - } - return !filter_flag; + for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { + if (i >= param->current_cidr_num) + break; + if (is_accept_ip(ip4, ¶m->cidrs[i], filter_flag) == filter_flag) + return filter_flag; + } + return !filter_flag; } -static bool filter_ip(const struct sock_key* const key, const struct sock_key* const peer_key, - const struct input_cidr* const param, bool filter_flag) +static bool filter_ip( + const struct sock_key *const key, + const struct sock_key *const peer_key, + const struct input_cidr *const param, + bool filter_flag) { - // If filter_flag is FILTER_PASS, the four IP addresses in key and peerkey must be in the whitelist - // If filter_flag is FILTER_RETURN, an IP address in the key or peerKey is in the blacklist will be - // return FILTER_RETURN - if (param->current_cidr_num == 0) - return FILTER_PASS; - - if (adj_filter_ip(key->sip4, param, filter_flag) != FILTER_PASS) - return FILTER_RETURN; - if (adj_filter_ip(key->dip4, param, filter_flag) != FILTER_PASS) - return FILTER_RETURN; - if (adj_filter_ip(peer_key->sip4, param, filter_flag) != FILTER_PASS) - return FILTER_RETURN; - if (adj_filter_ip(peer_key->dip4, param, filter_flag) != FILTER_PASS) - return FILTER_RETURN; - return FILTER_PASS; + // If filter_flag is FILTER_PASS, the four IP addresses in key and peerkey must be in the whitelist + // If filter_flag is FILTER_RETURN, an IP address in the key or peerKey is in the blacklist will be + // return FILTER_RETURN + if (param->current_cidr_num == 0) + return FILTER_PASS; + + if (adj_filter_ip(key->sip4, param, filter_flag) != FILTER_PASS) + return FILTER_RETURN; + if (adj_filter_ip(key->dip4, param, filter_flag) != FILTER_PASS) + return FILTER_RETURN; + if (adj_filter_ip(peer_key->sip4, param, filter_flag) != FILTER_PASS) + return FILTER_RETURN; + if (adj_filter_ip(peer_key->dip4, param, filter_flag) != FILTER_PASS) + return FILTER_RETURN; + return FILTER_PASS; } -static bool filter_port(const struct sock_key* const key, const struct sock_key* const peer_key, - const struct input_port* const param, bool filter_flag) +static bool filter_port( + const struct sock_key *const key, + const struct sock_key *const peer_key, + const struct input_port *const param, + bool filter_flag) { - // If filter_flag is FILTER_PASS, any of the four ports in key and peerkey can pass the whitelist - // If filter_flag is FILTER_RETURN, any of the four ports in key and peerkey cannot pass the blacklist - if (param->current_port_num == 0) - return FILTER_PASS; - - for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { - if (i >= param->current_port_num) - break; - if (is_accept_port(key, peer_key, ¶m->ports[i], filter_flag) == filter_flag) - return filter_flag; - } - return !filter_flag; + // If filter_flag is FILTER_PASS, any of the four ports in key and peerkey can pass the whitelist + // If filter_flag is FILTER_RETURN, any of the four ports in key and peerkey cannot pass the blacklist + if (param->current_port_num == 0) + return FILTER_PASS; + + for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { + if (i >= param->current_port_num) + break; + if (is_accept_port(key, peer_key, ¶m->ports[i], filter_flag) == filter_flag) + return filter_flag; + } + return !filter_flag; } #if MDA_GID_UID_FILTER -static bool is_accept_uid(const struct uid_gid_info* const current_uid_gid, const __u32 input_uid, - bool filter_option) +static bool is_accept_uid(const struct uid_gid_info *const current_uid_gid, const __u32 input_uid, bool filter_option) { - if ((current_uid_gid->cuid == input_uid) || (current_uid_gid->puid == input_uid)) - return filter_option; - return !filter_option; + if ((current_uid_gid->cuid == input_uid) || (current_uid_gid->puid == input_uid)) + return filter_option; + return !filter_option; } -static bool is_accept_gid(const struct uid_gid_info* const current_uid_gid, const __u32 input_gid, - bool filter_option) +static bool is_accept_gid(const struct uid_gid_info *const current_uid_gid, const __u32 input_gid, bool filter_option) { - if ((current_uid_gid->cgid == input_gid) || (current_uid_gid->pgid == input_gid)) - return filter_option; - return !filter_option; + if ((current_uid_gid->cgid == input_gid) || (current_uid_gid->pgid == input_gid)) + return filter_option; + return !filter_option; } -static bool filter_uid(const struct uid_gid_info* const current_uid_gid, - const struct input_uid* const param, bool filter_flag) +static bool +filter_uid(const struct uid_gid_info *const current_uid_gid, const struct input_uid *const param, bool filter_flag) { - // If filter_flag is FILTER_PASS, either side of the UID can pass the whitelist - // If filter_flag is FILTER_RETURN, either side of the UID cannot pass the blacklist - if (param->current_uid_num == 0) - return FILTER_PASS; - for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { - if (i >= param->current_uid_num) - break; - if (is_accept_uid(current_uid_gid, param->uids[i], filter_flag) == filter_flag) - return filter_flag; - } - return !filter_flag; + // If filter_flag is FILTER_PASS, either side of the UID can pass the whitelist + // If filter_flag is FILTER_RETURN, either side of the UID cannot pass the blacklist + if (param->current_uid_num == 0) + return FILTER_PASS; + for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { + if (i >= param->current_uid_num) + break; + if (is_accept_uid(current_uid_gid, param->uids[i], filter_flag) == filter_flag) + return filter_flag; + } + return !filter_flag; } -static bool filter_gid(const struct uid_gid_info* const current_uid_gid, - const struct input_gid* const param, bool filter_flag) +static bool +filter_gid(const struct uid_gid_info *const current_uid_gid, const struct input_gid *const param, bool filter_flag) { - // If filter_flag is FILTER_PASS, either gid can pass the whitelist - // If filter_flag is FILTER_RETURN, either gid cannot pass the blacklist - if (param->current_gid_num == 0) - return FILTER_PASS; - for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { - if (i >= param->current_gid_num) - break; - if (is_accept_gid(current_uid_gid, param->gids[i], filter_flag) == filter_flag) - return filter_flag; - } - return !filter_flag; + // If filter_flag is FILTER_PASS, either gid can pass the whitelist + // If filter_flag is FILTER_RETURN, either gid cannot pass the blacklist + if (param->current_gid_num == 0) + return FILTER_PASS; + for (int i = 0; i < MAX_PARAM_LENGTH; ++i) { + if (i >= param->current_gid_num) + break; + if (is_accept_gid(current_uid_gid, param->gids[i], filter_flag) == filter_flag) + return filter_flag; + } + return !filter_flag; } -static void get_current_uid_gid(struct uid_gid_info* const current_uid_gid, struct bpf_sock_ops* const skops) +static void get_current_uid_gid(struct uid_gid_info *const current_uid_gid, struct bpf_sock_ops *const skops) { - __u64 uid_gid = bpf_get_sockops_uid_gid(skops); - current_uid_gid->cuid = (uid_gid & 0xffffffff); - current_uid_gid->cgid = (uid_gid >> UID_LENGTH); - current_uid_gid->puid = 0; - current_uid_gid->pgid = 0; + __u64 uid_gid = bpf_get_sockops_uid_gid(skops); + current_uid_gid->cuid = (uid_gid & 0xffffffff); + current_uid_gid->cgid = (uid_gid >> UID_LENGTH); + current_uid_gid->puid = 0; + current_uid_gid->pgid = 0; } -static int get_peer_uid_gid(const struct sock_key* const peer_key, struct uid_gid_info* const current_uid_gid) +static int get_peer_uid_gid(const struct sock_key *const peer_key, struct uid_gid_info *const current_uid_gid) { - struct uid_gid_info *peer_uid_gid = bpf_map_lookup_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)peer_key); - if (peer_uid_gid == NULL) { - return FAILED; - } else { - current_uid_gid->puid = peer_uid_gid->cuid; - current_uid_gid->pgid = peer_uid_gid->cgid; - } - // Delete information about the peer Uid_GID in the helper - bpf_map_delete_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)peer_key); - return SUCCESS; + struct uid_gid_info *peer_uid_gid = bpf_map_lookup_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)peer_key); + if (peer_uid_gid == NULL) { + return FAILED; + } else { + current_uid_gid->puid = peer_uid_gid->cuid; + current_uid_gid->pgid = peer_uid_gid->cgid; + } + // Delete information about the peer Uid_GID in the helper + bpf_map_delete_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)peer_key); + return SUCCESS; } #endif -static bool filter(const struct sock_key* const key, const struct sock_key* const peer_key, - struct bpf_sock_ops* const skops) +static bool +filter(const struct sock_key *const key, const struct sock_key *const peer_key, struct bpf_sock_ops *const skops) { - int index = 0; - struct sock_param *param = bpf_map_lookup_elem(&SOCK_PARAM_MAP_NAME, &index); - if (param == NULL) - return FILTER_RETURN; - if (filter_ip(key, peer_key, ¶m->return_cidrs, FILTER_RETURN) != FILTER_PASS) - return FILTER_RETURN; + int index = 0; + struct sock_param *param = bpf_map_lookup_elem(&SOCK_PARAM_MAP_NAME, &index); + if (param == NULL) + return FILTER_RETURN; + if (filter_ip(key, peer_key, ¶m->return_cidrs, FILTER_RETURN) != FILTER_PASS) + return FILTER_RETURN; - if (filter_ip(key, peer_key, ¶m->accept_cidrs, FILTER_PASS) != FILTER_PASS) - return FILTER_RETURN; + if (filter_ip(key, peer_key, ¶m->accept_cidrs, FILTER_PASS) != FILTER_PASS) + return FILTER_RETURN; - if (filter_port(key, peer_key, ¶m->return_ports, FILTER_RETURN) != FILTER_PASS) - return FILTER_RETURN; + if (filter_port(key, peer_key, ¶m->return_ports, FILTER_RETURN) != FILTER_PASS) + return FILTER_RETURN; - if (filter_port(key, peer_key, ¶m->accept_ports, FILTER_PASS) != FILTER_PASS) - return FILTER_RETURN; + if (filter_port(key, peer_key, ¶m->accept_ports, FILTER_PASS) != FILTER_PASS) + return FILTER_RETURN; #if MDA_GID_UID_FILTER - if (param->accept_uids.current_uid_num == 0 && param->return_uids.current_uid_num == 0 && - param->accept_gids.current_gid_num == 0 && param->return_gids.current_gid_num == 0) - return FILTER_PASS; + if (param->accept_uids.current_uid_num == 0 && param->return_uids.current_uid_num == 0 + && param->accept_gids.current_gid_num == 0 && param->return_gids.current_gid_num == 0) + return FILTER_PASS; - struct uid_gid_info current_uid_gid = {0}; - get_current_uid_gid(¤t_uid_gid, skops); - if (get_peer_uid_gid(peer_key, ¤t_uid_gid) != SUCCESS) { - // The UID and GID of the peer are not found. mey be in other node - bpf_log(INFO, "can not found the peer helper info! peer key:%u:%u\n", peer_key->sport, peer_key->sip4); - return FILTER_RETURN; - } + struct uid_gid_info current_uid_gid = {0}; + get_current_uid_gid(¤t_uid_gid, skops); + if (get_peer_uid_gid(peer_key, ¤t_uid_gid) != SUCCESS) { + // The UID and GID of the peer are not found. mey be in other node + bpf_log(INFO, "can not found the peer helper info! peer key:%u:%u\n", peer_key->sport, peer_key->sip4); + return FILTER_RETURN; + } - if (filter_uid(¤t_uid_gid, ¶m->return_uids, FILTER_RETURN) != FILTER_PASS) - return FILTER_RETURN; + if (filter_uid(¤t_uid_gid, ¶m->return_uids, FILTER_RETURN) != FILTER_PASS) + return FILTER_RETURN; - if (filter_uid(¤t_uid_gid, ¶m->accept_uids, FILTER_PASS) != FILTER_PASS) - return FILTER_RETURN; + if (filter_uid(¤t_uid_gid, ¶m->accept_uids, FILTER_PASS) != FILTER_PASS) + return FILTER_RETURN; - if (filter_gid(¤t_uid_gid, ¶m->return_gids, FILTER_RETURN) != FILTER_PASS) - return FILTER_RETURN; + if (filter_gid(¤t_uid_gid, ¶m->return_gids, FILTER_RETURN) != FILTER_PASS) + return FILTER_RETURN; - if (filter_gid(¤t_uid_gid, ¶m->accept_gids, FILTER_PASS) != FILTER_PASS) - return FILTER_RETURN; + if (filter_gid(¤t_uid_gid, ¶m->accept_gids, FILTER_PASS) != FILTER_PASS) + return FILTER_RETURN; #endif - return FILTER_PASS; + return FILTER_PASS; } -static void extract_key4_from_ops(struct bpf_sock_ops* const ops, struct sock_key* const key) +static void extract_key4_from_ops(struct bpf_sock_ops *const ops, struct sock_key *const key) { - key->sip4 = ops->local_ip4; - /* - * The reason for the 16-bit shift to the right is that clang-7.1 and later versions seem to be - * optimized to think that only 16-bit data needs to be read here, but most kernels do not support this, - * causing the BPF validator to fail. - */ - key->sport = (bpf_htonl(ops->local_port) >> FORMAT_IP_LENGTH); - key->dip4 = ops->remote_ip4; + key->sip4 = ops->local_ip4; + /* + * The reason for the 16-bit shift to the right is that clang-7.1 and later versions seem to be + * optimized to think that only 16-bit data needs to be read here, but most kernels do not support this, + * causing the BPF validator to fail. + */ + key->sport = (bpf_htonl(ops->local_port) >> FORMAT_IP_LENGTH); + key->dip4 = ops->remote_ip4; #if !OE_23_03 - key->dport = (force_read(ops->remote_port) >> FORMAT_IP_LENGTH); -#else - key->dport = (force_read(ops->remote_port)); + key->dport = (force_read(ops->remote_port) >> FORMAT_IP_LENGTH); +#else + key->dport = (force_read(ops->remote_port)); #endif - bpf_log(DEBUG, "sip:%u, sport:%u\n", key->sip4, key->sport); - bpf_log(DEBUG, "dip:%u, dport:%u\n", key->dip4, key->dport); + bpf_log(DEBUG, "sip:%u, sport:%u\n", key->sip4, key->sport); + bpf_log(DEBUG, "dip:%u, dport:%u\n", key->dip4, key->dport); #if MDA_LOOPBACK_ADDR - set_netns_cookie((void*)ops, key); - bpf_log(DEBUG, "netns_cookie:%u\n", key->netns_cookie); + set_netns_cookie((void *)ops, key); + bpf_log(DEBUG, "netns_cookie:%u\n", key->netns_cookie); #endif } -static int add_sockhash_map(struct bpf_sock_ops* const skops, const struct sock_key* const key) +static int add_sockhash_map(struct bpf_sock_ops *const skops, const struct sock_key *const key) { - long ret = bpf_sock_hash_update((void *)skops, &SOCK_OPS_MAP_NAME, (void *)key, BPF_ANY); - if (ret != 0) { - bpf_log(ERROR, "sock ops map operator failed! err is %d\n", ret); - return FAILED; - } - return SUCCESS; + long ret = bpf_sock_hash_update((void *)skops, &SOCK_OPS_MAP_NAME, (void *)key, BPF_ANY); + if (ret != 0) { + bpf_log(ERROR, "sock ops map operator failed! err is %d\n", ret); + return FAILED; + } + return SUCCESS; } #if MDA_GID_UID_FILTER -static int add_helper_hash(const struct sock_key* const key, const struct uid_gid_info* const uid_gid) +static int add_helper_hash(const struct sock_key *const key, const struct uid_gid_info *const uid_gid) { - long ret = bpf_map_update_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)key, (void *)uid_gid, BPF_ANY); - if (ret != 0) { - bpf_log(DEBUG, "add_helper_hash failed! sip:%u, sport:%u ret:%d\n", key->sip4, key->sport, ret); - return FAILED; - } - return SUCCESS; + long ret = bpf_map_update_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)key, (void *)uid_gid, BPF_ANY); + if (ret != 0) { + bpf_log(DEBUG, "add_helper_hash failed! sip:%u, sport:%u ret:%d\n", key->sip4, key->sport, ret); + return FAILED; + } + return SUCCESS; } #endif -static int get_peer_addr(struct bpf_sock_ops* const skops, const struct sock_key* const key, - struct sock_key* const peer_key) +static int +get_peer_addr(struct bpf_sock_ops *const skops, const struct sock_key *const key, struct sock_key *const peer_key) { #if MDA_NAT_ACCEL - struct sockaddr_in target = {0}; - int target_len = sizeof(target); - int ret = bpf_sk_original_addr(skops, SO_ORIGINAL_DST, (void *)&target, target_len); - if (ret == 0) { - peer_key->sip4 = key->dip4; - peer_key->sport = key->dport; - peer_key->dip4 = target.sin_addr.s_addr; - peer_key->dport = target.sin_port; + struct sockaddr_in target = {0}; + int target_len = sizeof(target); + int ret = bpf_sk_original_addr(skops, SO_ORIGINAL_DST, (void *)&target, target_len); + if (ret == 0) { + peer_key->sip4 = key->dip4; + peer_key->sport = key->dport; + peer_key->dip4 = target.sin_addr.s_addr; + peer_key->dport = target.sin_port; #if MDA_LOOPBACK_ADDR - set_netns_cookie((void*)skops, peer_key); + set_netns_cookie((void *)skops, peer_key); #endif - return SUCCESS; - } else if (ret == -ENOENT) { + return SUCCESS; + } else if (ret == -ENOENT) { #endif - peer_key->sip4 = key->dip4; - peer_key->sport = key->dport; - peer_key->dip4 = key->sip4; - peer_key->dport = key->sport; + peer_key->sip4 = key->dip4; + peer_key->sport = key->dport; + peer_key->dip4 = key->sip4; + peer_key->dport = key->sport; #if MDA_LOOPBACK_ADDR - set_netns_cookie((void*)skops, peer_key); + set_netns_cookie((void *)skops, peer_key); #endif - return SUCCESS; + return SUCCESS; #if MDA_NAT_ACCEL - } + } - bpf_log(ERROR, "get target failed!, operator = %d, ret = %d\n", SO_ORIGINAL_DST, ret); - return FAILED; + bpf_log(ERROR, "get target failed!, operator = %d, ret = %d\n", SO_ORIGINAL_DST, ret); + return FAILED; #endif } -static int clean_ops(const struct sock_key* const key) +static int clean_ops(const struct sock_key *const key) { - bpf_map_delete_elem(&SOCK_OPS_MAP_NAME, (void *)key); + bpf_map_delete_elem(&SOCK_OPS_MAP_NAME, (void *)key); #if MDA_GID_UID_FILTER - bpf_map_delete_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)key); + bpf_map_delete_elem(&SOCK_OPS_HELPER_MAP_NAME, (void *)key); #endif - bpf_map_delete_elem(&SOCK_OPS_PROXY_MAP_NAME, (void*)key); - return SUCCESS; + bpf_map_delete_elem(&SOCK_OPS_PROXY_MAP_NAME, (void *)key); + return SUCCESS; } -static void active_ops_ipv4(struct bpf_sock_ops* const skops) +static void active_ops_ipv4(struct bpf_sock_ops *const skops) { - struct sock_key key = {0}; - extract_key4_from_ops(skops, &key); - if (add_sockhash_map(skops, &key)) { - bpf_log(ERROR, "active_ops_ipv4 failed!\n"); - return; - } + struct sock_key key = {0}; + extract_key4_from_ops(skops, &key); + if (add_sockhash_map(skops, &key)) { + bpf_log(ERROR, "active_ops_ipv4 failed!\n"); + return; + } #if MDA_GID_UID_FILTER - struct uid_gid_info current_uid_gid = {0}; - get_current_uid_gid(¤t_uid_gid, skops); - if (add_helper_hash(&key, ¤t_uid_gid)) { - bpf_log(ERROR, "active_ops_ipv4 failed!\n"); - (void)clean_ops(&key); - return; - } + struct uid_gid_info current_uid_gid = {0}; + get_current_uid_gid(¤t_uid_gid, skops); + if (add_helper_hash(&key, ¤t_uid_gid)) { + bpf_log(ERROR, "active_ops_ipv4 failed!\n"); + (void)clean_ops(&key); + return; + } #endif - return; + return; } -static void passive_ops_ipv4(struct bpf_sock_ops* const skops) +static void passive_ops_ipv4(struct bpf_sock_ops *const skops) { - struct sock_key key = {0}; - struct sock_key peer_key = {0}; + struct sock_key key = {0}; + struct sock_key peer_key = {0}; - extract_key4_from_ops(skops, &key); + extract_key4_from_ops(skops, &key); - if (get_peer_addr(skops, &key, &peer_key) != SUCCESS) - goto err; + if (get_peer_addr(skops, &key, &peer_key) != SUCCESS) + goto err; - if (filter(&key, &peer_key, skops) == FILTER_RETURN) { - bpf_log(INFO, "sip:%u, sport:%u filtered\n", peer_key.sip4, peer_key.sport); - goto err; - } + if (filter(&key, &peer_key, skops) == FILTER_RETURN) { + bpf_log(INFO, "sip:%u, sport:%u filtered\n", peer_key.sip4, peer_key.sport); + goto err; + } - if (add_sockhash_map(skops, &key)) - goto err; + if (add_sockhash_map(skops, &key)) + goto err; - /* - * key: 127.0.0.1:15001->172.17.0.3:6002 - * peer_key: 172.17.0.3:6002->172.17.0.2:5002 - */ + /* + * key: 127.0.0.1:15001->172.17.0.3:6002 + * peer_key: 172.17.0.3:6002->172.17.0.2:5002 + */ - if (bpf_map_update_elem(&SOCK_OPS_PROXY_MAP_NAME, &key, &peer_key, BPF_ANY)) - goto err; + if (bpf_map_update_elem(&SOCK_OPS_PROXY_MAP_NAME, &key, &peer_key, BPF_ANY)) + goto err; - if (bpf_map_update_elem(&SOCK_OPS_PROXY_MAP_NAME, &peer_key, &key, BPF_ANY)) - goto err; - return; - err: - (void)clean_ops(&peer_key); - (void)clean_ops(&key); + if (bpf_map_update_elem(&SOCK_OPS_PROXY_MAP_NAME, &peer_key, &key, BPF_ANY)) + goto err; + return; +err: + (void)clean_ops(&peer_key); + (void)clean_ops(&key); - return; + return; } -static void clean_ops_map(struct bpf_sock_ops* const skops) +static void clean_ops_map(struct bpf_sock_ops *const skops) { - struct sock_key key; - struct sock_key *reverse_key = NULL; - extract_key4_from_ops(skops, &key); - long ret; + struct sock_key key; + struct sock_key *reverse_key = NULL; + extract_key4_from_ops(skops, &key); + long ret; #if MDA_GID_UID_FILTER - ret = bpf_map_delete_elem(&SOCK_OPS_HELPER_MAP_NAME, &key); - if (ret && ret != -ENOENT) - bpf_log(INFO, "bpf map delete helper elem key failed! ret:%d\n", ret); + ret = bpf_map_delete_elem(&SOCK_OPS_HELPER_MAP_NAME, &key); + if (ret && ret != -ENOENT) + bpf_log(INFO, "bpf map delete helper elem key failed! ret:%d\n", ret); #endif - reverse_key = bpf_map_lookup_elem(&SOCK_OPS_PROXY_MAP_NAME, &key); - ret = bpf_map_delete_elem(&SOCK_OPS_PROXY_MAP_NAME, &key); - if (ret && ret != -ENOENT) - bpf_log(INFO, "bpf map delete proxy elem key failed! ret:%d\n", ret); + reverse_key = bpf_map_lookup_elem(&SOCK_OPS_PROXY_MAP_NAME, &key); + ret = bpf_map_delete_elem(&SOCK_OPS_PROXY_MAP_NAME, &key); + if (ret && ret != -ENOENT) + bpf_log(INFO, "bpf map delete proxy elem key failed! ret:%d\n", ret); - if (reverse_key == NULL) - return; + if (reverse_key == NULL) + return; - ret = bpf_map_delete_elem(&SOCK_OPS_PROXY_MAP_NAME, reverse_key); - if (ret && ret != -ENOENT) - bpf_log(INFO, "bpf map delete proxy elem key failed! ret:%d\n", ret); + ret = bpf_map_delete_elem(&SOCK_OPS_PROXY_MAP_NAME, reverse_key); + if (ret && ret != -ENOENT) + bpf_log(INFO, "bpf map delete proxy elem key failed! ret:%d\n", ret); } SEC("sockops") -int SOCK_OPS_NAME(struct bpf_sock_ops* const skops) +int SOCK_OPS_NAME(struct bpf_sock_ops *const skops) { - if (skops->family != AF_INET) - return 0; - - switch (skops->op) { - case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: - bpf_log(DEBUG, "active\n"); - if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) - bpf_log(ERROR, "set sockops cb failed!\n"); - active_ops_ipv4(skops); - break; - case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - bpf_log(DEBUG, "passive\n"); - if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) - bpf_log(ERROR, "set sockops cb failed!\n"); - passive_ops_ipv4(skops); - break; - case BPF_SOCK_OPS_STATE_CB: - if (skops->args[1] == BPF_TCP_CLOSE || skops->args[1] == BPF_TCP_CLOSE_WAIT - || skops->args[1] == BPF_TCP_FIN_WAIT1) - clean_ops_map(skops); - break; - default: - break; - } - return 0; + if (skops->family != AF_INET) + return 0; + + switch (skops->op) { + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + bpf_log(DEBUG, "active\n"); + if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) + bpf_log(ERROR, "set sockops cb failed!\n"); + active_ops_ipv4(skops); + break; + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + bpf_log(DEBUG, "passive\n"); + if (bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG) != 0) + bpf_log(ERROR, "set sockops cb failed!\n"); + passive_ops_ipv4(skops); + break; + case BPF_SOCK_OPS_STATE_CB: + if (skops->args[1] == BPF_TCP_CLOSE || skops->args[1] == BPF_TCP_CLOSE_WAIT + || skops->args[1] == BPF_TCP_FIN_WAIT1) + clean_ops_map(skops); + break; + default: + break; + } + return 0; } char _license[] SEC("license") = "GPL"; diff --git a/oncn-mda/ebpf_src/sock_redirect.c b/oncn-mda/ebpf_src/sock_redirect.c index 33cca4ec3..7545c252d 100644 --- a/oncn-mda/ebpf_src/sock_redirect.c +++ b/oncn-mda/ebpf_src/sock_redirect.c @@ -17,33 +17,33 @@ #include "mesh_accelerate.h" SEC("sk_msg") -int SOCK_REDIRECT_NAME(struct sk_msg_md* const msg) +int SOCK_REDIRECT_NAME(struct sk_msg_md *const msg) { - struct sock_key key = {0}; - struct sock_key *redir_key = NULL; - long ret = 0; + struct sock_key key = {0}; + struct sock_key *redir_key = NULL; + long ret = 0; - key.sip4 = msg->local_ip4; - key.dip4 = msg->remote_ip4; - key.sport = (bpf_htonl(msg->local_port) >> 16); - key.dport = (force_read(msg->remote_port) >> 16); + key.sip4 = msg->local_ip4; + key.dip4 = msg->remote_ip4; + key.sport = (bpf_htonl(msg->local_port) >> 16); + key.dport = (force_read(msg->remote_port) >> 16); #if MDA_LOOPBACK_ADDR - set_netns_cookie((void*)msg, &key); + set_netns_cookie((void *)msg, &key); #endif - redir_key = bpf_map_lookup_elem(&SOCK_OPS_PROXY_MAP_NAME, &key); - if (redir_key != NULL) { - ret = bpf_msg_redirect_hash(msg, &SOCK_OPS_MAP_NAME, redir_key, BPF_F_INGRESS); - if (ret != SK_DROP) { - bpf_log(DEBUG, "redirect the sk success\n"); + redir_key = bpf_map_lookup_elem(&SOCK_OPS_PROXY_MAP_NAME, &key); + if (redir_key != NULL) { + ret = bpf_msg_redirect_hash(msg, &SOCK_OPS_MAP_NAME, redir_key, BPF_F_INGRESS); + if (ret != SK_DROP) { + bpf_log(DEBUG, "redirect the sk success\n"); - } else { - // If you connect to the peer machine, you do end up in this branch - bpf_log(INFO, "no such socket, may be peer socket on another machine\n"); - } - } + } else { + // If you connect to the peer machine, you do end up in this branch + bpf_log(INFO, "no such socket, may be peer socket on another machine\n"); + } + } - return SK_PASS; + return SK_PASS; } char _license[] SEC("license") = "GPL"; diff --git a/oncn-mda/include/data.h b/oncn-mda/include/data.h index f73655de8..0975a1eb7 100644 --- a/oncn-mda/include/data.h +++ b/oncn-mda/include/data.h @@ -22,134 +22,134 @@ #include #include "../../config/kmesh_marcos_def.h" -#define SKOPS_MAP_SIZE 196608 -#define MAX_PARAM_LENGTH 10 +#define SKOPS_MAP_SIZE 196608 +#define MAX_PARAM_LENGTH 10 -#define DUMP_QUEUE_LENGTH 4096 -#define MAX_DUMP_DATA_SIZE 4096 +#define DUMP_QUEUE_LENGTH 4096 +#define MAX_DUMP_DATA_SIZE 4096 #define SUCCESS 0 #define FAILED 1 -#define TRUE 0 -#define FALSE 1 +#define TRUE 0 +#define FALSE 1 -#define ERROR (-1) +#define ERROR (-1) // Currently, the maximum length of the NAME of BPF Map prog can be defined as 16(including '\0'), // which will be truncated -#define SOCK_OPS_MAP_NAME sock_ops_map -#define SOCK_PARAM_MAP_NAME sock_param_map -#define SOCK_OPS_PROXY_MAP_NAME sock_proxy_map -#define SOCK_DUMP_MAP_I_NAME sock_dump_map -#define SOCK_DUMP_CPU_ARRAY_NAME sock_ddata_map +#define SOCK_OPS_MAP_NAME sock_ops_map +#define SOCK_PARAM_MAP_NAME sock_param_map +#define SOCK_OPS_PROXY_MAP_NAME sock_proxy_map +#define SOCK_DUMP_MAP_I_NAME sock_dump_map +#define SOCK_DUMP_CPU_ARRAY_NAME sock_ddata_map #if MDA_GID_UID_FILTER -#define MAX_UID_GID_LENGTH 10 -#define SOCK_OPS_HELPER_MAP_NAME sock_helper_map +#define MAX_UID_GID_LENGTH 10 +#define SOCK_OPS_HELPER_MAP_NAME sock_helper_map #endif -#define SOCK_OPS_NAME ma_ops -#define SOCK_REDIRECT_NAME ma_redirect +#define SOCK_OPS_NAME ma_ops +#define SOCK_REDIRECT_NAME ma_redirect #define to_str__(X) #X -#define to_str(X) to_str__(X) +#define to_str(X) to_str__(X) struct sock_key { - __u32 sip4; - __u32 dip4; - __u32 sport; - __u32 dport; + __u32 sip4; + __u32 dip4; + __u32 sport; + __u32 dport; #if MDA_LOOPBACK_ADDR - __u64 netns_cookie; + __u64 netns_cookie; #endif } __attribute__((packed)); struct cidr { - __u32 ip4; - __u32 mask; + __u32 ip4; + __u32 mask; } __attribute__((packed)); struct port_range { - __u32 begin_port; - __u32 end_port; + __u32 begin_port; + __u32 end_port; } __attribute__((packed)); struct dump_prarm { - __u32 switch_on; - __u8 current_cidr_num; // Indicates the number of cidRs currently entered - __u8 current_port_num; // Indicates the number of ports to be filtered - struct cidr dump_cidr[MAX_PARAM_LENGTH]; - struct port_range dump_port[MAX_PARAM_LENGTH]; + __u32 switch_on; + __u8 current_cidr_num; // Indicates the number of cidRs currently entered + __u8 current_port_num; // Indicates the number of ports to be filtered + struct cidr dump_cidr[MAX_PARAM_LENGTH]; + struct port_range dump_port[MAX_PARAM_LENGTH]; } __attribute__((packed)); // When modifying the following structure, place PARAM_SIZE last enum ma_param_type { - ACCEPT_IP = 0, - RETURN_IP, - ACCEPT_PORT, - RETURN_PORT, + ACCEPT_IP = 0, + RETURN_IP, + ACCEPT_PORT, + RETURN_PORT, #if MDA_GID_UID_FILTER - ACCEPT_UID, - RETURN_UID, - ACCEPT_GID, - RETURN_GID, + ACCEPT_UID, + RETURN_UID, + ACCEPT_GID, + RETURN_GID, #endif - DUMP, - DUMP_IP, - DUMP_PORT, - PARAM_SIZE, + DUMP, + DUMP_IP, + DUMP_PORT, + PARAM_SIZE, }; struct input_cidr { - __u8 current_cidr_num; - struct cidr cidrs[MAX_PARAM_LENGTH]; + __u8 current_cidr_num; + struct cidr cidrs[MAX_PARAM_LENGTH]; } __attribute__((packed)); struct input_port { - __u8 current_port_num; - struct port_range ports[MAX_PARAM_LENGTH]; + __u8 current_port_num; + struct port_range ports[MAX_PARAM_LENGTH]; } __attribute__((packed)); #if MDA_GID_UID_FILTER struct uid_gid_info { - __u32 cuid; - __u32 cgid; - __u32 puid; - __u32 pgid; + __u32 cuid; + __u32 cgid; + __u32 puid; + __u32 pgid; } __attribute__((packed)); struct input_uid { - __u8 current_uid_num; - __u32 uids[MAX_PARAM_LENGTH]; + __u8 current_uid_num; + __u32 uids[MAX_PARAM_LENGTH]; } __attribute__((packed)); struct input_gid { - __u8 current_gid_num; - __u32 gids[MAX_PARAM_LENGTH]; + __u8 current_gid_num; + __u32 gids[MAX_PARAM_LENGTH]; } __attribute__((packed)); #endif struct sock_param { - struct input_cidr accept_cidrs; - struct input_cidr return_cidrs; - struct input_port accept_ports; - struct input_port return_ports; + struct input_cidr accept_cidrs; + struct input_cidr return_cidrs; + struct input_port accept_ports; + struct input_port return_ports; #if MDA_GID_UID_FILTER - struct input_uid accept_uids; - struct input_uid return_uids; - struct input_gid accept_gids; - struct input_gid return_gids; + struct input_uid accept_uids; + struct input_uid return_uids; + struct input_gid accept_gids; + struct input_gid return_gids; #endif - struct dump_prarm dump_params; + struct dump_prarm dump_params; } __attribute__((packed)); struct dump_data { - __u64 timestamp; - __u32 sip; - __u32 sport; - __u32 dip; - __u32 dport; - __u32 data_length; + __u64 timestamp; + __u32 sip; + __u32 sport; + __u32 dip; + __u32 dport; + __u32 data_length; }; #endif diff --git a/oncn-mda/include/log.h b/oncn-mda/include/log.h index 717b1ee6c..b57a2cfaf 100644 --- a/oncn-mda/include/log.h +++ b/oncn-mda/include/log.h @@ -25,17 +25,10 @@ #include #include "securec.h" -enum LOG_LEVEL { - FATAL = 0, - ERR, - WARN, - INFO, - DEBUG -}; +enum LOG_LEVEL { FATAL = 0, ERR, WARN, INFO, DEBUG }; -void ma_log(enum LOG_LEVEL level, const char* format, ...); +void ma_log(enum LOG_LEVEL level, const char *format, ...); -#define macli_log(level, format, ...) \ - ma_log(level, format, ##__VA_ARGS__) +#define macli_log(level, format, ...) ma_log(level, format, ##__VA_ARGS__) #endif // MACLI_LOG_H diff --git a/oncn-mda/include/macli.h b/oncn-mda/include/macli.h index e4ebf843c..c12320da8 100644 --- a/oncn-mda/include/macli.h +++ b/oncn-mda/include/macli.h @@ -37,97 +37,97 @@ #include "data.h" #include "log.h" -#define MAX_CIDR_LENGTH 19 -#define MAX_IP_LENGTH 16 +#define MAX_CIDR_LENGTH 19 +#define MAX_IP_LENGTH 16 #define MAX_PORT_RANGE_LENGTH 12 -#define MASK_LENGTH 32 -#define MASK_BASE_NUM 2 +#define MASK_LENGTH 32 +#define MASK_BASE_NUM 2 -#define CONFIGFILE_PATH "/etc/oncn-mda/oncn-mda.conf" -#define BPF_PIN_FOLDER "/sys/fs/bpf/meshAccelerate" -#define SOCK_OPS_PATH_INIT "/usr/share/oncn-mda/sock_ops.c.o" -#define SOCK_REDIRECT_PATH_INIT "/usr/share/oncn-mda/sock_redirect.c.o" +#define CONFIGFILE_PATH "/etc/oncn-mda/oncn-mda.conf" +#define BPF_PIN_FOLDER "/sys/fs/bpf/meshAccelerate" +#define SOCK_OPS_PATH_INIT "/usr/share/oncn-mda/sock_ops.c.o" +#define SOCK_REDIRECT_PATH_INIT "/usr/share/oncn-mda/sock_redirect.c.o" struct input_filter_rule { - int input_ip_num; - int input_port_num; + int input_ip_num; + int input_port_num; #if MDA_GID_UID_FILTER - int input_uid_num; - int input_gid_num; + int input_uid_num; + int input_gid_num; #endif - char input_ip[MAX_PARAM_LENGTH][MAX_CIDR_LENGTH]; - char input_port[MAX_PARAM_LENGTH][MAX_PORT_RANGE_LENGTH]; + char input_ip[MAX_PARAM_LENGTH][MAX_CIDR_LENGTH]; + char input_port[MAX_PARAM_LENGTH][MAX_PORT_RANGE_LENGTH]; #if MDA_GID_UID_FILTER - __u32 input_uid[MAX_PARAM_LENGTH]; - __u32 input_gid[MAX_PARAM_LENGTH]; + __u32 input_uid[MAX_PARAM_LENGTH]; + __u32 input_gid[MAX_PARAM_LENGTH]; #endif }; struct cmd { - const char* cmd; - int (*func)(int argc, char* const *argv); + const char *cmd; + int (*func)(int argc, char *const *argv); }; enum MESH_MAP { - // Do not modify the sequence, add later - // This order already corresponds to the pin file name in g_pinMapFilePath during initialization - MESH_MAP_OPS_MAP = 0, + // Do not modify the sequence, add later + // This order already corresponds to the pin file name in g_pinMapFilePath during initialization + MESH_MAP_OPS_MAP = 0, #if MDA_GID_UID_FILTER - MESH_MAP_OPS_HELPER_MAP, + MESH_MAP_OPS_HELPER_MAP, #endif - MESH_MAP_OPS_PARAM_MAP, - MESH_MAP_OPS_PROXY_MAP, - MESH_MAP_OPS_DUMP_I_MAP, - MESH_MAP_OPS_DUMP_DATA_MAP, - MESH_MAP_NUM + MESH_MAP_OPS_PARAM_MAP, + MESH_MAP_OPS_PROXY_MAP, + MESH_MAP_OPS_DUMP_I_MAP, + MESH_MAP_OPS_DUMP_DATA_MAP, + MESH_MAP_NUM }; enum MESH_PROG { - // Do not modify the sequence, add later - // This order already corresponds to the pin file name in g_pinMapFilePath during initialization - MESH_PROG_OPS = 0, - MESH_PROG_REDIRECT, - MESH_PROG_NUM + // Do not modify the sequence, add later + // This order already corresponds to the pin file name in g_pinMapFilePath during initialization + MESH_PROG_OPS = 0, + MESH_PROG_REDIRECT, + MESH_PROG_NUM }; struct mesh_map_info { - char name[BPF_OBJ_NAME_LEN]; - char pin_file_path[PATH_MAX]; - struct bpf_create_map_attr* xattr; - int fd; + char name[BPF_OBJ_NAME_LEN]; + char pin_file_path[PATH_MAX]; + struct bpf_create_map_attr *xattr; + int fd; }; struct mesh_prog_info { - char name[BPF_OBJ_NAME_LEN]; - char pin_file_path[PATH_MAX]; - struct bpf_object_open_attr* xattr; - enum bpf_attach_type attach_type; - int attach_fd; - int fd; + char name[BPF_OBJ_NAME_LEN]; + char pin_file_path[PATH_MAX]; + struct bpf_object_open_attr *xattr; + enum bpf_attach_type attach_type; + int attach_fd; + int fd; }; struct mesh_service_info { - struct mesh_map_info map_fds[MESH_MAP_NUM]; - struct mesh_prog_info prog_fds[MESH_PROG_NUM]; + struct mesh_map_info map_fds[MESH_MAP_NUM]; + struct mesh_prog_info prog_fds[MESH_PROG_NUM]; }; // global.c -int check_cidr(const char* const src, __u32* const ip, __u32* const mask); -int check_port(const char* const src, __u32* const begin_port, __u32* const end_port); -int init_fds(struct mesh_service_info* const fds, int cgroup_fd); -int get_u32_num(const char* const src, __u32* const ret); +int check_cidr(const char *const src, __u32 *const ip, __u32 *const mask); +int check_port(const char *const src, __u32 *const begin_port, __u32 *const end_port); +int init_fds(struct mesh_service_info *const fds, int cgroup_fd); +int get_u32_num(const char *const src, __u32 *const ret); int get_cgroup_root_fd(void); -int get_map_filter_rule(const struct mesh_map_info* const param_map_info, struct sock_param* const param_list); +int get_map_filter_rule(const struct mesh_map_info *const param_map_info, struct sock_param *const param_list); // query.c -int do_query(int argc, char* const *argv); -int check_accelerating_on(const struct mesh_service_info* const fds); +int do_query(int argc, char *const *argv); +int check_accelerating_on(const struct mesh_service_info *const fds); // switch.c -int do_enable(int argc, char* const *argv); -int do_disable(int argc, char* const *argv); -void close_fds(int cgroup_fd, const struct mesh_service_info* const fds); +int do_enable(int argc, char *const *argv); +int do_disable(int argc, char *const *argv); +void close_fds(int cgroup_fd, const struct mesh_service_info *const fds); // chain.c -int do_chain(int argc, char* const *argv, struct sock_param* const filter_rules); +int do_chain(int argc, char *const *argv, struct sock_param *const filter_rules); #endif diff --git a/oncn-mda/include/mesh_accelerate.h b/oncn-mda/include/mesh_accelerate.h index 6fdd0222f..307bc905e 100644 --- a/oncn-mda/include/mesh_accelerate.h +++ b/oncn-mda/include/mesh_accelerate.h @@ -29,98 +29,98 @@ #include "data.h" enum bpf_loglevel { - BPF_LOG_ERROR = 0, - BPF_LOG_WARN, - BPF_LOG_INFO, - BPF_LOG_DEBUG, + BPF_LOG_ERROR = 0, + BPF_LOG_WARN, + BPF_LOG_INFO, + BPF_LOG_DEBUG, }; -#define BPF_LOGLEVEL BPF_LOG_ERROR +#define BPF_LOGLEVEL BPF_LOG_ERROR #ifndef bpf_printk -# define bpf_printk(fmt, ...) \ - ({ \ - char ____fmt[] = fmt; \ - bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \ - }) +#define bpf_printk(fmt, ...) \ + ({ \ + char ____fmt[] = fmt; \ + bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \ + }) #endif -#define bpf_log(l, f, ...) \ -do { \ - if (BPF_LOG_ ## l <= BPF_LOGLEVEL) \ - bpf_printk("[oncn-mda "# l"] "f"", ##__VA_ARGS__); \ -} while (0) +#define bpf_log(l, f, ...) \ + do { \ + if (BPF_LOG_##l <= BPF_LOGLEVEL) \ + bpf_printk("[oncn-mda " #l "] " f "", ##__VA_ARGS__); \ + } while (0) #ifndef force_read -#define force_read(X) (*(volatile typeof(X)*)&(X)) +#define force_read(X) (*(volatile typeof(X) *)&(X)) #endif #define SO_ORIGINAL_DST 800 -#define FILTER_PASS true +#define FILTER_PASS true #define FILTER_RETURN false -#define UID_LENGTH 32 +#define UID_LENGTH 32 #define FORMAT_IP_LENGTH 16 #define LOOPBACK_ADDR 16777343 struct bpf_map_def SEC("maps") SOCK_OPS_MAP_NAME = { - .type = BPF_MAP_TYPE_SOCKHASH, - .key_size = sizeof(struct sock_key), - .value_size = sizeof(int), - .max_entries = SKOPS_MAP_SIZE, - .map_flags = 0, + .type = BPF_MAP_TYPE_SOCKHASH, + .key_size = sizeof(struct sock_key), + .value_size = sizeof(int), + .max_entries = SKOPS_MAP_SIZE, + .map_flags = 0, }; struct bpf_map_def SEC("maps") SOCK_PARAM_MAP_NAME = { - .type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(__u32), - .value_size = sizeof(struct sock_param), - .max_entries = 1, + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(struct sock_param), + .max_entries = 1, }; struct bpf_map_def SEC("maps") SOCK_OPS_PROXY_MAP_NAME = { - .type = BPF_MAP_TYPE_HASH, - .key_size = sizeof(struct sock_key), - .value_size = sizeof(struct sock_key), - .max_entries = SKOPS_MAP_SIZE, - .map_flags = 0, + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(struct sock_key), + .value_size = sizeof(struct sock_key), + .max_entries = SKOPS_MAP_SIZE, + .map_flags = 0, }; #if MDA_GID_UID_FILTER struct bpf_map_def SEC("maps") SOCK_OPS_HELPER_MAP_NAME = { - .type = BPF_MAP_TYPE_HASH, - .key_size = sizeof(struct sock_key), - .value_size = sizeof(struct uid_gid_info), - .max_entries = SKOPS_MAP_SIZE, - .map_flags = 0, + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(struct sock_key), + .value_size = sizeof(struct uid_gid_info), + .max_entries = SKOPS_MAP_SIZE, + .map_flags = 0, }; #endif struct bpf_map_def SEC("maps") SOCK_DUMP_MAP_I_NAME = { - .type = BPF_MAP_TYPE_QUEUE, - .key_size = 0, - .value_size = sizeof(struct dump_data), - .max_entries = DUMP_QUEUE_LENGTH, - .map_flags = 0, + .type = BPF_MAP_TYPE_QUEUE, + .key_size = 0, + .value_size = sizeof(struct dump_data), + .max_entries = DUMP_QUEUE_LENGTH, + .map_flags = 0, }; struct bpf_map_def SEC("maps") SOCK_DUMP_CPU_ARRAY_NAME = { - .type = BPF_MAP_TYPE_PERCPU_ARRAY, - .key_size = sizeof(__u32), - .value_size = sizeof(struct dump_data), - .max_entries = 1, + .type = BPF_MAP_TYPE_PERCPU_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(struct dump_data), + .max_entries = 1, }; #if MDA_LOOPBACK_ADDR -static inline void set_netns_cookie(void* const ctx, struct sock_key* const key) +static inline void set_netns_cookie(void *const ctx, struct sock_key *const key) { - if (key->sip4 != LOOPBACK_ADDR || key->dip4 != LOOPBACK_ADDR) - key->netns_cookie = 0; - else - key->netns_cookie = bpf_get_netns_cookie(ctx); - return; + if (key->sip4 != LOOPBACK_ADDR || key->dip4 != LOOPBACK_ADDR) + key->netns_cookie = 0; + else + key->netns_cookie = bpf_get_netns_cookie(ctx); + return; } #endif