Skip to content

Commit e992dca

Browse files
msherif1234andreaskaris
authored andcommitted
WIP:DNM: Bpfman operator APIs review
Signed-off-by: Mohamed Mahmoud <[email protected]>
1 parent 230d0e0 commit e992dca

21 files changed

+4834
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
Copyright 2023 The bpfman Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
metav1types "k8s.io/apimachinery/pkg/types"
22+
"sigs.k8s.io/controller-runtime/pkg/client"
23+
)
24+
25+
// +union
26+
// +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"
27+
// +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"
28+
// +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"
29+
// +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"
30+
// +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"
31+
type BpfApplicationProgramState struct {
32+
BpfProgramStateCommon `json:",inline"`
33+
34+
// type specifies the provisioned eBPF program type for this program entry.
35+
// Type will be one of:
36+
// TC, TCX, UProbe, URetProbe, XDP
37+
//
38+
// When set to TC, the tc object will be populated with the eBPF program data
39+
// associated with a TC program.
40+
//
41+
// When set to TCX, the tcx object will be populated with the eBPF program
42+
// data associated with a TCX program.
43+
//
44+
// When set to UProbe, the uprobe object will be populated with the eBPF
45+
// program data associated with a UProbe program.
46+
//
47+
// When set to URetProbe, the uretprobe object will be populated with the eBPF
48+
// program data associated with a URetProbe program.
49+
//
50+
// When set to XDP, the xdp object will be populated with the eBPF program data
51+
// associated with a URetProbe program.
52+
// +unionDiscriminator
53+
// +required
54+
// +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"UProbe";"URetProbe"
55+
Type EBPFProgType `json:"type"`
56+
57+
// xdp contains the attachment data for an XDP program when type is set to XDP.
58+
// +unionMember
59+
// +optional
60+
XDP *XdpProgramInfoState `json:"xdp,omitempty"`
61+
62+
// tc contains the attachment data for a TC program when type is set to TC.
63+
// +unionMember
64+
// +optional
65+
TC *TcProgramInfoState `json:"tc,omitempty"`
66+
67+
// tcx contains the attachment data for a TCX program when type is set to TCX.
68+
// +unionMember
69+
// +optional
70+
TCX *TcxProgramInfoState `json:"tcx,omitempty"`
71+
72+
// uprobe contains the attachment data for a UProbe program when type is set to
73+
// UProbe.
74+
// +unionMember
75+
// +optional
76+
UProbe *UprobeProgramInfoState `json:"uprobe,omitempty"`
77+
78+
// uretprobe contains the attachment data for a URetProbe program when type is
79+
// set to URetProbe.
80+
// +unionMember
81+
// +optional
82+
URetProbe *UprobeProgramInfoState `json:"uretprobe,omitempty"`
83+
}
84+
85+
type BpfApplicationStateStatus struct {
86+
// UpdateCount tracks the number of times the BpfApplicationState object has
87+
// been updated. The bpfman agent initializes it to 1 when it creates the
88+
// object, and then increments it before each subsequent update. It serves
89+
// as a lightweight sequence number to verify that the API server is serving
90+
// the most recent version of the object before beginning a new Reconcile
91+
// operation.
92+
UpdateCount int64 `json:"updateCount"`
93+
// node is the name of the Kubernets node for this BpfApplicationState.
94+
Node string `json:"node"`
95+
// appLoadStatus reflects the status of loading the eBPF application on the
96+
// given node.
97+
//
98+
// NotLoaded is a temporary state that is assigned when a
99+
// ClusterBpfApplicationState is created and the initial reconcile is being
100+
// processed.
101+
//
102+
// LoadSuccess is returned if all the programs have been loaded with no
103+
// errors.
104+
//
105+
// LoadError is returned if one or more programs encountered an error and
106+
// were not loaded.
107+
//
108+
// NotSelected is returned if this application did not select to run on this
109+
// Kubernetes node.
110+
//
111+
// UnloadSuccess is returned when all the programs were successfully
112+
// unloaded.
113+
//
114+
// UnloadError is returned if one or more programs encountered an error when
115+
// being unloaded.
116+
AppLoadStatus AppLoadStatus `json:"appLoadStatus"`
117+
// programs is a list of eBPF programs contained in the parent BpfApplication
118+
// instance. Each entry in the list contains the derived program attributes as
119+
// well as the attach status for each program on the given Kubernetes node.
120+
Programs []BpfApplicationProgramState `json:"programs,omitempty"`
121+
// conditions contains the summary state of the BpfApplication for the given
122+
// Kubernetes node. If one or more programs failed to load or attach to the
123+
// designated attachment point, the condition will report the error. If more
124+
// than one error has occurred, condition will contain the first error
125+
// encountered.
126+
// +patchMergeKey=type
127+
// +patchStrategy=merge
128+
// +listType=map
129+
// +listMapKey=type
130+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
131+
}
132+
133+
// +genclient
134+
// +kubebuilder:object:root=true
135+
// +kubebuilder:subresource:status
136+
// +kubebuilder:resource:scope=Namespaced
137+
138+
// BpfApplicationState contains the state of a BpfApplication instance for a
139+
// given Kubernetes node. When a user creates a BpfApplication instance, bpfman
140+
// creates a BpfApplicationState instance for each node in a Kubernetes
141+
// cluster.
142+
// +kubebuilder:printcolumn:name="Node",type=string,JSONPath=".status.node"
143+
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`
144+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
145+
type BpfApplicationState struct {
146+
metav1.TypeMeta `json:",inline"`
147+
metav1.ObjectMeta `json:"metadata,omitempty"`
148+
149+
// status reflects the status of a BpfApplication instance for the given node.
150+
// appLoadStatus and conditions provide an overall status for the given node,
151+
// while each item in the programs list provides a per eBPF program status for
152+
// the given node.
153+
Status BpfApplicationStateStatus `json:"status,omitempty"`
154+
}
155+
156+
// +kubebuilder:object:root=true
157+
// BpfApplicationStateList contains a list of BpfApplicationState objects
158+
type BpfApplicationStateList struct {
159+
metav1.TypeMeta `json:",inline"`
160+
metav1.ListMeta `json:"metadata,omitempty"`
161+
Items []BpfApplicationState `json:"items"`
162+
}
163+
164+
func (an BpfApplicationState) GetName() string {
165+
return an.Name
166+
}
167+
168+
func (an BpfApplicationState) GetUID() metav1types.UID {
169+
return an.UID
170+
}
171+
172+
func (an BpfApplicationState) GetAnnotations() map[string]string {
173+
return an.Annotations
174+
}
175+
176+
func (an BpfApplicationState) GetLabels() map[string]string {
177+
return an.Labels
178+
}
179+
180+
func (an BpfApplicationState) GetConditions() []metav1.Condition {
181+
return an.Status.Conditions
182+
}
183+
184+
func (an BpfApplicationState) GetClientObject() client.Object {
185+
return &an
186+
}
187+
188+
func (anl BpfApplicationStateList) GetItems() []BpfApplicationState {
189+
return anl.Items
190+
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
Copyright 2024 The bpfman Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
// BpfApplicationProgram defines the desired state of BpfApplication
24+
// +union
25+
// +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"
26+
// +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"
27+
// +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"
28+
// +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"
29+
// +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"
30+
type BpfApplicationProgram struct {
31+
// name is a required field and is the name of the function that is the entry
32+
// point for the eBPF program. name must not be an empty string, must not
33+
// exceed 64 characters in length, must start with alpha characters and must
34+
// only contain alphanumeric characters.
35+
// +required
36+
// +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+."
37+
// +kubebuilder:validation:MinLength=1
38+
// +kubebuilder:validation:MaxLength=64
39+
Name string `json:"name"`
40+
41+
// type is a required field used to specify the type of the eBPF program.
42+
//
43+
// Allowed values are:
44+
// TC, TCX, UProbe, URetProbe, XDP
45+
//
46+
// When set to TC, the eBPF program can attach to network devices (interfaces).
47+
// The program can be attached on either packet ingress or egress, so the
48+
// program will be called on every incoming or outgoing packet seen by the
49+
// network device. When using the TC program type, the tc field is required.
50+
// See tc for more details on TC programs.
51+
//
52+
// When set to TCX, the eBPF program can attach to network devices
53+
// (interfaces). The program can be attached on either packet ingress or
54+
// egress, so the program will be called on every incoming or outgoing packet
55+
// seen by the network device. When using the TCX program type, the tcx field
56+
// is required. See tcx for more details on TCX programs.
57+
//
58+
// When set to UProbe, the program can attach in user-space. The UProbe is
59+
// attached to a binary, library or function name, and optionally an offset in
60+
// the code. When using the UProbe program type, the uprobe field is required.
61+
// See uprobe for more details on UProbe programs.
62+
//
63+
// When set to URetProbe, the program can attach in user-space.
64+
// The URetProbe is attached to the return of a binary, library or function
65+
// name, and optionally an offset in the code. When using the URetProbe
66+
// program type, the uretprobe field is required. See uretprobe for more
67+
// details on URetProbe programs.
68+
//
69+
// When set to XDP, the eBPF program can attach to network devices (interfaces)
70+
// and will be called on every incoming packet received by the network device.
71+
// When using the XDP program type, the xdp field is required. See xdp for more
72+
// details on XDP programs.
73+
// +unionDiscriminator
74+
// +required
75+
// +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"UProbe";"URetProbe"
76+
Type EBPFProgType `json:"type"`
77+
78+
// xdp is an optional field, but required when the type field is set to XDP.
79+
// xdp defines the desired state of the application's XDP programs. XDP program
80+
// can be attached to network devices (interfaces) and will be called on every
81+
// incoming packet received by the network device. The XDP attachment point is
82+
// just after the packet has been received off the wire, but before the Linux
83+
// kernel has allocated an sk_buff, which is used to pass the packet through
84+
// the kernel networking stack.
85+
// +unionMember
86+
// +optional
87+
XDP *XdpProgramInfo `json:"xdp,omitempty"`
88+
89+
// tc is an optional field, but required when the type field is set to TC. tc
90+
// defines the desired state of the application's TC programs. TC programs are
91+
// attached to network devices (interfaces). The program can be attached on
92+
// either packet ingress or egress, so the program will be called on every
93+
// incoming or outgoing packet seen by the network device. The TC attachment
94+
// point is in Linux's Traffic Control (tc) subsystem, which is after the
95+
// Linux kernel has allocated an sk_buff. TCX is newer implementation of TC
96+
// with enhanced performance and better support for running multiple programs
97+
// on a given network device. This makes TC useful for packet classification
98+
// actions.
99+
// +unionMember
100+
// +optional
101+
TC *TcProgramInfo `json:"tc,omitempty"`
102+
103+
// tcx is an optional field, but required when the type field is set to TCX.
104+
// tcx defines the desired state of the application's TCX programs. TCX
105+
// programs are attached to network devices (interfaces). The program can be
106+
// attached on either packet ingress or egress, so the program will be called
107+
// on every incoming or outgoing packet seen by the network device. The TCX
108+
// attachment point is in Linux's Traffic Control (tc) subsystem, which is
109+
// after the Linux kernel has allocated an sk_buff. This makes TCX useful for
110+
// packet classification actions. TCX is a newer implementation of TC with
111+
// enhanced performance and better support for running multiple programs on a
112+
// given network device.
113+
// +unionMember
114+
// +optional
115+
TCX *TcxProgramInfo `json:"tcx,omitempty"`
116+
117+
// uprobe is an optional field, but required when the type field is set to
118+
// UProbe. uprobe defines the desired state of the application's UProbe
119+
// programs. UProbe programs are user-space probes. A target must be provided,
120+
// which is the library name or absolute path to a binary or library where the
121+
// probe is attached. Optionally, a function name can also be provided to
122+
// provide finer granularity on where the probe is attached. They can be
123+
// attached at any point in the binary, library or function using the optional
124+
// offset field. However, caution must be taken when using the offset, ensuring
125+
// the offset is still in the desired bytecode.
126+
// +unionMember
127+
// +optional
128+
UProbe *UprobeProgramInfo `json:"uprobe,omitempty"`
129+
130+
// uretprobe is an optional field, but required when the type field is set to
131+
// URetProbe. uretprobe defines the desired state of the application's
132+
// URetProbe programs. URetProbe programs are user-space probes. A target must
133+
// be provided, which is the library name or absolute path to a binary or
134+
// library where the probe is attached. Optionally, a function name can also be
135+
// provided to provide finer granularity on where the probe is attached. They
136+
// are attached to the return point of the binary, library or function, but can
137+
// be set anywhere using the optional offset field. However, caution must be
138+
// taken when using the offset, ensuring the offset is still in the desired
139+
// bytecode.
140+
// +unionMember
141+
// +optional
142+
URetProbe *UprobeProgramInfo `json:"uretprobe,omitempty"`
143+
}
144+
145+
// spec defines the desired state of the BpfApplication. The BpfApplication
146+
// describes the set of one or more namespace scoped eBPF programs that should
147+
// be loaded for a given application and attributes for how they should be
148+
// loaded. eBPF programs that are grouped together under the same
149+
// BpfApplication instance can share maps and global data between the eBPF
150+
// programs loaded on the same Kubernetes Node.
151+
type BpfApplicationSpec struct {
152+
BpfAppCommon `json:",inline"`
153+
154+
// programs is a required field and is the list of eBPF programs in a BPF
155+
// Application CRD that should be loaded in kernel memory. At least one entry
156+
// is required. eBPF programs in this list will be loaded on the system based
157+
// the nodeSelector. Even if an eBPF program is loaded in kernel memory, it
158+
// cannot be triggered until an attachment point is provided. The different
159+
// program types have different ways of attaching. The attachment points can be
160+
// added at creation time or modified (added or removed) at a later time to
161+
// activate or deactivate the eBPF program as desired.
162+
// CAUTION: When programs are added or removed from the list, that requires all
163+
// programs in the list to be reloaded, which could be temporarily service
164+
// effecting. For this reason, modifying the list is currently not allowed.
165+
// +required
166+
// +kubebuilder:validation:MinItems:=1
167+
Programs []BpfApplicationProgram `json:"programs,omitempty"`
168+
}
169+
170+
// +genclient
171+
// +kubebuilder:object:root=true
172+
// +kubebuilder:subresource:status
173+
// +kubebuilder:resource:scope=Namespaced
174+
175+
// BpfApplication is the schema for the namespace scoped BPF Applications API.
176+
// This API allows applications to use bpfman to load and attach one or more
177+
// eBPF programs on a Kubernetes cluster.
178+
//
179+
// The bpfApplication.status field reports the overall status of the
180+
// BpfApplication CRD. A given BpfApplication CRD can result in loading and
181+
// attaching multiple eBPF programs on multiple nodes, so this status is just a
182+
// summary. More granular per-node status details can be found in the
183+
// corresponding BpfApplicationState CRD that bpfman creates for each node.
184+
// +kubebuilder:printcolumn:name="NodeSelector",type=string,JSONPath=`.spec.nodeselector`
185+
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`
186+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
187+
type BpfApplication struct {
188+
metav1.TypeMeta `json:",inline"`
189+
metav1.ObjectMeta `json:"metadata,omitempty"`
190+
191+
Spec BpfApplicationSpec `json:"spec,omitempty"`
192+
Status BpfAppStatus `json:"status,omitempty"`
193+
}
194+
195+
// +kubebuilder:object:root=true
196+
// BpfApplicationList contains a list of BpfApplications
197+
type BpfApplicationList struct {
198+
metav1.TypeMeta `json:",inline"`
199+
metav1.ListMeta `json:"metadata,omitempty"`
200+
Items []BpfApplication `json:"items"`
201+
}

0 commit comments

Comments
 (0)