Skip to content

Commit 9afc8c9

Browse files
Merge branch 'main' into main
2 parents 5228975 + 0847367 commit 9afc8c9

File tree

8 files changed

+690
-90
lines changed

8 files changed

+690
-90
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: Sync kmeshctl Docs to Website (via PR)
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- docs/ctl/**
9+
- .github/workflows/sync-kmeshctl-docs.yml
10+
11+
jobs:
12+
sync-docs:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: 🧭 Checkout website repository
17+
uses: actions/checkout@v4
18+
with:
19+
repository: kmesh-net/website
20+
token: ${{ secrets.GH_PAT }}
21+
path: website
22+
ref: main
23+
fetch-depth: 1
24+
25+
- name: 🧭 Checkout kmesh repository
26+
uses: actions/checkout@v4
27+
with:
28+
repository: kmesh-net/kmesh
29+
token: ${{ secrets.GH_PAT }}
30+
path: kmesh
31+
fetch-depth: 1
32+
33+
- name: 🔁 Sync kmeshctl Docs Using rsync
34+
run: |
35+
set -e
36+
37+
# Define source and target directories
38+
KMESH_CTL_DIR="kmesh/docs/ctl"
39+
WEBSITE_KMESHCTL_DIR="website/docs/kmeshctl"
40+
41+
echo "🔍 Source directory: $KMESH_CTL_DIR"
42+
echo "🎯 Target directory: $WEBSITE_KMESHCTL_DIR"
43+
44+
# Check if source directory exists
45+
if [ ! -d "$KMESH_CTL_DIR" ]; then
46+
echo "❌ ERROR: Source directory does not exist!"
47+
exit 1
48+
fi
49+
50+
# Create target directory if it doesn't exist
51+
if [ ! -d "$WEBSITE_KMESHCTL_DIR" ]; then
52+
echo "📁 Creating $WEBSITE_KMESHCTL_DIR..."
53+
mkdir -p "$WEBSITE_KMESHCTL_DIR"
54+
fi
55+
56+
# Sync files using rsync
57+
echo "🔄 Syncing files with rsync..."
58+
rsync -avc --delete --exclude='.git' --exclude='.*' "$KMESH_CTL_DIR/" "$WEBSITE_KMESHCTL_DIR/"
59+
60+
# Navigate to the website repository
61+
cd website
62+
63+
# Stage changes
64+
git add -A docs/kmeshctl/
65+
66+
# Check if there are any changes
67+
if git diff --cached --quiet; then
68+
echo "✅ No changes detected."
69+
exit 0
70+
else
71+
echo "✨ Changes detected. Creating commit..."
72+
git config user.name "github-actions[bot]"
73+
git config user.email "github-actions[bot]@users.noreply.github.com"
74+
git commit -m 'docs: sync kmeshctl docs from kmesh-net/kmesh'
75+
fi
76+
77+
- name: 🤝 Create Pull Request
78+
uses: peter-evans/create-pull-request@v5
79+
with:
80+
token: ${{ secrets.GH_PAT }}
81+
path: website
82+
branch-suffix: timestamp
83+
base: main
84+
title: "docs: sync latest kmeshctl documentation (commit ${{ github.sha }})"
85+
body: |
86+
This PR syncs the latest changes from [kmesh/docs/ctl](https://github.com/kmesh-net/kmesh/tree/main/docs/ctl).
87+
88+
**Triggered by commit:** ${{ github.sha }}
89+
90+
Please review and merge.
91+
commit-message: "docs: sync kmeshctl docs"
92+
delete-branch: true

bpf/kmesh/workload/sendmsg.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
#include <bpf/bpf_helpers.h>
88
#include "bpf_log.h"
99
#include "bpf_common.h"
10-
10+
#ifdef KMESH_UNIT_TEST
11+
struct {
12+
__uint(type, BPF_MAP_TYPE_SOCKHASH);
13+
__type(key, struct bpf_sock_tuple);
14+
__type(value, __u32);
15+
__uint(max_entries, MAP_SIZE_OF_MANAGER);
16+
__uint(map_flags, 0);
17+
} map_of_kmesh_sendmsg SEC(".maps");
18+
#endif
1119
/*
1220
* sk msg is used to encode metadata into the payload when the client sends
1321
* data to waypoint.

test/bpf_ut/Makefile

Lines changed: 11 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,18 @@
1-
MAKEFLAGS += -r
2-
3-
QUIET ?= @
4-
CLANG ?= clang
5-
GO ?= go
6-
71
ROOT_DIR := $(shell git rev-parse --show-toplevel)
8-
TEST_DIR := $(ROOT_DIR)/test/bpf_ut
9-
10-
FLAGS := -isystem /usr/include -I/usr/local/include
11-
FLAGS += -I./include -I$(ROOT_DIR)/bpf/include
12-
FLAGS += -fPIC -D__NR_CPUS__=$(shell nproc --all) -D__TARGET_ARCH_x86_64 -D__x86_64__ -D_GNU_SOURCE -DKERNEL_VERSION_HIGHER_5_13_0=1
13-
FLAGS += -O2 -g
14-
15-
CLANG_FLAGS := ${FLAGS} --target=bpf -std=gnu99
16-
# eBPF verifier enforces unaligned access checks where necessary, so don't
17-
# let clang complain too early.
18-
CLANG_FLAGS += -Wall -Wextra
19-
CLANG_FLAGS += -Wno-address-of-packed-member
20-
CLANG_FLAGS += -Wno-unknown-warning-option
21-
CLANG_FLAGS += -Wno-gnu-variable-sized-type-not-at-end
22-
CLANG_FLAGS += -Wenum-conversion
23-
CLANG_FLAGS += -Wimplicit-fallthrough
24-
# Create dependency files for each .o file.
25-
CLANG_FLAGS += -MD
26-
27-
.PHONY: all clean run
282

29-
all: xdp_shutdown_in_userspace_test.o \
30-
xdp_authz_offload_test.o \
31-
workload_sockops_test.o \
32-
tc_mark_encrypt_test.o \
33-
tc_mark_decrypt_test.o \
34-
workload_cgroup_skb_test.o
3+
.PHONY: all build-bpf-tests run clean
354

5+
all: build-bpf-tests
366

37-
XDP_FLAGS = -I$(ROOT_DIR)/bpf/kmesh/ -I$(ROOT_DIR)/bpf/kmesh/workload/include -I$(ROOT_DIR)/api/v2-c
38-
xdp_%.o: xdp_%.c
39-
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(XDP_FLAGS) -c $< -o $@
7+
build-bpf-tests:
8+
@echo "Building BPF unit tests..."
9+
@bash $(ROOT_DIR)/test/bpf_ut/build_bpf_ut_tests.sh
4010

41-
WORKLOAD_SOCKOPS_FLAGS = -I$(ROOT_DIR)/bpf/kmesh/ -I$(ROOT_DIR)/bpf/kmesh/probes -I$(ROOT_DIR)/bpf/kmesh/workload/include -I$(ROOT_DIR)/api/v2-c
42-
workload_sockops_test.o: workload_sockops_test.c
43-
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(WORKLOAD_SOCKOPS_FLAGS) -c $< -o $@
11+
run: build-bpf-tests
12+
@echo "Running BPF unit tests..."
13+
@cd $(ROOT_DIR)/test/bpf_ut/bpftest && go test -v ./...
4414

45-
TC_FLAGS = -I$(ROOT_DIR)/bpf/kmesh/ -I$(ROOT_DIR)/bpf/kmesh/general/include -I$(ROOT_DIR)/bpf/kmesh/general -I$(ROOT_DIR)/api/v2-c
46-
tc_mark_encrypt_test.o: tc_mark_encrypt_test.c
47-
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(TC_FLAGS) -c $< -o $@
48-
tc_mark_decrypt_test.o: tc_mark_decrypt_test.c
49-
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(TC_FLAGS) -c $< -o $@
50-
51-
WORKLOAD_CGROUP_SKB_FLAGS = -I$(ROOT_DIR)/bpf/kmesh/ \
52-
-I$(ROOT_DIR)/bpf/kmesh/probes \
53-
-I$(ROOT_DIR)/bpf/kmesh/workload/include \
54-
-I$(ROOT_DIR)/api/v2-c
55-
workload_cgroup_skb_test.o: workload_cgroup_skb_test.c
56-
$(QUIET) $(CLANG) $(CLANG_FLAGS) $(WORKLOAD_CGROUP_SKB_FLAGS) -c $< -o $@
5715
clean:
58-
$(QUIET) rm -f $(wildcard *.o)
59-
$(QUIET) rm -f $(wildcard *.d)
60-
$(QUIET) echo "clean all object files"
61-
62-
BPF_TEST_FLAGS:=
63-
ifneq ($(shell id -u), 0)
64-
BPF_TEST_FLAGS += -exec "sudo -E"
65-
endif
66-
ifeq ($(V),1)
67-
BPF_TEST_FLAGS += -test.v
68-
endif
69-
ifeq ($(COVER),1)
70-
ifndef COVERFORMAT
71-
COVERFORMAT:=html
72-
endif
73-
BPF_TEST_FLAGS += -coverage-report $(ROOT_DIR)/bpf-coverage.$(COVERFORMAT) -coverage-format $(COVERFORMAT)
74-
ifdef NOCOVER
75-
BPF_TEST_FLAGS += -no-test-coverage "$(NOCOVER)"
76-
endif
77-
endif
78-
ifeq ($(INSTRLOG),1)
79-
BPF_TEST_FLAGS += -instrumentation-log $(ROOT_DIR)/test/bpf-instrumentation.log
80-
endif
81-
ifdef RUN
82-
BPF_TEST_FLAGS += -run $(RUN)
83-
endif
84-
ifdef BPF_TEST_DUMP_CTX
85-
BPF_TEST_FLAGS += -dump-ctx
86-
endif
87-
ifdef BPF_TEST_FILE
88-
BPF_TEST_FLAGS += -test $(BPF_TEST_FILE)
89-
endif
90-
91-
run: all
92-
$(GO) test ./bpftest -bpf-ut-path $(ROOT_DIR)/test/bpf_ut $(BPF_TEST_FLAGS)
93-
94-
-include $(TEST_OBJECTS:.o=.d)
16+
@echo "Cleaning build files..."
17+
@rm -f $(ROOT_DIR)/test/bpf_ut/*.o
18+
@rm -f $(ROOT_DIR)/test/bpf_ut/*.d

test/bpf_ut/bpftest/bpf_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func loadAndPrepSpec(t *testing.T, elfPath string) *ebpf.CollectionSpec {
209209
for n, p := range spec.Programs {
210210
switch p.Type {
211211
// https://docs.ebpf.io/linux/syscall/BPF_PROG_TEST_RUN/
212-
case ebpf.XDP, ebpf.SchedACT, ebpf.SchedCLS, ebpf.SocketFilter, ebpf.CGroupSKB, ebpf.SockOps:
212+
case ebpf.XDP, ebpf.SchedACT, ebpf.SchedCLS, ebpf.SocketFilter, ebpf.CGroupSKB, ebpf.SockOps, ebpf.SkMsg:
213213
continue
214214
}
215215

test/bpf_ut/bpftest/tlv_utils.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//go:build linux && (amd64 || arm64) && !aix && !ppc64
2+
3+
/*
4+
* Copyright The Kmesh Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at:
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package bpftests
20+
21+
import (
22+
"encoding/binary"
23+
"fmt"
24+
"net"
25+
"testing"
26+
)
27+
28+
// TLV protocol constants and structs
29+
const (
30+
TLV_ORG_DST_ADDR_TYPE = 0x01
31+
TLV_PAYLOAD_TYPE = 0xFE
32+
TLV_END_LENGTH = 0x00000000
33+
)
34+
35+
// TLV header structure
36+
type TLVHeader struct {
37+
Type uint8
38+
Length uint32
39+
}
40+
41+
// TLV data content
42+
type TLVData struct {
43+
IP net.IP
44+
Port uint16
45+
}
46+
47+
// ParseTLVMessage: parse TLV message
48+
func ParseTLVMessage(data []byte) (*TLVData, error) {
49+
if len(data) < 16 {
50+
return nil, fmt.Errorf("data too short for TLV format: got %d bytes, need at least 16", len(data))
51+
}
52+
// parse TLV header
53+
header := TLVHeader{
54+
Type: data[0],
55+
Length: binary.BigEndian.Uint32(data[1:5]),
56+
}
57+
// test
58+
if header.Type != TLV_ORG_DST_ADDR_TYPE {
59+
return nil, fmt.Errorf("unexpected TLV type: got %#x, want %#x", header.Type, TLV_ORG_DST_ADDR_TYPE)
60+
}
61+
var tlvData TLVData
62+
var expectedMinSize int
63+
if header.Length == 6 {
64+
if len(data) < 16 {
65+
return nil, fmt.Errorf("IPv4 TLV data too short: got %d bytes, need at least 16", len(data))
66+
}
67+
tlvData.IP = net.IPv4(data[5], data[6], data[7], data[8])
68+
tlvData.Port = binary.BigEndian.Uint16(data[9:11])
69+
expectedMinSize = 16
70+
} else if header.Length == 18 {
71+
if len(data) < 28 {
72+
return nil, fmt.Errorf("IPv6 TLV data too short: got %d bytes, need at least 28", len(data))
73+
}
74+
tlvData.IP = net.IP(data[5:21])
75+
tlvData.Port = binary.BigEndian.Uint16(data[21:23])
76+
expectedMinSize = 28
77+
} else {
78+
return nil, fmt.Errorf("unsupported TLV length: %d (expected 6 for IPv4 or 18 for IPv6)", header.Length)
79+
}
80+
if len(data) < expectedMinSize {
81+
return nil, fmt.Errorf("data too short for end tag validation: got %d bytes, need at least %d", len(data), expectedMinSize)
82+
}
83+
endTag := data[expectedMinSize-5]
84+
if endTag != TLV_PAYLOAD_TYPE {
85+
return nil, fmt.Errorf("missing or wrong TLV end tag: got %#x, want %#x", endTag, TLV_PAYLOAD_TYPE)
86+
}
87+
endLength := binary.BigEndian.Uint32(data[expectedMinSize-4 : expectedMinSize])
88+
if endLength != TLV_END_LENGTH {
89+
return nil, fmt.Errorf("unexpected TLV end length: got %#08x, want %#08x", endLength, TLV_END_LENGTH)
90+
}
91+
return &tlvData, nil
92+
}
93+
94+
// verify the integrity and correctness of the TLV message
95+
func ValidateTLVMessage(t *testing.T, data []byte, expectedIP net.IP, expectedPort uint16) error {
96+
tlvData, err := ParseTLVMessage(data)
97+
if err != nil {
98+
return fmt.Errorf("failed to parse TLV message: %v", err)
99+
}
100+
if !tlvData.IP.Equal(expectedIP) {
101+
return fmt.Errorf("unexpected TLV IP: got %v, want %v", tlvData.IP, expectedIP)
102+
}
103+
if tlvData.Port != expectedPort {
104+
return fmt.Errorf("unexpected TLV port: got %d, want %d", tlvData.Port, expectedPort)
105+
}
106+
t.Logf("TLV message validation successful: IP=%v, Port=%d", tlvData.IP, tlvData.Port)
107+
return nil
108+
}

0 commit comments

Comments
 (0)