-
Notifications
You must be signed in to change notification settings - Fork 525
PoC: Templated Policies for Reduced Memory and eBPF Program Count #4279
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -91,6 +91,39 @@ DEFINE_ARRAY_OF_STRING_MAPS(9) | |
| DEFINE_ARRAY_OF_STRING_MAPS(10) | ||
| #endif | ||
|
|
||
| #define POLICY_STR_OUTER_MAX_ENTRIES 1 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw some discussion here, #1408 about having one single map instead of 11 different maps. We can also accept the performance loss and use just one unique shared map to simplify things |
||
| #define POLICY_STR_INNER_MAX_ENTRIES 1 | ||
|
|
||
| #define DEFINE_POLICY_STR_HASH_OF_MAPS(N) \ | ||
| struct { \ | ||
| __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); \ | ||
| __uint(max_entries, POLICY_STR_OUTER_MAX_ENTRIES); \ | ||
| __uint(map_flags, BPF_F_NO_PREALLOC); \ | ||
| __type(key, __u32); \ | ||
| __array( \ | ||
| values, struct { \ | ||
| __uint(type, BPF_MAP_TYPE_HASH); \ | ||
| __uint(max_entries, POLICY_STR_INNER_MAX_ENTRIES); \ | ||
| __type(key, __u8[STRING_MAPS_SIZE_##N]); \ | ||
| __type(value, __u8); \ | ||
| }); \ | ||
| } pol_str_maps_##N SEC(".maps"); | ||
|
|
||
| DEFINE_POLICY_STR_HASH_OF_MAPS(0) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(1) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(2) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(3) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(4) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(5) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(6) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(7) | ||
|
|
||
| #ifdef __V511_BPF_PROG | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(8) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(9) | ||
| DEFINE_POLICY_STR_HASH_OF_MAPS(10) | ||
| #endif | ||
|
|
||
| struct { | ||
| __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
| __uint(max_entries, 1); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -648,7 +648,7 @@ type EventConfig struct { | |
| ArgReturnAction int32 `align:"argreturnaction"` | ||
| PolicyID uint32 `align:"policy_id"` | ||
| Flags uint32 `align:"flags"` | ||
| Pad uint32 `align:"pad"` | ||
| CgroupFilter uint32 `align:"cgroup_filter"` | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just an hack to enable/disable the new logic |
||
| BTFArg [EventConfigMaxArgs][MaxBTFArgDepth]ConfigBTFArg `align:"btf_arg"` | ||
| UsdtArg [EventConfigMaxUsdtArgs]ConfigUsdtArg `align:"usdt_arg"` | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| package policyfilter | ||
|
|
||
| import ( | ||
| "github.com/cilium/tetragon/pkg/labels" | ||
| ) | ||
|
|
||
| type basePolicy struct { | ||
| id PolicyID | ||
| namespace string | ||
| containerSelector labels.Selector | ||
| podSelector labels.Selector | ||
| } | ||
|
|
||
| func (b *basePolicy) setID(polID PolicyID) { | ||
| b.id = polID | ||
| } | ||
|
|
||
| func (b *basePolicy) setFilters(namespace string, podSelector labels.Selector, containerSelector labels.Selector) { | ||
| b.namespace = namespace | ||
| b.podSelector = podSelector | ||
| b.containerSelector = containerSelector | ||
| } | ||
|
|
||
| func (b *basePolicy) getID() PolicyID { | ||
| return b.id | ||
| } | ||
|
|
||
| func (b *basePolicy) podInfoMatches(pod *podInfo) bool { | ||
| if pod == nil { | ||
| return false | ||
| } | ||
| return b.podMatches(pod.namespace, pod.labels) | ||
| } | ||
|
|
||
| func (b *basePolicy) podMatches(podNs string, podLabels labels.Labels) bool { | ||
| if b.namespace != "" && podNs != b.namespace { | ||
| return false | ||
| } | ||
| podLabels1 := make(labels.Labels) | ||
| if podLabels != nil { | ||
| podLabels1 = podLabels | ||
| } | ||
| if _, ok := podLabels1[labels.K8sPodNamespace]; !ok { | ||
| podLabels1[labels.K8sPodNamespace] = podNs | ||
| } | ||
| return b.podSelector.Match(podLabels1) | ||
| } | ||
|
|
||
| func (b *basePolicy) containerMatches(container *containerInfo) bool { | ||
| if container == nil { | ||
| return false | ||
| } | ||
| filter := labels.Labels{ | ||
| "name": container.name, | ||
| "repo": container.repo, | ||
| } | ||
| return b.containerSelector.Match(filter) | ||
| } | ||
|
|
||
| func (b *basePolicy) matchingContainersCgroupIDs(containers []containerInfo) []CgroupID { | ||
| var ids []CgroupID | ||
| for i := range containers { | ||
| if b.containerMatches(&containers[i]) { | ||
| ids = append(ids, containers[i].cgID) | ||
| } | ||
| } | ||
| return ids | ||
| } |
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.
This sounds like a duplicate logic of the above
policy_filter_check(). Instead of hardcoding a policy value inside the policy config and using it as a key for a globalBPF_MAP_TYPE_HASH_OF_MAPS, we could just use a simple hashmapBPF_MAP_TYPE_HASHand configure at runtime the policy_id associated with the groups.If we deploy a k8s-aware policy (without bindings) and we assign it a
policy_id=4We can translate the pod selectors into a simple hash map identical to the one introduced in this patch
So instead of starting from the policy_id to get a HashMap like
We immediately jump inside the hash map with the cgroup-id, and we can recover the policy_id number from there.
WDYT?