-
Notifications
You must be signed in to change notification settings - Fork 137
feat: add cgroup_skb eBPF program #1474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: sweeywu <sweetwx6@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @wxnzb, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a new configuration option for eBPF programs to enable periodic reporting and significantly enhances the unit test coverage for cgroup_skb eBPF programs. The added tests validate the functionality of ingress and egress cgroup_skb programs, ensuring their correct operation in monitoring and managing TCP connection details within cgroups.
Highlights
- New BPF Configuration: Added
EnablePeriodicReportto theGlobalBpfConfigstruct, introducing a new configuration option for controlling periodic reporting within BPF programs. - Expanded BPF Test Suite: Introduced a comprehensive new test suite (
testCgroupSkb) specifically forcgroup_skbeBPF programs, covering both ingress and egress traffic scenarios to ensure proper network monitoring and handling. - BPF Test Mocking Framework: Created a new eBPF test program (
workload_cgroup_skb_test.c) that includes a mock implementation forbpf_sk_storage_get. This allows for more controlled and isolated testing ofcgroup_skblogic by simulating BPF socket storage behavior.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
BPF code takes flight, Network packets, swift and bright, Tests ensure it's right.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces eBPF programs attached to cgroups for sk_buff processing, along with corresponding unit tests. I've identified a few critical issues that should be addressed to ensure the code is robust and maintainable, including code duplication, a hardcoded cgroup path, and a recursive call in a BPF mock function.
test/bpf_ut/bpftest/workload_test.go
Outdated
| } | ||
| } | ||
| lk, err := link.AttachCgroup(link.CgroupOptions{ | ||
| Path: constants.Cgroup2Path, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cgroupPath parameter is passed to this function but is not used. Instead, a hardcoded value constants.Cgroup2Path is used when attaching the cgroup program. This is a bug that makes the function's behavior differ from its signature and could lead to tests attaching to the wrong cgroup if the path were to change.
Path: cgroupPath,| { | ||
| struct bpf_sock *sk_sock = (struct bpf_sock *)sk; | ||
| void *storage = NULL; | ||
| storage = bpf_sk_storage_get(map, sk_sock, value, flags); | ||
| if (!storage && map == &map_of_sock_storage) { | ||
| storage = &mock_storage; | ||
| } | ||
|
|
||
| return storage; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of this mock function is incorrect. Line 21 causes infinite recursion because bpf_sk_storage_get is macro-defined as mock_bpf_sk_storage_get. This will lead to a stack overflow at runtime. BPF helpers cannot be called from userspace test code; they must be fully mocked.
The function body should be replaced with logic that simulates the helper's behavior without calling the real helper.
| { | |
| struct bpf_sock *sk_sock = (struct bpf_sock *)sk; | |
| void *storage = NULL; | |
| storage = bpf_sk_storage_get(map, sk_sock, value, flags); | |
| if (!storage && map == &map_of_sock_storage) { | |
| storage = &mock_storage; | |
| } | |
| return storage; | |
| } | |
| { | |
| // Unused parameters must be cast to void to prevent compiler warnings. | |
| (void)sk; | |
| (void)value; | |
| (void)flags; | |
| // The mock should not call the real bpf_sk_storage_get helper. | |
| // It should only return the mock data for the specific map being tested. | |
| if (map == &map_of_sock_storage) { | |
| return &mock_storage; | |
| } | |
| return NULL; | |
| } |
test/bpf_ut/bpftest/workload_test.go
Outdated
| name: "CgroupEgress_is_managed_by_kmesh_skb", | ||
| workFunc: func(t *testing.T, cgroupPath, objFilePath string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workFunc for CgroupEgress_is_managed_by_kmesh_skb is almost an exact copy of the one for CgroupIngress_is_managed_by_kmesh_skb. This large-scale code duplication (over 100 lines) is a significant maintainability concern. Future changes will need to be made in two places, which is error-prone.
Please consider refactoring the common logic into a shared helper function that accepts the BPF program name as a parameter. This will greatly reduce duplication and improve the long-term health of the test suite.
test/bpf_ut/bpftest/workload_test.go
Outdated
| // converts a uint32 IPv4 address into a dotted-decimal string | ||
| func printIPv4(ip uint32) string { | ||
| b := make([]byte, 4) | ||
| b[0] = byte(ip & 0xff) | ||
| b[1] = byte((ip >> 8) & 0xff) | ||
| b[2] = byte((ip >> 16) & 0xff) | ||
| b[3] = byte((ip >> 24) & 0xff) | ||
| return fmt.Sprintf("%d.%d.%d.%d", b[3], b[2], b[1], b[0]) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation of printIPv4 is functionally correct but unnecessarily complex and hard to follow. It manually extracts bytes from the uint32 and reassembles them for printing. A more idiomatic and readable approach would be to use the standard library's binary and net packages. This improves maintainability and makes the code's intent clearer.
The function comment should also be updated to clarify the expected endianness of the input IP address.
// converts a uint32 IPv4 address in host byte order into a dotted-decimal string
func printIPv4(ip uint32) string {
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, ip)
return net.IP(b).String()
}Signed-off-by: sweeywu <sweetwx6@gmail.com>
Signed-off-by: sweeywu <sweetwx6@gmail.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
Signed-off-by: sweeywu <sweetwx6@gmail.com>
Signed-off-by: sweeywu <sweetwx6@gmail.com>
LiZhenCheng9527
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost lgtm
| if err := binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &info); err != nil { | ||
| log.Printf("parsing ringbuf event: %s", err) | ||
| } else { | ||
| fmt.Printf("tcp_probe_info:\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the necessary output information?
|
@hzxuzhonghu @sancppp PTAL |
hzxuzhonghu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
Please make the pr title more descriptive
Got it, I will update the PR title. Thanks for the suggestion! |
|
/lgtm |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: LiZhenCheng9527 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What type of PR is this?
What this PR does / why we need it:
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?: