Skip to content

Commit

Permalink
WIP: BpfApplicationNode CRD POC
Browse files Browse the repository at this point in the history
This is currently incomplete.

Signed-off-by: Andre Fredette <[email protected]>
  • Loading branch information
anfredette committed Dec 18, 2024
1 parent 336e98c commit 5dce708
Show file tree
Hide file tree
Showing 37 changed files with 2,478 additions and 58 deletions.
130 changes: 130 additions & 0 deletions apis/v1alpha1/bpfApplicationNode_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
Copyright 2023 The bpfman 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.
*/

package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// BpfApplicationProgram defines the desired state of BpfApplication
// +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 == '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"
type BpfApplicationProgramNode struct {
// Type specifies the bpf program type
// +unionDiscriminator
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"Fentry";"Fexit";"Kprobe";"Kretprobe";"Uprobe";"Uretprobe";"Tracepoint"
Type EBPFProgType `json:"type,omitempty"`

// xdp defines the desired state of the application's XdpPrograms.
// +unionMember
// +optional
XDP *XdpProgramInfoNode `json:"xdp,omitempty"`

// tc defines the desired state of the application's TcPrograms.
// +unionMember
// +optional
TC *TcProgramInfoNode `json:"tc,omitempty"`

// // tcx defines the desired state of the application's TcxPrograms.
// // +unionMember
// // +optional
// TCX *TcxProgramInfoNode `json:"tcx,omitempty"`

// fentry defines the desired state of the application's FentryPrograms.
// +unionMember
// +optional
Fentry *FentryProgramInfoNode `json:"fentry,omitempty"`

// // fexit defines the desired state of the application's FexitPrograms.
// // +unionMember
// // +optional
// Fexit *FexitProgramInfoNode `json:"fexit,omitempty"`

// // kprobe defines the desired state of the application's KprobePrograms.
// // +unionMember
// // +optional
// Kprobe *KprobeProgramInfoNode `json:"kprobe,omitempty"`

// // kretprobe defines the desired state of the application's KretprobePrograms.
// // +unionMember
// // +optional
// Kretprobe *KprobeProgramInfoNode `json:"kretprobe,omitempty"`

// // uprobe defines the desired state of the application's UprobePrograms.
// // +unionMember
// // +optional
// Uprobe *UprobeProgramInfoNode `json:"uprobe,omitempty"`

// // uretprobe defines the desired state of the application's UretprobePrograms.
// // +unionMember
// // +optional
// Uretprobe *UprobeProgramInfoNode `json:"uretprobe,omitempty"`

// // tracepoint defines the desired state of the application's TracepointPrograms.
// // +unionMember
// // +optional
// Tracepoint *TracepointProgramInfoNode `json:"tracepoint,omitempty"`
}

// BpfApplicationSpec defines the desired state of BpfApplication
type BpfApplicationNodeSpec struct {
// Programs is a list of bpf programs contained in the parent application.
// It is a map from the bpf program name to BpfApplicationProgramNode
// elements.
Programs map[string]BpfApplicationProgramNode `json:"programs,omitempty"`
}

// BpfApplicationStatus defines the observed state of BpfApplication
type BpfApplicationNodeStatus struct {
BpfAppStatus `json:",inline"`
}

// +genclient
// +genclient:nonNamespaced
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster

// BpfApplicationNode is the Schema for the bpfapplications API
// +kubebuilder:printcolumn:name="NodeSelector",type=string,JSONPath=`.spec.nodeselector`
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
type BpfApplicationNode struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec BpfApplicationNodeSpec `json:"spec,omitempty"`
Status BpfAppStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// BpfApplicationList contains a list of BpfApplications
type BpfApplicationNodeList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []BpfApplicationNode `json:"items"`
}
19 changes: 19 additions & 0 deletions apis/v1alpha1/fentryProgram_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,22 @@ type FentryProgramList struct {
metav1.ListMeta `json:"metadata,omitempty"`
Items []FentryProgram `json:"items"`
}

type FentryProgramInfoNode struct {
AppProgramStatus `json:",inline"`
// The list of points to which the program should be attached.
// FentryAttachInfoNode is similar to FentryAttachInfo, but the interface and
// container selectors are expanded, and we have one instance of
// FentryAttachInfoNode for each unique attach point. The list is optional and
// may be udated after the bpf program has been loaded.
// +optional
AttachPoint FentryAttachInfoNode `json:"attach_points"`
}

type FentryAttachInfoNode struct {
AttachStatus `json:",inline"`
// An identifier for the attach point assigned by bpfman. This field is
// empty until the program is successfully attached and bpfman returns the
// id.
attachId *uint32 `json:"attachid"`

Check failure on line 93 in apis/v1alpha1/fentryProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

structtag: struct field attachId has json tag but is not exported (govet)
}
39 changes: 36 additions & 3 deletions apis/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,50 @@ type BpfAppCommon struct {
ByteCode BytecodeSelector `json:"bytecode"`
}

// BpfAppStatus defines the BpfProgram status
// BpfAppStatus reflects the status of a BpfApplication or BpfApplicationNode object
type BpfAppStatus struct {
// Conditions houses the global cluster state for the eBPFProgram. The explicit
// condition types are defined internally.
// For a BpfApplication object, Conditions contains the global cluster state
// for the object. For a BpfApplicationNode object, Conditions contains the
// state of the BpfApplication object on the given node.
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

// AppProgramStatus defines the status for a given bpf application program on a given node.
type AppProgramStatus struct {
// ShouldLoad reflects whether the program should be loaded.
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
ShouldLoad []metav1.Condition `json:"should_load,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
// IsLoaded reflects whether the program should be loaded.
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
IsLoaded []metav1.Condition `json:"is_loaded,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

// AttachStatus defines the status for one attach point for a given bpf application program
type AttachStatus struct {
// ShouldAttach reflects whether the attachment should exist.
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
ShouldAttach []metav1.Condition `json:"should_attach,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
// IsAttached reflects whether the attachment exists.
// +patchMergeKey=type
// +patchStrategy=merge
// +listType=map
// +listMapKey=type
IsAttached []metav1.Condition `json:"is_attached,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
}

// PullPolicy describes a policy for if/when to pull a container image
// +kubebuilder:validation:Enum=Always;Never;IfNotPresent
type PullPolicy string
Expand Down
43 changes: 43 additions & 0 deletions apis/v1alpha1/tcProgram_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,46 @@ type TcProgramList struct {
metav1.ListMeta `json:"metadata,omitempty"`
Items []TcProgram `json:"items"`
}

type TcProgramInfoNode struct {
AppProgramStatus `json:",inline"`
// The list of points to which the program should be attached.
// TcAttachInfoNode is similar to TcAttachInfo, but the interface and
// container selectors are expanded, and we have one instance of
// TcAttachInfoNode for each unique attach point. The list is optional and
// may be udated after the bpf program has been loaded.
// +optional
AttachPoints []TcAttachInfoNode `json:"attach_points"`
}

type TcAttachInfoNode struct {
AttachStatus `json:",inline"`
// An identifier for the attach point assigned by bpfman. This field is
// empty until the program is successfully attached and bpfman returns the
// id.
attachId *uint32 `json:"attachid"`

Check failure on line 119 in apis/v1alpha1/tcProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

structtag: struct field attachId has json tag but is not exported (govet)

// Interface name to attach the tc program to.
ifName string `json:"ifname"`

Check failure on line 122 in apis/v1alpha1/tcProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

field `ifName` is unused (unused)

// Optional container pid to attach the tc program in.
// +optional
containerPid *uint32 `json:"containerpid"`

Check failure on line 126 in apis/v1alpha1/tcProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

structtag: struct field containerPid has json tag but is not exported (govet)

// Priority specifies the priority of the tc program in relation to
// other programs of the same type with the same attach point. It is a value
// from 0 to 1000 where lower values have higher precedence.
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=1000
Priority int32 `json:"priority"`

// Direction specifies the direction of traffic the tc program should
// attach to for a given network device.
// +kubebuilder:validation:Enum=ingress;egress
Direction string `json:"direction"`

// ProceedOn allows the user to call other tc programs in chain on this exit code.
// Multiple values are supported by repeating the parameter.
// +kubebuilder:validation:MaxItems=11
ProceedOn []TcProceedOnValue `json:"proceedon"`
}
38 changes: 38 additions & 0 deletions apis/v1alpha1/xdpProgram_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,41 @@ type XdpProgramList struct {
metav1.ListMeta `json:"metadata,omitempty"`
Items []XdpProgram `json:"items"`
}

type XdpProgramInfoNode struct {
AppProgramStatus `json:",inline"`
// The list of points to which the program should be attached.
// XdpAttachInfoNode is similar to XdpAttachInfo, but the interface and
// container selectors are expanded, and we have one instance of
// XdpAttachInfoNode for each unique attach point. The list is optional and
// may be udated after the bpf program has been loaded.
// +optional
AttachPoints []XdpAttachInfoNode `json:"attach_points"`
}

type XdpAttachInfoNode struct {
AttachStatus `json:",inline"`
// An identifier for the attach point assigned by bpfman. This field is
// empty until the program is successfully attached and bpfman returns the
// id.
attachId *uint32 `json:"attachid"`

Check failure on line 119 in apis/v1alpha1/xdpProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

structtag: struct field attachId has json tag but is not exported (govet)

// Interface name to attach the xdp program to.
ifName string `json:"ifname"`

Check failure on line 122 in apis/v1alpha1/xdpProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

field `ifName` is unused (unused)

// Optional container pid to attach the xdp program in.
// +optional
containerPid *uint32 `json:"containerpid"`

Check failure on line 126 in apis/v1alpha1/xdpProgram_types.go

View workflow job for this annotation

GitHub Actions / Build (Go 1.22 - amd64)

structtag: struct field containerPid has json tag but is not exported (govet)

// Priority specifies the priority of the xdp program in relation to
// other programs of the same type with the same attach point. It is a value
// from 0 to 1000 where lower values have higher precedence.
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=1000
Priority int32 `json:"priority"`

// ProceedOn allows the user to call other xdp programs in chain on this exit code.
// Multiple values are supported by repeating the parameter.
// +kubebuilder:validation:MaxItems=6
ProceedOn []XdpProceedOnValue `json:"proceedon"`
}
Loading

0 comments on commit 5dce708

Please sign in to comment.