Skip to content

Commit

Permalink
Working code for cluster-scoped XDP programs.
Browse files Browse the repository at this point in the history
Much more cleanup, testing, and then support for other program types
TBD.

Signed-off-by: Andre Fredette <[email protected]>
  • Loading branch information
anfredette committed Jan 22, 2025
1 parent 89ee1c3 commit 218f890
Show file tree
Hide file tree
Showing 71 changed files with 3,596 additions and 1,462 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ COMMON_FLAGS ?= ${VERIFY_FLAG} --go-header-file $(shell pwd)/hack/boilerplate.go
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) rbac:roleName=agent-role paths="./controllers/bpfman-agent/..." output:rbac:artifacts:config=config/rbac/bpfman-agent
$(CONTROLLER_GEN) rbac:roleName=operator-role paths="./controllers/bpfman-operator" output:rbac:artifacts:config=config/rbac/bpfman-operator
$(CONTROLLER_GEN) rbac:roleName=agent-role paths="./controllers/bpfman-agent/...;./controllers/app-agent/..." output:rbac:artifacts:config=config/rbac/bpfman-agent
$(CONTROLLER_GEN) rbac:roleName=operator-role paths="./controllers/bpfman-operator;./controllers/app-operator" output:rbac:artifacts:config=config/rbac/bpfman-operator

.PHONY: generate
generate: manifests generate-register generate-deepcopy generate-typed-clients generate-typed-listers generate-typed-informers ## Generate ALL auto-generated code.
Expand Down
7 changes: 7 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,11 @@ resources:
kind: BpfNsApplication
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
controller: true
domain: bpfman.io
kind: BpfApplicationNode
path: github.com/bpfman/bpfman-operator/apis/v1alpha1
version: v1alpha1
version: "3"
29 changes: 18 additions & 11 deletions apis/v1alpha1/bpfApplicationNode_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ import (
// +union
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'XDP' ? has(self.xdp) : !has(self.xdp)",message="xdp configuration is required when type is XDP, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'TC' ? has(self.tc) : !has(self.tc)",message="tc configuration is required when type is TC, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'TCX' ? has(self.tcx) : !has(self.tcx)",message="tcx configuration is required when type is TCX, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'TCX' ? has(self.tcx) : !has(self.tcx)",message="tcx configuration is required when type is TCX, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Fentry' ? has(self.fentry) : !has(self.fentry)",message="fentry configuration is required when type is Fentry, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Fexit' ? has(self.fexit) : !has(self.fexit)",message="fexit configuration is required when type is Fexit, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Kprobe' ? has(self.kprobe) : !has(self.kprobe)",message="kprobe configuration is required when type is Kprobe, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Kretprobe' ? has(self.kretprobe) : !has(self.kretprobe)",message="kretprobe configuration is required when type is Kretprobe, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Uprobe' ? has(self.uprobe) : !has(self.uprobe)",message="uprobe configuration is required when type is Uprobe, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Uretprobe' ? has(self.uretprobe) : !has(self.uretprobe)",message="uretprobe configuration is required when type is Uretprobe, and forbidden otherwise"
// +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Tracepoint' ? has(self.tracepoint) : !has(self.tracepoint)",message="tracepoint configuration is required when type is Tracepoint, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Fexit' ? has(self.fexit) : !has(self.fexit)",message="fexit configuration is required when type is Fexit, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Kprobe' ? has(self.kprobe) : !has(self.kprobe)",message="kprobe configuration is required when type is Kprobe, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Kretprobe' ? has(self.kretprobe) : !has(self.kretprobe)",message="kretprobe configuration is required when type is Kretprobe, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Uprobe' ? has(self.uprobe) : !has(self.uprobe)",message="uprobe configuration is required when type is Uprobe, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Uretprobe' ? has(self.uretprobe) : !has(self.uretprobe)",message="uretprobe configuration is required when type is Uretprobe, and forbidden otherwise"
// // +kubebuilder:validation:XValidation:rule="has(self.type) && self.type == 'Tracepoint' ? has(self.tracepoint) : !has(self.tracepoint)",message="tracepoint configuration is required when type is Tracepoint, and forbidden otherwise"
type BpfApplicationProgramNode struct {
// AppProgramStatus records whether the program should be loaded and whether
// ProgramAttachStatus records whether the program should be loaded and whether
// the program is loaded.
AppProgramStatus `json:",inline"`
ProgramAttachStatus BpfProgramConditionType `json:"programattachstatus"`

// ProgramId is the id of the program in the kernel. Not set until the
// program is loaded.
Expand Down Expand Up @@ -103,7 +103,14 @@ type BpfApplicationProgramNode struct {

// BpfApplicationSpec defines the desired state of BpfApplication
type BpfApplicationNodeSpec struct {
AppLoadStatus `json:",inline"`
// The number of times the BpfApplicationNode has been updated. Set to 1
// when the object is created, then it is incremented prior to each update.
// This allows us to verify that the API server has the updated object prior
// to starting a new Reconcile operation.
UpdateCount int64 `json:"updatecount"`
// AppLoadStatus reflects the status of loading the bpf application on the
// given node.
AppLoadStatus BpfProgramConditionType `json:"apploadstatus"`
// Programs is a list of bpf programs contained in the parent application.
// It is a map from the bpf program name to BpfApplicationProgramNode
// elements.
Expand All @@ -117,7 +124,7 @@ type BpfApplicationNodeSpec struct {
// +kubebuilder:resource:scope=Cluster

// BpfApplicationNode is the Schema for the bpfapplications API
// +kubebuilder:printcolumn:name="NodeSelector",type=string,JSONPath=`.spec.nodeselector`
// +kubebuilder:printcolumn:name="Node",type=string,JSONPath=".metadata.labels['kubernetes.io/hostname']"
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
type BpfApplicationNode struct {
Expand Down
20 changes: 4 additions & 16 deletions apis/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ type BpfProgramCommon struct {
// program
BpfFunctionName string `json:"bpffunctionname"`

// MapOwnerSelector is used to select the loaded eBPF program this eBPF program
// OldMapOwnerSelector is used to select the loaded eBPF program this eBPF program
// will share a map with. The value is a label applied to the BpfProgram to select.
// The selector must resolve to exactly one instance of a BpfProgram on a given node
// or the eBPF program will not load.
// +optional
MapOwnerSelector metav1.LabelSelector `json:"mapownerselector"`
OldMapOwnerSelector metav1.LabelSelector `json:"oldmapownerselector"`
}

// BpfAppCommon defines the common attributes for all BpfApp programs
Expand Down Expand Up @@ -126,18 +126,6 @@ type BpfAppStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

// AppLoadStatus reflects the status of loading a bpf application on a given node.
type AppLoadStatus struct {
// Status reflects the status of loading a bpf application on a given node.
Status BpfProgramConditionType `json:"status"`
}

// AppProgramStatus reflects the overall status for attaching this program on a given node.
type AppProgramStatus struct {
// Status reflects the overall status for attaching this program on a given node.
Status BpfProgramConditionType `json:"status"`
}

// AttachInfoCommon reflects the status for one attach point for a given bpf application program
type AttachInfoCommon struct {
// ShouldAttach reflects whether the attachment should exist.
Expand All @@ -150,8 +138,8 @@ type AttachInfoCommon struct {
// id.
// ANF-TODO: For the POC, this will be the program ID.
AttachId *uint32 `json:"attachid"`
// Status reflects whether the attachment has been reconciled successfully, and if not, why.
Status BpfProgramConditionType `json:"status"`
// AttachStatus reflects whether the attachment has been reconciled successfully, and if not, why.
AttachStatus BpfProgramConditionType `json:"attachstatus"`
}

// PullPolicy describes a policy for if/when to pull a container image
Expand Down
34 changes: 1 addition & 33 deletions apis/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ metadata:
creationTimestamp: null
name: bpfman-agent-role
rules:
- apiGroups:
- bpfman.io
resources:
- bpfapplicationnodes
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- bpfman.io
resources:
- bpfapplicationnodes/finalizers
verbs:
- update
- apiGroups:
- bpfman.io
resources:
- bpfapplicationnodes/status
verbs:
- get
- patch
- update
- apiGroups:
- bpfman.io
resources:
Expand Down
2 changes: 1 addition & 1 deletion bundle/manifests/bpfman-config_v1_configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v1
data:
bpfman.agent.healthprobe.addr: :8175
bpfman.agent.image: quay.io/bpfman/bpfman-agent:latest
bpfman.agent.log.level: info
bpfman.agent.log.level: debug
bpfman.agent.metric.addr: 127.0.0.1:8174
bpfman.image: quay.io/bpfman/bpfman:latest
bpfman.log.level: info
Expand Down
98 changes: 15 additions & 83 deletions bundle/manifests/bpfman-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,87 +20,8 @@ metadata:
}
},
"nodeselector": {},
"programs": [
{
"kprobe": {
"attach_points": [
{
"func_name": "try_to_wake_up",
"offset": 0,
"retprobe": false
}
],
"bpffunctionname": "kprobe_counter"
},
"type": "Kprobe"
},
{
"tracepoint": {
"attach_points": [
{
"name": "syscalls/sys_enter_kill"
}
],
"bpffunctionname": "tracepoint_kill_recorder"
},
"type": "Tracepoint"
},
{
"tc": {
"attach_points": [
{
"direction": "ingress",
"interfaceselector": {
"primarynodeinterface": true
},
"priority": 55
}
],
"bpffunctionname": "stats"
},
"type": "TC"
},
{
"tcx": {
"attach_points": [
{
"direction": "ingress",
"interfaceselector": {
"primarynodeinterface": true
},
"priority": 500
}
],
"bpffunctionname": "tcx_stats"
},
"type": "TCX"
},
{
"type": "Uprobe",
"uprobe": {
"attach_points": [
{
"containers": {
"containernames": [
"bpfman",
"bpfman-agent"
],
"namespace": "bpfman",
"pods": {
"matchLabels": {
"name": "bpfman-daemon"
}
}
},
"func_name": "malloc",
"retprobe": false,
"target": "libc"
}
],
"bpffunctionname": "uprobe_counter"
}
},
{
"programs": {
"xdp_stats": {
"type": "XDP",
"xdp": {
"attach_points": [
Expand All @@ -114,7 +35,7 @@ metadata:
"bpffunctionname": "xdp_stats"
}
}
]
}
}
},
{
Expand Down Expand Up @@ -641,7 +562,7 @@ metadata:
capabilities: Basic Install
categories: OpenShift Optional
containerImage: quay.io/bpfman/bpfman-operator:latest
createdAt: "2025-01-03T19:50:49Z"
createdAt: "2025-01-22T13:10:53Z"
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/cni: "false"
features.operators.openshift.io/csi: "true"
Expand Down Expand Up @@ -686,6 +607,9 @@ spec:
apiservicedefinitions: {}
customresourcedefinitions:
owned:
- kind: BpfApplicationNode
name: bpfapplicationnodes.bpfman.io
version: v1alpha1
- description: BpfApplication is the Schema for the bpfapplications API
displayName: Bpf Application
kind: BpfApplication
Expand Down Expand Up @@ -1101,6 +1025,14 @@ spec:
- patch
- update
- watch
- apiGroups:
- bpfman.io
resources:
- bpfapplicationnodes
verbs:
- get
- list
- watch
- apiGroups:
- bpfman.io
resources:
Expand Down
Loading

0 comments on commit 218f890

Please sign in to comment.