diff --git a/bpfman-operator/apis/v1alpha1/bpf_application_state_types.go b/bpfman-operator/apis/v1alpha1/bpf_application_state_types.go new file mode 100644 index 00000000000..f3142de3b42 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/bpf_application_state_types.go @@ -0,0 +1,190 @@ +/* +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" + metav1types "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// +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 == '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" +type BpfApplicationProgramState struct { + BpfProgramStateCommon `json:",inline"` + + // type specifies the provisioned eBPF program type for this program entry. + // Type will be one of: + // TC, TCX, UProbe, URetProbe, XDP + // + // When set to TC, the tc object will be populated with the eBPF program data + // associated with a TC program. + // + // When set to TCX, the tcx object will be populated with the eBPF program + // data associated with a TCX program. + // + // When set to UProbe, the uprobe object will be populated with the eBPF + // program data associated with a UProbe program. + // + // When set to URetProbe, the uretprobe object will be populated with the eBPF + // program data associated with a URetProbe program. + // + // When set to XDP, the xdp object will be populated with the eBPF program data + // associated with a URetProbe program. + // +unionDiscriminator + // +required + // +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"UProbe";"URetProbe" + Type EBPFProgType `json:"type"` + + // xdp contains the attachment data for an XDP program when type is set to XDP. + // +unionMember + // +optional + XDP *XdpProgramInfoState `json:"xdp,omitempty"` + + // tc contains the attachment data for a TC program when type is set to TC. + // +unionMember + // +optional + TC *TcProgramInfoState `json:"tc,omitempty"` + + // tcx contains the attachment data for a TCX program when type is set to TCX. + // +unionMember + // +optional + TCX *TcxProgramInfoState `json:"tcx,omitempty"` + + // uprobe contains the attachment data for a UProbe program when type is set to + // UProbe. + // +unionMember + // +optional + UProbe *UprobeProgramInfoState `json:"uprobe,omitempty"` + + // uretprobe contains the attachment data for a URetProbe program when type is + // set to URetProbe. + // +unionMember + // +optional + URetProbe *UprobeProgramInfoState `json:"uretprobe,omitempty"` +} + +type BpfApplicationStateStatus struct { + // UpdateCount tracks the number of times the BpfApplicationState object has + // been updated. The bpfman agent initializes it to 1 when it creates the + // object, and then increments it before each subsequent update. It serves + // as a lightweight sequence number to verify that the API server is serving + // the most recent version of the object before beginning a new Reconcile + // operation. + UpdateCount int64 `json:"updateCount"` + // node is the name of the Kubernets node for this BpfApplicationState. + Node string `json:"node"` + // appLoadStatus reflects the status of loading the eBPF application on the + // given node. + // + // NotLoaded is a temporary state that is assigned when a + // ClusterBpfApplicationState is created and the initial reconcile is being + // processed. + // + // LoadSuccess is returned if all the programs have been loaded with no + // errors. + // + // LoadError is returned if one or more programs encountered an error and + // were not loaded. + // + // NotSelected is returned if this application did not select to run on this + // Kubernetes node. + // + // UnloadSuccess is returned when all the programs were successfully + // unloaded. + // + // UnloadError is returned if one or more programs encountered an error when + // being unloaded. + AppLoadStatus AppLoadStatus `json:"appLoadStatus"` + // programs is a list of eBPF programs contained in the parent BpfApplication + // instance. Each entry in the list contains the derived program attributes as + // well as the attach status for each program on the given Kubernetes node. + Programs []BpfApplicationProgramState `json:"programs,omitempty"` + // conditions contains the summary state of the BpfApplication for the given + // Kubernetes node. If one or more programs failed to load or attach to the + // designated attachment point, the condition will report the error. If more + // than one error has occurred, condition will contain the first error + // encountered. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Namespaced + +// BpfApplicationState contains the state of a BpfApplication instance for a +// given Kubernetes node. When a user creates a BpfApplication instance, bpfman +// creates a BpfApplicationState instance for each node in a Kubernetes +// cluster. +// +kubebuilder:printcolumn:name="Node",type=string,JSONPath=".status.node" +// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason` +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +type BpfApplicationState struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // status reflects the status of a BpfApplication instance for the given node. + // appLoadStatus and conditions provide an overall status for the given node, + // while each item in the programs list provides a per eBPF program status for + // the given node. + Status BpfApplicationStateStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// BpfApplicationStateList contains a list of BpfApplicationState objects +type BpfApplicationStateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []BpfApplicationState `json:"items"` +} + +func (an BpfApplicationState) GetName() string { + return an.Name +} + +func (an BpfApplicationState) GetUID() metav1types.UID { + return an.UID +} + +func (an BpfApplicationState) GetAnnotations() map[string]string { + return an.Annotations +} + +func (an BpfApplicationState) GetLabels() map[string]string { + return an.Labels +} + +func (an BpfApplicationState) GetConditions() []metav1.Condition { + return an.Status.Conditions +} + +func (an BpfApplicationState) GetClientObject() client.Object { + return &an +} + +func (anl BpfApplicationStateList) GetItems() []BpfApplicationState { + return anl.Items +} diff --git a/bpfman-operator/apis/v1alpha1/bpf_application_types.go b/bpfman-operator/apis/v1alpha1/bpf_application_types.go new file mode 100644 index 00000000000..29b2d8ac653 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/bpf_application_types.go @@ -0,0 +1,201 @@ +/* +Copyright 2024 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 == '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" +type BpfApplicationProgram struct { + // name is a required field and is the name of the function that is the entry + // point for the eBPF program. name must not be an empty string, must not + // exceed 64 characters in length, must start with alpha characters and must + // only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Name string `json:"name"` + + // type is a required field used to specify the type of the eBPF program. + // + // Allowed values are: + // TC, TCX, UProbe, URetProbe, XDP + // + // When set to TC, the eBPF program can attach to network devices (interfaces). + // The program can be attached on either packet ingress or egress, so the + // program will be called on every incoming or outgoing packet seen by the + // network device. When using the TC program type, the tc field is required. + // See tc for more details on TC programs. + // + // When set to TCX, the eBPF program can attach to network devices + // (interfaces). The program can be attached on either packet ingress or + // egress, so the program will be called on every incoming or outgoing packet + // seen by the network device. When using the TCX program type, the tcx field + // is required. See tcx for more details on TCX programs. + // + // When set to UProbe, the program can attach in user-space. The UProbe is + // attached to a binary, library or function name, and optionally an offset in + // the code. When using the UProbe program type, the uprobe field is required. + // See uprobe for more details on UProbe programs. + // + // When set to URetProbe, the program can attach in user-space. + // The URetProbe is attached to the return of a binary, library or function + // name, and optionally an offset in the code. When using the URetProbe + // program type, the uretprobe field is required. See uretprobe for more + // details on URetProbe programs. + // + // When set to XDP, the eBPF program can attach to network devices (interfaces) + // and will be called on every incoming packet received by the network device. + // When using the XDP program type, the xdp field is required. See xdp for more + // details on XDP programs. + // +unionDiscriminator + // +required + // +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"UProbe";"URetProbe" + Type EBPFProgType `json:"type"` + + // xdp is an optional field, but required when the type field is set to XDP. + // xdp defines the desired state of the application's XDP programs. XDP program + // can be attached to network devices (interfaces) and will be called on every + // incoming packet received by the network device. The XDP attachment point is + // just after the packet has been received off the wire, but before the Linux + // kernel has allocated an sk_buff, which is used to pass the packet through + // the kernel networking stack. + // +unionMember + // +optional + XDP *XdpProgramInfo `json:"xdp,omitempty"` + + // tc is an optional field, but required when the type field is set to TC. tc + // defines the desired state of the application's TC programs. TC programs are + // attached to network devices (interfaces). The program can be attached on + // either packet ingress or egress, so the program will be called on every + // incoming or outgoing packet seen by the network device. The TC attachment + // point is in Linux's Traffic Control (tc) subsystem, which is after the + // Linux kernel has allocated an sk_buff. TCX is newer implementation of TC + // with enhanced performance and better support for running multiple programs + // on a given network device. This makes TC useful for packet classification + // actions. + // +unionMember + // +optional + TC *TcProgramInfo `json:"tc,omitempty"` + + // tcx is an optional field, but required when the type field is set to TCX. + // tcx defines the desired state of the application's TCX programs. TCX + // programs are attached to network devices (interfaces). The program can be + // attached on either packet ingress or egress, so the program will be called + // on every incoming or outgoing packet seen by the network device. The TCX + // attachment point is in Linux's Traffic Control (tc) subsystem, which is + // after the Linux kernel has allocated an sk_buff. This makes TCX useful for + // packet classification actions. TCX is a newer implementation of TC with + // enhanced performance and better support for running multiple programs on a + // given network device. + // +unionMember + // +optional + TCX *TcxProgramInfo `json:"tcx,omitempty"` + + // uprobe is an optional field, but required when the type field is set to + // UProbe. uprobe defines the desired state of the application's UProbe + // programs. UProbe programs are user-space probes. A target must be provided, + // which is the library name or absolute path to a binary or library where the + // probe is attached. Optionally, a function name can also be provided to + // provide finer granularity on where the probe is attached. They can be + // attached at any point in the binary, library or function using the optional + // offset field. However, caution must be taken when using the offset, ensuring + // the offset is still in the desired bytecode. + // +unionMember + // +optional + UProbe *UprobeProgramInfo `json:"uprobe,omitempty"` + + // uretprobe is an optional field, but required when the type field is set to + // URetProbe. uretprobe defines the desired state of the application's + // URetProbe programs. URetProbe programs are user-space probes. A target must + // be provided, which is the library name or absolute path to a binary or + // library where the probe is attached. Optionally, a function name can also be + // provided to provide finer granularity on where the probe is attached. They + // are attached to the return point of the binary, library or function, but can + // be set anywhere using the optional offset field. However, caution must be + // taken when using the offset, ensuring the offset is still in the desired + // bytecode. + // +unionMember + // +optional + URetProbe *UprobeProgramInfo `json:"uretprobe,omitempty"` +} + +// spec defines the desired state of the BpfApplication. The BpfApplication +// describes the set of one or more namespace scoped eBPF programs that should +// be loaded for a given application and attributes for how they should be +// loaded. eBPF programs that are grouped together under the same +// BpfApplication instance can share maps and global data between the eBPF +// programs loaded on the same Kubernetes Node. +type BpfApplicationSpec struct { + BpfAppCommon `json:",inline"` + + // programs is a required field and is the list of eBPF programs in a BPF + // Application CRD that should be loaded in kernel memory. At least one entry + // is required. eBPF programs in this list will be loaded on the system based + // the nodeSelector. Even if an eBPF program is loaded in kernel memory, it + // cannot be triggered until an attachment point is provided. The different + // program types have different ways of attaching. The attachment points can be + // added at creation time or modified (added or removed) at a later time to + // activate or deactivate the eBPF program as desired. + // CAUTION: When programs are added or removed from the list, that requires all + // programs in the list to be reloaded, which could be temporarily service + // effecting. For this reason, modifying the list is currently not allowed. + // +required + // +kubebuilder:validation:MinItems:=1 + Programs []BpfApplicationProgram `json:"programs,omitempty"` +} + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Namespaced + +// BpfApplication is the schema for the namespace scoped BPF Applications API. +// This API allows applications to use bpfman to load and attach one or more +// eBPF programs on a Kubernetes cluster. +// +// The bpfApplication.status field reports the overall status of the +// BpfApplication CRD. A given BpfApplication CRD can result in loading and +// attaching multiple eBPF programs on multiple nodes, so this status is just a +// summary. More granular per-node status details can be found in the +// corresponding BpfApplicationState CRD that bpfman creates for each node. +// +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 BpfApplication struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec BpfApplicationSpec `json:"spec,omitempty"` + Status BpfAppStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// BpfApplicationList contains a list of BpfApplications +type BpfApplicationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []BpfApplication `json:"items"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_bpf_application_state_types.go b/bpfman-operator/apis/v1alpha1/cluster_bpf_application_state_types.go new file mode 100644 index 00000000000..1d55fba90e1 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_bpf_application_state_types.go @@ -0,0 +1,241 @@ +/* +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" + metav1types "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// +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 ClBpfApplicationProgramState struct { + BpfProgramStateCommon `json:",inline"` + + // type specifies the provisioned eBPF program type for this program entry. + // Type will be one of: + // FEntry, FExit, KProbe, KRetProbe, TC, TCX, Tracepoint, UProbe, + // URetProbe, XDP + // + // When set to FEntry, the fentry object will be populated with the eBPF + // program data associated with an FEntry program. + // + // When set to FExit, the fexit object will be populated with the eBPF program + // data associated with an FExit program. + // + // When set to KProbe, the kprobe object will be populated with the eBPF + // program data associated with a KProbe program. + // + // When set to KRetProbe, the kretprobe object will be populated with the + // eBPF program data associated with a KRetProbe program. + // + // When set to TC, the tc object will be populated with the eBPF program data + // associated with a TC program. + // + // When set to TCX, the tcx object will be populated with the eBPF program + // data associated with a TCX program. + // + // When set to Tracepoint, the tracepoint object will be populated with the + // eBPF program data associated with a Tracepoint program. + // + // When set to UProbe, the uprobe object will be populated with the eBPF + // program data associated with a UProbe program. + // + // When set to URetProbe, the uretprobe object will be populated with the eBPF + // program data associated with a URetProbe program. + // + // When set to XDP, the xdp object will be populated with the eBPF program data + // associated with a URetProbe program. + // +unionDiscriminator + // +required + // +kubebuilder:validation:Enum:="FEntry";"FExit";"KProbe";"KRetProbe";"TC";"TCX";"TracePoint";"UProbe";"URetProbe";"XDP" + Type EBPFProgType `json:"type"` + + // xdp contains the attachment data for an XDP program when type is set to XDP. + // +unionMember + // +optional + XDP *ClXdpProgramInfoState `json:"xdp,omitempty"` + + // tc contains the attachment data for a TC program when type is set to TC. + // +unionMember + // +optional + TC *ClTcProgramInfoState `json:"tc,omitempty"` + + // tcx contains the attachment data for a TCX program when type is set to TCX. + // +unionMember + // +optional + TCX *ClTcxProgramInfoState `json:"tcx,omitempty"` + + // fentry contains the attachment data for an FEntry program when type is set + // to FEntry. + // +unionMember + // +optional + FEntry *ClFentryProgramInfoState `json:"fentry,omitempty"` + + // fexit contains the attachment data for an FExit program when type is set to + // FExit. + // +unionMember + // +optional + FExit *ClFexitProgramInfoState `json:"fexit,omitempty"` + + // kprobe contains the attachment data for a KProbe program when type is set to + // KProbe. + // +unionMember + // +optional + KProbe *ClKprobeProgramInfoState `json:"kprobe,omitempty"` + + // kretprobe contains the attachment data for a KRetProbe program when type is + // set to KRetProbe. + // +unionMember + // +optional + KRetProbe *ClKretprobeProgramInfoState `json:"kretprobe,omitempty"` + + // uprobe contains the attachment data for a UProbe program when type is set to + // UProbe. + // +unionMember + // +optional + UProbe *ClUprobeProgramInfoState `json:"uprobe,omitempty"` + + // uretprobe contains the attachment data for a URetProbe program when type is + // set to URetProbe. + // +unionMember + // +optional + URetProbe *ClUprobeProgramInfoState `json:"uretprobe,omitempty"` + + // tracepoint contains the attachment data for a Tracepoint program when type + // is set to Tracepoint. + // +unionMember + // +optional + TracePoint *ClTracepointProgramInfoState `json:"tracepoint,omitempty"` +} + +type ClBpfApplicationStateStatus struct { + // UpdateCount tracks the number of times the BpfApplicationState object has + // been updated. The bpfman agent initializes it to 1 when it creates the + // object, and then increments it before each subsequent update. It serves + // as a lightweight sequence number to verify that the API server is serving + // the most recent version of the object before beginning a new Reconcile + // operation. + UpdateCount int64 `json:"updateCount"` + // node is the name of the Kubernetes node for this ClusterBpfApplicationState. + Node string `json:"node"` + // appLoadStatus reflects the status of loading the eBPF application on the + // given node. + // + // NotLoaded is a temporary state that is assigned when a + // ClusterBpfApplicationState is created and the initial reconcile is being + // processed. + // + // LoadSuccess is returned if all the programs have been loaded with no errors. + // + // LoadError is returned if one or more programs encountered an error and were + // not loaded. + // + // NotSelected is returned if this application did not select to run on this + // Kubernetes node. + // + // UnloadSuccess is returned when all the programs were successfully unloaded. + // + // UnloadError is returned if one or more programs encountered an error when + // being unloaded. + AppLoadStatus AppLoadStatus `json:"appLoadStatus"` + // programs is a list of eBPF programs contained in the parent + // ClusterBpfApplication instance. Each entry in the list contains the derived + // program attributes as well as the attach status for each program on the + // given Kubernetes node. + Programs []ClBpfApplicationProgramState `json:"programs,omitempty"` + // conditions contains the summary state of the ClusterBpfApplication for the + // given Kubernetes node. If one or more programs failed to load or attach to + // the designated attachment point, the condition will report the error. If + // more than one error has occurred, condition will contain the first error + // encountered. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster + +// ClusterBpfApplicationState contains the state of a ClusterBpfApplication +// instance for a given Kubernetes node. When a user creates a +// ClusterBpfApplication instance, bpfman creates a ClusterBpfApplicationState +// instance for each node in a Kubernetes cluster. +// +kubebuilder:printcolumn:name="Node",type=string,JSONPath=".status.node" +// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason` +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +type ClusterBpfApplicationState struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // status reflects the status of a ClusterBpfApplication instance for the given + // node. appLoadStatus and conditions provide an overall status for the given + // node, while each item in the programs list provides a per eBPF program + // status for the given node. + Status ClBpfApplicationStateStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// ClusterBpfApplicationStateList contains a list of BpfApplicationState objects +type ClusterBpfApplicationStateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterBpfApplicationState `json:"items"` +} + +func (an ClusterBpfApplicationState) GetName() string { + return an.Name +} + +func (an ClusterBpfApplicationState) GetUID() metav1types.UID { + return an.UID +} + +func (an ClusterBpfApplicationState) GetAnnotations() map[string]string { + return an.Annotations +} + +func (an ClusterBpfApplicationState) GetLabels() map[string]string { + return an.Labels +} + +func (an ClusterBpfApplicationState) GetConditions() []metav1.Condition { + return an.Status.Conditions +} + +func (an ClusterBpfApplicationState) GetClientObject() client.Object { + return &an +} + +func (anl ClusterBpfApplicationStateList) GetItems() []ClusterBpfApplicationState { + return anl.Items +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_bpf_application_types.go b/bpfman-operator/apis/v1alpha1/cluster_bpf_application_types.go new file mode 100644 index 00000000000..97b91eb40d3 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_bpf_application_types.go @@ -0,0 +1,332 @@ +/* +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" +) + +// EBPFProgType defines the supported eBPF program types +type EBPFProgType string + +const ( + // ProgTypeXDP refers to the XDP program type. + ProgTypeXDP EBPFProgType = "XDP" + + // ProgTypeTC refers to the TC program type. + ProgTypeTC EBPFProgType = "TC" + + // ProgTypeTCX refers to the TCX program type. + ProgTypeTCX EBPFProgType = "TCX" + + // ProgTypeFentry refers to the Fentry program type. + ProgTypeFentry EBPFProgType = "FEntry" + + // ProgTypeFexit refers to the Fexit program type. + ProgTypeFexit EBPFProgType = "FExit" + + // ProgTypeKprobe refers to the Kprobe program type. + ProgTypeKprobe EBPFProgType = "KProbe" + + // ProgTypeKretprobe refers to the Kretprobe program type. + ProgTypeKretprobe EBPFProgType = "KRetProbe" + + // ProgTypeUprobe refers to the Uprobe program type. + ProgTypeUprobe EBPFProgType = "UProbe" + + // ProgTypeUretprobe refers to the Uretprobe program type. + ProgTypeUretprobe EBPFProgType = "URetProbe" + + // ProgTypeTracepoint refers to the Tracepoint program type. + ProgTypeTracepoint EBPFProgType = "TracePoint" +) + +type TCDirectionType string + +const ( + TCIngress TCDirectionType = "Ingress" + TCEgress TCDirectionType = "Egress" +) + +// +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 ClBpfApplicationProgram struct { + // name is a required field and is the name of the function that is the entry + // point for the eBPF program. name must not be an empty string, must not + // exceed 64 characters in length, must start with alpha characters and must + // only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Name string `json:"name"` + + // type is a required field used to specify the type of the eBPF program. + // + // Allowed values are: + // FEntry, FExit, KProbe, KRetProbe, TC, TCX, TracePoint, UProbe, URetProbe, + // XDP + // + // When set to FEntry, the program is attached to the entry of a Linux kernel + // function or to another eBPF program function. When using the FEntry program + // type, the fentry field is required. See fentry for more details on FEntry + // programs. + // + // When set to FExit, the program is attached to the exit of a Linux kernel + // function or to another eBPF program function. When using the FExit program + // type, the fexit field is required. See fexit for more details on FExit + // programs. + // + // When set to KProbe, the program is attached to entry of a Linux kernel + // function. When using the KProbe program type, the kprobe field is required. + // See kprobe for more details on KProbe programs. + // + // When set to KRetProbe, the program is attached to exit of a Linux kernel + // function. When using the KRetProbe program type, the kretprobe field is + // required. See kretprobe for more details on KRetProbe programs. + // + // When set to TC, the eBPF program can attach to network devices (interfaces). + // The program can be attached on either packet ingress or egress, so the + // program will be called on every incoming or outgoing packet seen by the + // network device. When using the TC program type, the tc field is required. + // See tc for more details on TC programs. + // + // When set to TCX, the eBPF program can attach to network devices + // (interfaces). The program can be attached on either packet ingress or + // egress, so the program will be called on every incoming or outgoing packet + // seen by the network device. When using the TCX program type, the tcx field + // is required. See tcx for more details on TCX programs. + // + // When set to Tracepoint, the program can attach to one of the predefined set + // of Linux kernel functions. When using the Tracepoint program type, the + // tracepoint field is required. See tracepoint for more details on Tracepoint + // programs. + // + // When set to UProbe, the program can attach in user-space. The UProbe is + // attached to a binary, library or function name, and optionally an offset in + // the code. When using the UProbe program type, the uprobe field is required. + // See uprobe for more details on UProbe programs. + // + // When set to URetProbe, the program can attach in user-space. + // The URetProbe is attached to the return of a binary, library or function + // name, and optionally an offset in the code. When using the URetProbe + // program type, the uretprobe field is required. See uretprobe for more + // details on URetProbe programs. + // + // When set to XDP, the eBPF program can attach to network devices (interfaces) + // and will be called on every incoming packet received by the network device. + // When using the XDP program type, the xdp field is required. See xdp for more + // details on XDP programs. + // +unionDiscriminator + // +required + // +kubebuilder:validation:Enum:="XDP";"TC";"TCX";"FEntry";"FExit";"KProbe";"KRetProbe";"UProbe";"URetProbe";"TracePoint" + Type EBPFProgType `json:"type"` + + // xdp is an optional field, but required when the type field is set to XDP. + // xdp defines the desired state of the application's XDP programs. XDP program + // can be attached to network devices (interfaces) and will be called on every + // incoming packet received by the network device. The XDP attachment point is + // just after the packet has been received off the wire, but before the Linux + // kernel has allocated an sk_buff, which is used to pass the packet through + // the kernel networking stack. + // +unionMember + // +optional + XDP *ClXdpProgramInfo `json:"xdp,omitempty"` + + // tc is an optional field, but required when the type field is set to TC. tc + // defines the desired state of the application's TC programs. TC programs are + // attached to network devices (interfaces). The program can be attached on + // either packet ingress or egress, so the program will be called on every + // incoming or outgoing packet seen by the network device. The TC attachment + // point is in Linux's Traffic Control (tc) subsystem, which is after the + // Linux kernel has allocated an sk_buff. TCX is newer implementation of TC + // with enhanced performance and better support for running multiple programs + // on a given network device. This makes TC useful for packet classification + // actions. + // +unionMember + // +optional + TC *ClTcProgramInfo `json:"tc,omitempty"` + + // tcx is an optional field, but required when the type field is set to TCX. + // tcx defines the desired state of the application's TCX programs. TCX + // programs are attached to network devices (interfaces). The program can be + // attached on either packet ingress or egress, so the program will be called + // on every incoming or outgoing packet seen by the network device. The TCX + // attachment point is in Linux's Traffic Control (tc) subsystem, which is + // after the Linux kernel has allocated an sk_buff. This makes TCX useful for + // packet classification actions. TCX is a newer implementation of TC with + // enhanced performance and better support for running multiple programs on a + // given network device. + // +unionMember + // +optional + TCX *ClTcxProgramInfo `json:"tcx,omitempty"` + + // fentry is an optional field, but required when the type field is set to + // FEntry. fentry defines the desired state of the application's FEntry + // programs. FEntry programs are attached to the entry of a Linux kernel + // function or to another eBPF program function. They are attached to the first + // instruction, before control passes to the function. FEntry programs are + // similar to KProbe programs, but have higher performance. + // +unionMember + // +optional + FEntry *ClFentryProgramInfo `json:"fentry,omitempty"` + + // fexit is an optional field, but required when the type field is set to + // FExit. fexit defines the desired state of the application's FExit programs. + // FExit programs are attached to the exit of a Linux kernel function or to + // another eBPF program function. The program is invoked when the function + // returns, independent of where in the function that occurs. FExit programs + // are similar to KRetProbe programs, but get invoked with the input arguments + // and the return values. They also have higher performance over KRetProbe + // programs. + // +unionMember + // +optional + FExit *ClFexitProgramInfo `json:"fexit,omitempty"` + + // kprobe is an optional field, but required when the type field is set to + // KProbe. kprobe defines the desired state of the application's Kprobe + // programs. KProbe programs are attached to a Linux kernel function. Unlike + // FEntry programs, which must always be attached at the entry point of a Linux + // kernel function, KProbe programs can be attached at any point in the + // function using the optional offset field. However, caution must be taken + // when using the offset, ensuring the offset is still in the function + // bytecode. FEntry programs have less overhead than KProbe programs. + // +unionMember + // +optional + KProbe *ClKprobeProgramInfo `json:"kprobe,omitempty"` + + // kretprobe is an optional field, but required when the type field is set to + // KRetProbe. kretprobe defines the desired state of the application's + // KRetProbe programs. KRetProbe programs are attached to the exit of a Linux + // kernel function. FExit programs have less overhead than KRetProbe programs + // and FExit programs have access to both the input arguments as well as the + // return values. KRetProbes only have access to the return values. + // +unionMember + // +optional + KRetProbe *ClKretprobeProgramInfo `json:"kretprobe,omitempty"` + + // uprobe is an optional field, but required when the type field is set to + // UProbe. uprobe defines the desired state of the application's UProbe + // programs. UProbe programs are user-space probes. A target must be provided, + // which is the library name or absolute path to a binary or library where the + // probe is attached. Optionally, a function name can also be provided to + // provide finer granularity on where the probe is attached. They can be + // attached at any point in the binary, library or function using the optional + // offset field. However, caution must be taken when using the offset, ensuring + // the offset is still in the desired bytecode. + // +unionMember + // +optional + UProbe *ClUprobeProgramInfo `json:"uprobe,omitempty"` + + // uretprobe is an optional field, but required when the type field is set to + // URetProbe. uretprobe defines the desired state of the application's + // URetProbe programs. URetProbe programs are user-space probes. A target must + // be provided, which is the library name or absolute path to a binary or + // library where the probe is attached. Optionally, a function name can also be + // provided to provide finer granularity on where the probe is attached. They + // are attached to the return point of the binary, library or function, but can + // be set anywhere using the optional offset field. However, caution must be + // taken when using the offset, ensuring the offset is still in the desired + // bytecode. + // +unionMember + // +optional + URetProbe *ClUprobeProgramInfo `json:"uretprobe,omitempty"` + + // tracepoint is an optional field, but required when the type field is set to + // Tracepoint. tracepoint defines the desired state of the application's + // Tracepoint programs. Whereas KProbes attach to dynamically to any Linux + // kernel function, Tracepoint programs are programs that can only be attached + // at predefined locations in the Linux kernel. Use the following command to + // see the available attachment points: + // `sudo find /sys/kernel/debug/tracing/events -type d` + // While KProbes are more flexible in where in the kernel the probe can be + // attached, the functions and data structure rely on the kernel your system is + // running. Tracepoints tend to be more stable across kernel versions and are + // better for portability. + // +unionMember + // +optional + TracePoint *ClTracepointProgramInfo `json:"tracepoint,omitempty"` +} + +// spec defines the desired state of the ClusterBpfApplication. The +// ClusterBpfApplication describes the set of one or more cluster scoped eBPF +// programs that should be loaded for a given application and attributes for +// how they should be loaded. eBPF programs that are grouped together under the +// same ClusterBpfApplication instance can share maps and global data between +// the eBPF programs loaded on the same Kubernetes Node. +type ClBpfApplicationSpec struct { + BpfAppCommon `json:",inline"` + + // programs is a required field and is the list of eBPF programs in a BPF + // Application CRD that should be loaded in kernel memory. At least one entry + // is required. eBPF programs in this list will be loaded on the system based + // the nodeSelector. Even if an eBPF program is loaded in kernel memory, it + // cannot be triggered until an attachment point is provided. The different + // program types have different ways of attaching. The attachment points can be + // added at creation time or modified (added or removed) at a later time to + // activate or deactivate the eBPF program as desired. + // CAUTION: When programs are added or removed from the list, that requires all + // programs in the list to be reloaded, which could be temporarily service + // effecting. For this reason, modifying the list is currently not allowed. + // +required + // +kubebuilder:validation:MinItems:=1 + Programs []ClBpfApplicationProgram `json:"programs"` +} + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster + +// ClusterBpfApplication is the schema for the cluster scoped BPF Applications +// API. This API allows applications to use bpfman to load and attach one or +// more eBPF programs on a Kubernetes cluster. +// +// The clusterBpfApplication.status field reports the overall status of the +// ClusterBpfApplication CRD. A given ClusterBpfApplication CRD can result in +// loading and attaching multiple eBPF programs on multiple nodes, so this +// status is just a summary. More granular per-node status details can be +// found in the corresponding ClusterBpfApplicationState CRD that bpfman +// creates for each node. +// +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 ClusterBpfApplication struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClBpfApplicationSpec `json:"spec,omitempty"` + Status BpfAppStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// ClusterBpfApplicationList contains a list of BpfApplications +type ClusterBpfApplicationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterBpfApplication `json:"items"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_fentry_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_fentry_program_types.go new file mode 100644 index 00000000000..ceab34dbf1c --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_fentry_program_types.go @@ -0,0 +1,77 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type ClFentryProgramInfo struct { + ClFentryLoadInfo `json:",inline"` + + // links is an optional field and is a flag to indicate if the FEntry program + // should be attached. The attachment point for a FEntry program is a Linux + // kernel function. Unlike other eBPF program types, an FEntry program must be + // provided with the target function at load time. The links field is optional, + // but unlike other program types where it represents a list of attachment + // points, for FEntry programs it contains at most one entry that determines + // whether the program should be attached to the specified function. To attach + // the program, add an entry to links with mode set to Attach. To detach it, + // remove the entry from links. + // +optional + // +kubebuilder:validation:MaxItems=1 + Links []ClFentryAttachInfo `json:"links,omitempty"` +} + +type ClFentryLoadInfo struct { + // function is a required field and specifies the name of the Linux kernel + // function to attach the FEntry program. function must not be an empty string, + // must not exceed 64 characters in length, must start with alpha characters + // and must only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Function string `json:"function"` +} + +type AttachTypeAttach string + +const ( + Attach AttachTypeAttach = "Attach" +) + +type ClFentryAttachInfo struct { + // mode is a required field. When set to Attach, the FEntry program will + // attempt to be attached. To detach the FEntry program, remove the link entry. + // +required + // +kubebuilder:validation:Enum=Attach; + Mode AttachTypeAttach `json:"mode"` +} + +type ClFentryProgramInfoState struct { + ClFentryLoadInfo `json:",inline"` + + // links is a list of attachment points for the FEntry program. Each entry in + // the list includes a linkStatus, which indicates if the attachment was + // successful or not on this node, a linkId, which is the kernel ID for the + // link if successfully attached, and other attachment specific data. + // +optional + // +kubebuilder:validation:MaxItems=1 + Links []ClFentryAttachInfoState `json:"links,omitempty"` +} + +type ClFentryAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_fexit_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_fexit_program_types.go new file mode 100644 index 00000000000..a37110bc783 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_fexit_program_types.go @@ -0,0 +1,71 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type ClFexitProgramInfo struct { + ClFexitLoadInfo `json:",inline"` + + // links is an optional field and is a flag to indicate if the FExit program + // should be attached. The attachment point for a FExit program is a Linux + // kernel function. Unlike other eBPF program types, an FExit program must be + // provided with the target function at load time. The links field is optional, + // but unlike other program types where it represents a list of attachment + // points, for FExit programs it contains at most one entry that determines + // whether the program should be attached to the specified function. To attach + // the program, add an entry to links with mode set to Attach. To detach it, + // remove the entry from links. + // +optional + // +kubebuilder:validation:MaxItems=1 + Links []ClFexitAttachInfo `json:"links,omitempty"` +} + +type ClFexitLoadInfo struct { + // function is a required field and specifies the name of the Linux kernel + // function to attach the FExit program. function must not be an empty string, + // must not exceed 64 characters in length, must start with alpha characters + // and must only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Function string `json:"function"` +} + +type ClFexitAttachInfo struct { + // mode is a required field. When set to Attach, the FExit program will + // attempt to be attached. To detach the FExit program, remove the link entry. + // +required + // +kubebuilder:validation:Enum=Attach; + Mode AttachTypeAttach `json:"mode"` +} + +type ClFexitProgramInfoState struct { + ClFexitLoadInfo `json:",inline"` + + // links is a list of attachment points for the FExit program. Each entry in + // the list includes a linkStatus, which indicates if the attachment was + // successful or not, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + // +kubebuilder:validation:MaxItems=1 + Links []ClFexitAttachInfoState `json:"links,omitempty"` +} + +type ClFexitAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_kprobe_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_kprobe_program_types.go new file mode 100644 index 00000000000..cff43a95c36 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_kprobe_program_types.go @@ -0,0 +1,77 @@ +/* +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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +// ClKprobeProgramInfo contains the information for the kprobe program +type ClKprobeProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // KProbe program should be attached. The eBPF program is loaded in kernel + // memory when the BPF Application CRD is created and the selected Kubernetes + // nodes are active. The eBPF program will not be triggered until the program + // has also been attached to an attachment point described in this list. Items + // may be added or removed from the list at any point, causing the eBPF program + // to be attached or detached. + // + // The attachment point for a KProbe program is a Linux kernel function. By + // default, the eBPF program is triggered at the entry of the attachment point, + // but the attachment point can be adjusted using an optional offset. + // +optional + Links []ClKprobeAttachInfo `json:"links,omitempty"` +} + +type ClKprobeAttachInfo struct { + // function is a required field and specifies the name of the Linux kernel + // function to attach the KProbe program. function must not be an empty string, + // must not exceed 64 characters in length, must start with alpha characters + // and must only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Function string `json:"function"` + + // offset is an optional field and the value is added to the address of the + // attachment point function. If not provided, offset defaults to 0. + // +optional + // +kubebuilder:default:=0 + Offset uint64 `json:"offset"` +} + +type ClKprobeProgramInfoState struct { + // links is a list of attachment points for the KProbe program. Each entry in + // the list includes a linkStatus, which indicates if the attachment was + // successful or not on this node, a linkId, which is the kernel ID for the + // link if successfully attached, and other attachment specific data. + // +optional + Links []ClKprobeAttachInfoState `json:"links,omitempty"` +} + +type ClKprobeAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // function is the provisioned name of the Linux kernel function the KProbe + // program should be attached. + // +required + Function string `json:"function"` + + // offset is the provisioned offset, whose value is added to the address of the + // attachment point function. + // +optional + // +kubebuilder:default:=0 + Offset uint64 `json:"offset"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_kretprobe_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_kretprobe_program_types.go new file mode 100644 index 00000000000..606b3c1a68d --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_kretprobe_program_types.go @@ -0,0 +1,62 @@ +/* +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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +// ClKprobeProgramInfo contains the information for the kprobe program +type ClKretprobeProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // KRetProbe program should be attached. The eBPF program is loaded in kernel + // memory when the BPF Application CRD is created and the selected Kubernetes + // nodes are active. The eBPF program will not be triggered until the program + // has also been attached to an attachment point described in this list. Items + // may be added or removed from the list at any point, causing the eBPF program + // to be attached or detached. + // + // The attachment point for a KRetProbe program is a Linux kernel function. + // +optional + Links []ClKretprobeAttachInfo `json:"links,omitempty"` +} + +type ClKretprobeAttachInfo struct { + // function is a required field and specifies the name of the Linux kernel + // function to attach the KRetProbe program. function must not be an empty + // string, must not exceed 64 characters in length, must start with alpha + // characters and must only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Function string `json:"function"` +} + +type ClKretprobeProgramInfoState struct { + // links is a list of attachment points for the KRetProbe program. Each entry + // in the list includes a linkStatus, which indicates if the attachment was + // successful or not on this node, a linkId, which is the kernel ID for the + // link if successfully attached, and other attachment specific data. + // +optional + Links []ClKretprobeAttachInfoState `json:"links,omitempty"` +} + +type ClKretprobeAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // function is the provisioned name of the Linux kernel function the KRetProbe + // program should be attached. + Function string `json:"function"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_tc_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_tc_program_types.go new file mode 100644 index 00000000000..73978fd5162 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_tc_program_types.go @@ -0,0 +1,137 @@ +/* +Copyright 2022. + +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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +// +kubebuilder:validation:Enum:=UnSpec;OK;ReClassify;Shot;Pipe;Stolen;Queued;Repeat;ReDirect;Trap;DispatcherReturn; +type TcProceedOnValue string + +type ClTcProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // TC program should be attached. The TC program is loaded in kernel memory + // when the BPF Application CRD is created and the selected Kubernetes nodes + // are active. The TC program will not be triggered until the program has also + // been attached to an attachment point described in this list. Items may be + // added or removed from the list at any point, causing the TC program to be + // attached or detached. + // + // The attachment point for a TC program is a network interface (or device). + // The interface can be specified by name, by allowing bpfman to discover each + // interface, or by setting the primaryNodeInterface flag, which instructs + // bpfman to use the primary interface of a Kubernetes node. Optionally, the + // TC program can also be installed into a set of network namespaces. + // +optional + Links []ClTcAttachInfo `json:"links,omitempty"` +} + +type ClTcAttachInfo struct { + // interfaceSelector is a required field and is used to determine the network + // interface (or interfaces) the TC program is attached. Interface list is set + // by providing a list of interface names, enabling auto discovery, or setting + // the primaryNodeInterface flag, but only one option is allowed. + // +required + InterfaceSelector InterfaceSelector `json:"interfaceSelector"` + + // networkNamespaces is an optional field that identifies the set of network + // namespaces in which to attach the eBPF program. If networkNamespaces is not + // specified, the eBPF program will be attached in the root network namespace. + // +optional + NetworkNamespaces *ClNetworkNamespaceSelector `json:"networkNamespaces,omitempty"` + + // direction is a required field and specifies the direction of traffic. + // Allowed values are: + // Ingress, Egress + // + // When set to Ingress, the TC program is triggered when packets are received + // by the interface. + // + // When set to Egress, the TC program is triggered when packets are to be + // transmitted by the interface. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is an optional field and determines the execution order of the TC + // program relative to other TC programs attached to the same attachment point. + // It must be a value between 0 and 1000, where lower values indicate higher + // precedence. For TC programs on the same attachment point with the same + // direction and priority, the most recently attached program has a lower + // precedence. If not provided, priority will default to 1000. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default:=1000 + Priority int32 `json:"priority,omitempty"` + + // proceedOn is an optional field and allows the user to call other TC programs + // in a chain, or not call the next program in a chain based on the exit code + // of a TC program. Allowed values, which are the possible exit codes from a TC + // eBPF program, are: + // UnSpec, OK, ReClassify, Shot, Pipe, Stolen, Queued, Repeat, ReDirect, + // Trap, DispatcherReturn + // + // Multiple values are supported. Default is OK, Pipe and DispatcherReturn. So + // using the default values, if a TC program returns Pipe, the next TC + // program in the chain will be called. If a TC program returns Stolen, the + // next TC program in the chain will NOT be called. + // +optional + // +kubebuilder:default:={Pipe,DispatcherReturn} + ProceedOn []TcProceedOnValue `json:"proceedOn,omitempty"` +} + +type ClTcProgramInfoState struct { + // links is a list of attachment points for the TC program. Each entry in the + // list includes a linkStatus, which indicates if the attachment was successful + // or not on this node, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + Links []ClTcAttachInfoState `json:"links,omitempty"` +} + +type ClTcAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // interfaceName is the name of the interface the TC program should be + // attached. + // +required + InterfaceName string `json:"interfaceName"` + + // netnsPath is the optional path to the network namespace inside of which the + // TC program should be attached. + // +optional + NetnsPath string `json:"netnsPath,omitempty"` + + // direction is the provisioned direction of traffic, Ingress or Egress, the TC + // program should be attached for a given network device. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is the provisioned 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. + // +required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + Priority int32 `json:"priority"` + + // proceedOn is the provisioned list of proceedOn values. proceedOn allows the + // user to call other TC programs in a chain, or not call the next program in a + // chain based on the exit code of a TC program .Multiple values are supported. + // +required + ProceedOn []TcProceedOnValue `json:"proceedOn"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_tcx_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_tcx_program_types.go new file mode 100644 index 00000000000..1c629cda7b8 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_tcx_program_types.go @@ -0,0 +1,114 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +// ClTcxProgramInfo defines the tcx program details +type ClTcxProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // TCX program should be attached. The TCX program is loaded in kernel memory + // when the BPF Application CRD is created and the selected Kubernetes nodes + // are active. The TCX program will not be triggered until the program has also + // been attached to an attachment point described in this list. Items may be + // added or removed from the list at any point, causing the TCX program to be + // attached or detached. + // + // The attachment point for a TCX program is a network interface (or device). + // The interface can be specified by name, by allowing bpfman to discover each + // interface, or by setting the primaryNodeInterface flag, which instructs + // bpfman to use the primary interface of a Kubernetes node. Optionally, the + // TCX program can also be installed into a set of network namespaces. + // +optional + Links []ClTcxAttachInfo `json:"links,omitempty"` +} + +type ClTcxAttachInfo struct { + // interfaceSelector is a required field and is used to determine the network + // interface (or interfaces) the TCX program is attached. Interface list is set + // by providing a list of interface names, enabling auto discovery, or setting + // the primaryNodeInterface flag, but only one option is allowed. + // +required + InterfaceSelector InterfaceSelector `json:"interfaceSelector"` + + // networkNamespaces is an optional field that identifies the set of network + // namespaces in which to attach the eBPF program. If networkNamespaces is not + // specified, the eBPF program will be attached in the root network namespace. + // +optional + NetworkNamespaces *ClNetworkNamespaceSelector `json:"networkNamespaces,omitempty"` + + // direction is a required field and specifies the direction of traffic. + // Allowed values are: + // Ingress, Egress + // + // When set to Ingress, the TC program is triggered when packets are received + // by the interface. + // + // When set to Egress, the TC program is triggered when packets are to be + // transmitted by the interface. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is an optional field and determines the execution order of the TCX + // program relative to other TCX programs attached to the same attachment + // point. It must be a value between 0 and 1000, where lower values indicate + // higher precedence. For TCX programs on the same attachment point with the + // same direction and priority, the most recently attached program has a lower + // precedence. If not provided, priority will default to 1000. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default:=1000 + Priority int32 `json:"priority,omitempty"` +} + +type ClTcxProgramInfoState struct { + // links is a list of attachment points for the TCX program. Each entry in the + // list includes a linkStatus, which indicates if the attachment was successful + // or not on this node, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + Links []ClTcxAttachInfoState `json:"links,omitempty"` +} + +type ClTcxAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // interfaceName is the name of the interface the TCX program should be + // attached. + // +required + InterfaceName string `json:"interfaceName"` + + // netnsPath is the optional path to the network namespace inside of which the + // TCX program should be attached. + // +optional + NetnsPath string `json:"netnsPath,omitempty"` + + // direction is the provisioned direction of traffic, Ingress or Egress, the TC + // program should be attached for a given network device. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is the provisioned priority of the TCX 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. + // +required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + Priority int32 `json:"priority"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_tracepoint_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_tracepoint_program_types.go new file mode 100644 index 00000000000..14b5e530428 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_tracepoint_program_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022. + +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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type ClTracepointProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // Tracepoint program should be attached. The Tracepoint program is loaded in + // kernel memory when the BPF Application CRD is created and the selected + // Kubernetes nodes are active. The Tracepoint program will not be triggered + // until the program has also been attached to an attachment point described in + // this list. Items may be added or removed from the list at any point, causing + // the Tracepoint program to be attached or detached. + // + // The attachment point for a Tracepoint program is a one of a predefined set + // of Linux kernel functions. + // +optional + Links []ClTracepointAttachInfo `json:"links,omitempty"` +} + +type ClTracepointAttachInfo struct { + // name is a required field and specifies the name of the Linux kernel + // Tracepoint to attach the eBPF program. name must not be an empty string, + // must not exceed 64 characters in length, must start with alpha characters + // and must only contain alphanumeric characters. + // +required + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Name string `json:"name"` +} + +type ClTracepointProgramInfoState struct { + // links is a list of attachment points for the Tracepoint program. Each entry + // in the list includes a linkStatus, which indicates if the attachment was + // successful or not on this node, a linkId, which is the kernel ID for the + // link if successfully attached, and other attachment specific data. + // +optional + Links []ClTracepointAttachInfoState `json:"links,omitempty"` +} + +type ClTracepointAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // The name of a kernel tracepoint to attach the bpf program to. + // name is the provisioned name of the Linux kernel tracepoint function the + // Tracepoint program should be attached. + // +required + Name string `json:"name"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_uprobe_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_uprobe_program_types.go new file mode 100644 index 00000000000..0c061f9bfd8 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_uprobe_program_types.go @@ -0,0 +1,113 @@ +/* +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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type ClUprobeProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // UProbe or URetProbe program should be attached. The eBPF program is loaded + // in kernel memory when the BPF Application CRD is created and the selected + // Kubernetes nodes are active. The eBPF program will not be triggered until + // the program has also been attached to an attachment point described in this + // list. Items may be added or removed from the list at any point, causing the + // eBPF program to be attached or detached. + // + // The attachment point for a UProbe and URetProbe program is a user-space + // binary or function. By default, the eBPF program is triggered at the entry + // of the attachment point, but the attachment point can be adjusted using an + // optional function name and/or offset. Optionally, the eBPF program can be + // installed in a set of containers or limited to a specified PID. + // +optional + Links []ClUprobeAttachInfo `json:"links,omitempty"` +} + +type ClUprobeAttachInfo struct { + // function is an optional field and specifies the name of a user-space function + // to attach the UProbe or URetProbe program. If not provided, the eBPF program + // will be triggered on the entry of the target. function must not be an empty + // string, must not exceed 64 characters in length, must start with alpha + // characters and must only contain alphanumeric characters. + // +optional + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Function string `json:"function,omitempty"` + + // offset is an optional field and the value is added to the address of the + // attachment point function. + // +optional + // +kubebuilder:default:=0 + Offset uint64 `json:"offset,omitempty"` + + // target is a required field and is the user-space library name or the + // absolute path to a binary or library. + // +required + Target string `json:"target"` + + // pid is an optional field and if provided, limits the execution of the UProbe + // or URetProbe to the provided process identification number (PID). If pid is + // not provided, the UProbe or URetProbe executes for all PIDs. + // +optional + Pid *int32 `json:"pid,omitempty"` + + // containers is an optional field that identifies the set of containers in + // which to attach the UProbe or URetProbe program. If containers is not + // specified, the eBPF program will be attached in the bpfman container. + // +optional + Containers *ClContainerSelector `json:"containers,omitempty"` +} + +type ClUprobeProgramInfoState struct { + // links is a list of attachment points for the UProbe program. Each entry in + // the list includes a linkStatus, which indicates if the attachment was + // successful or not on this node, a linkId, which is the kernel ID for the + // link if successfully attached, and other attachment specific data. + // +optional + Links []ClUprobeAttachInfoState `json:"links,omitempty"` +} + +type ClUprobeAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // function is the provisioned name of the user-space function the UProbe + // program should be attached. + // +optional + Function string `json:"function,omitempty"` + + // offset is the provisioned offset, whose value is added to the address of the + // attachment point function. + // +optional + // +kubebuilder:default:=0 + Offset uint64 `json:"offset"` + + // target is the provisioned user-space library name or the absolute path to a + // binary or library. + // +required + Target string `json:"target"` + + // pid is the provisioned pid. If set, pid limits the execution of the UProbe + // or URetProbe to the provided process identification number (PID). If pid is + // not provided, the UProbe or URetProbe executes for all PIDs. + // +optional + Pid *int32 `json:"pid,omitempty"` + + // If containers is provisioned in the ClusterBpfApplication instance, + // containerPid is the derived PID of the container the UProbe or URetProbe this + // attachment point is attached. + // +optional + ContainerPid *int32 `json:"containerPid,omitempty"` +} diff --git a/bpfman-operator/apis/v1alpha1/cluster_xdp_program_types.go b/bpfman-operator/apis/v1alpha1/cluster_xdp_program_types.go new file mode 100644 index 00000000000..3f25e801a38 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/cluster_xdp_program_types.go @@ -0,0 +1,117 @@ +/* +Copyright 2022. + +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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +// +kubebuilder:validation:Enum:=Aborted;Drop;Pass;TX;ReDirect;DispatcherReturn; +type XdpProceedOnValue string + +type ClXdpProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // XDP program should be attached. The XDP program is loaded in kernel memory + // when the BPF Application CRD is created and the selected Kubernetes nodes + // are active. The XDP program will not be triggered until the program has also + // been attached to an attachment point described in this list. Items may be + // added or removed from the list at any point, causing the XDP program to be + // attached or detached. + // + // The attachment point for an XDP program is a network interface (or device). + // The interface can be specified by name, by allowing bpfman to discover each + // interface, or by setting the primaryNodeInterface flag, which instructs + // bpfman to use the primary interface of a Kubernetes node. Optionally, the + // XDP program can also be installed into a set of network namespaces. + // +optional + Links []ClXdpAttachInfo `json:"links,omitempty"` +} + +type ClXdpAttachInfo struct { + // interfaceSelector is a required field and is used to determine the network + // interface (or interfaces) the XDP program is attached. Interface list is set + // by providing a list of interface names, enabling auto discovery, or setting + // the primaryNodeInterface flag, but only one option is allowed. + // +required + InterfaceSelector InterfaceSelector `json:"interfaceSelector"` + + // networkNamespaces identifies the set of network namespaces in which to + // attach the eBPF program. If networkNamespaces is not specified, the eBPF + // program will be attached in the root network namespace. + // +optional + NetworkNamespaces *ClNetworkNamespaceSelector `json:"networkNamespaces,omitempty"` + + // priority is an optional field and determines the execution order of the XDP + // program relative to other XDP programs attached to the same attachment + // point. It must be a value between 0 and 1000, where lower values indicate + // higher precedence. For XDP programs on the same attachment point with the + // same priority, the most recently attached program has a lower precedence. If + // not provided, priority will default to 1000. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default:=1000 + Priority int32 `json:"priority,omitempty"` + + // proceedOn is an optional field and allows the user to call other XDP + // programs in a chain, or not call the next program in a chain based on the + // exit code of an XDP program. Allowed values, which are the possible exit + // codes from an XDP eBPF program, are: + // Aborted, Drop, Pass, TX, ReDirect, DispatcherReturn + // + // Multiple values are supported. Default is Pass and DispatcherReturn. So + // using the default values, if an XDP program returns Pass, the next XDP + // program in the chain will be called. If an XDP program returns Drop, the + // next XDP program in the chain will NOT be called. + // +optional + // +kubebuilder:default:={Pass,DispatcherReturn} + ProceedOn []XdpProceedOnValue `json:"proceedOn,omitempty"` +} + +type ClXdpProgramInfoState struct { + // links is a list of attachment points for the XDP program. Each entry in the + // list includes a linkStatus, which indicates if the attachment was successful + // or not on this node, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + Links []ClXdpAttachInfoState `json:"links,omitempty"` +} + +type ClXdpAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // interfaceName is the name of the interface the XDP program should be + // attached. + // +required + InterfaceName string `json:"interfaceName"` + + // netnsPath is the optional path to the network namespace inside of which the + // XDP program should be attached. + // +optional + NetnsPath string `json:"netnsPath,omitempty"` + + // priority is the provisioned 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. + // +required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + Priority int32 `json:"priority"` + + // proceedOn is the provisioned list of proceedOn values. proceedOn allows the + // user to call other TC programs in a chain, or not call the next program in a + // chain based on the exit code of a TC program .Multiple values are supported. + // +required + ProceedOn []XdpProceedOnValue `json:"proceedOn"` +} diff --git a/bpfman-operator/apis/v1alpha1/doc.go b/bpfman-operator/apis/v1alpha1/doc.go new file mode 100644 index 00000000000..18313d2cf9e --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2022 The Kubernetes 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 contains API Schema definitions for the +// bpfman.io API group. +// +kubebuilder:object:generate=true +// +groupName=bpfman.io +package v1alpha1 diff --git a/bpfman-operator/apis/v1alpha1/shared_types.go b/bpfman-operator/apis/v1alpha1/shared_types.go new file mode 100644 index 00000000000..3e20dc29d58 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/shared_types.go @@ -0,0 +1,506 @@ +/* +Copyright 2022. + +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" +) + +type InterfaceDiscovery struct { + // interfaceAutoDiscovery is an optional field. When enabled, the agent + // monitors the creation and deletion of interfaces and automatically + // attached eBPF programs to the newly discovered interfaces. + // CAUTION: This has the potential to attach a given eBPF program to a large + // number of interfaces. Use with caution. + // +optional + // +kubebuilder:default:=false + InterfaceAutoDiscovery *bool `json:"interfaceAutoDiscovery,omitempty"` + + // excludeInterfaces is an optional field that contains a list of interface + // names that are excluded from interface discovery. The interface names in + // the list are case-sensitive. By default, the list contains the loopback + // interface, "lo". This field is only taken into consideration if + // interfaceAutoDiscovery is set to true. + // +optional + // +kubebuilder:default:={"lo"} + ExcludeInterfaces []string `json:"excludeInterfaces,omitempty"` + + // allowedInterfaces is an optional field that contains a list of interface + // names that are allowed to be discovered. If empty, the agent will fetch all + // the interfaces in the system, excepting the ones listed in + // excludeInterfaces. if non-empty, only entries in the list will be considered + // for discovery. If an entry enclosed by slashes, such as `/br-/` or + // `/veth*/`, then the entry is considered as a regular expression for + // matching. Otherwise, the interface names in the list are case-sensitive. + // This field is only taken into consideration if interfaceAutoDiscovery is set + // to true. + // +optional + AllowedInterfaces []string `json:"allowedInterfaces,omitempty"` +} + +// InterfaceSelector describes the set of interfaces to attach a program to. +// +kubebuilder:validation:MaxProperties=1 +// +kubebuilder:validation:MinProperties=1 +type InterfaceSelector struct { + // interfacesDiscoveryConfig is an optional field that is used to control if + // and how to automatically discover interfaces. If the agent should + // automatically discover and attach eBPF programs to interfaces, use the + // fields under interfacesDiscoveryConfig to control what is allow and excluded + // from discovery. + // +optional + InterfacesDiscoveryConfig *InterfaceDiscovery `json:"interfacesDiscoveryConfig,omitempty"` + + // interfaces is an optional field and is a list of network interface names to + // attach the eBPF program. The interface names in the list are case-sensitive. + // +optional + Interfaces []string `json:"interfaces,omitempty"` + + // primaryNodeInterface is and optional field and indicates to attach the eBPF + // program to the primary interface on the Kubernetes node. Only 'true' is + // accepted. + // +optional + PrimaryNodeInterface *bool `json:"primaryNodeInterface,omitempty"` +} + +// ClContainerSelector identifies a set of containers. +type ClContainerSelector struct { + // namespace is an optional field and indicates the target Kubernetes + // namespace. If not provided, all Kubernetes namespaces are included. + // +optional + Namespace string `json:"namespace,omitempty"` + + // pods is a required field and indicates the target pods. To select all pods + // use the standard metav1.LabelSelector semantics and make it empty. + // +required + Pods metav1.LabelSelector `json:"pods"` + + // containerNames is an optional field and is a list of container names in a + // pod to attach the eBPF program. If no names are specified, all containers + // in the pod are selected. + // +optional + ContainerNames []string `json:"containerNames,omitempty"` +} + +// ContainerSelector identifies a set of containers. It is different from ClContainerSelector +// in that "Namespace" was removed. Namespace scoped programs can only attach to the namespace +// they are created in. +type ContainerSelector struct { + // pods is a required field and indicates the target pods. To select all pods + // use the standard metav1.LabelSelector semantics and make it empty. + // +required + Pods metav1.LabelSelector `json:"pods"` + + // containerNames is an optional field and is a list of container names in a + // pod to attach the eBPF program. If no names are specified, all containers + // in the pod are selected. + // +optional + ContainerNames []string `json:"containerNames,omitempty"` +} + +// ClNetworkNamespaceSelector identifies a network namespace for network-related +// program types in the cluster-scoped ClusterBpfApplication object. +type ClNetworkNamespaceSelector struct { + // namespace is an optional field and indicates the target network namespace. + // If not provided, the default network namespace is used. + // +optional + Namespace string `json:"namespace,omitempty"` + + // pods is a required field and indicates the target pods. To select all pods + // use the standard metav1.LabelSelector semantics and make it empty. + // +required + Pods metav1.LabelSelector `json:"pods"` +} + +// NetworkNamespaceSelector identifies a network namespace for network-related +// program types in the namespace-scoped BpfApplication object. +type NetworkNamespaceSelector struct { + // pods is a required field and indicates the target pods. To select all pods + // use the standard metav1.LabelSelector semantics and make it empty. + // +required + Pods metav1.LabelSelector `json:"pods"` +} + +// BpfAppCommon defines the common attributes for all BpfApp programs +type BpfAppCommon struct { + // nodeSelector is a required field and allows the user to specify which + // Kubernetes nodes to deploy the eBPF programs. To select all nodes use + // standard metav1.LabelSelector semantics and make it empty. + // +required + NodeSelector metav1.LabelSelector `json:"nodeSelector"` + + // globalData is an optional field that allows the user to set global variables + // when the program is loaded. This allows the same compiled bytecode to be + // deployed by different BPF Applications to behave differently based on + // globalData configuration values. It uses an array of raw bytes. This is a + // very low level primitive. The caller is responsible for formatting the byte + // string appropriately considering such things as size, endianness, alignment + // and packing of data structures. + // +optional + GlobalData map[string][]byte `json:"globalData,omitempty"` + + // bytecode is a required field and configures where the eBPF program's + // bytecode should be loaded from. The image must contain one or more + // eBPF programs. + // +required + ByteCode ByteCodeSelector `json:"byteCode"` + + // mapOwnerSelector is an optional field used to share maps across + // applications. eBPF programs loaded with the same ClusterBpfApplication or + // BpfApplication instance do not need to use this field. This label selector + // allows maps from a different ClusterBpfApplication or BpfApplication + // instance to be used by this instance. + // TODO: mapOwnerSelector is currently not supported due to recent code rework. + // +optional + MapOwnerSelector *metav1.LabelSelector `json:"mapOwnerSelector,omitempty"` +} + +// status reflects the status of a BPF Application and indicates if all the +// eBPF programs for a given instance loaded successfully or not. +type BpfAppStatus struct { + // conditions contains the summary state for all eBPF programs defined in the + // BPF Application instance for all the Kubernetes nodes in the cluster. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// AttachInfoStateCommon reflects the status for one attach point for a given bpf +// application program +type AttachInfoStateCommon struct { + // shouldAttach reflects whether the attachment should exist. + // +required + ShouldAttach bool `json:"shouldAttach"` + // uuid is an Unique identifier for the attach point assigned by bpfman agent. + // +required + UUID string `json:"uuid"` + // linkId is an identifier for the link assigned by bpfman. This field is + // empty until the program is successfully attached and bpfman returns the + // id. + // +optional + LinkId *uint32 `json:"linkId,omitempty"` + // linkStatus reflects whether the attachment has been reconciled + // successfully, and if not, why. + // +required + LinkStatus LinkStatus `json:"linkStatus"` +} + +type BpfProgramStateCommon struct { + // name is the name of the function that is the entry point for the eBPF + // program + // +required + Name string `json:"name"` + // programLinkStatus reflects whether all links requested for the program + // are in the correct state. + // +required + ProgramLinkStatus ProgramLinkStatus `json:"programLinkStatus"` + // programId is the id of the program in the kernel. Not set until the + // program is loaded. + // +optional + ProgramId *uint32 `json:"programId,omitempty"` +} + +// PullPolicy describes a policy for if/when to pull a container image +// +kubebuilder:validation:Enum=Always;Never;IfNotPresent +type PullPolicy string + +const ( + // PullAlways means that bpfman always attempts to pull the latest bytecode image. Container will fail If the pull fails. + PullAlways PullPolicy = "Always" + // PullNever means that bpfman never pulls an image, but only uses a local image. Container will fail if the image isn't present + PullNever PullPolicy = "Never" + // PullIfNotPresent means that bpfman pulls if the image isn't present on disk. Container will fail if the image isn't present and the pull fails. + PullIfNotPresent PullPolicy = "IfNotPresent" +) + +// ByteCodeSelector defines the various ways to reference BPF bytecode objects. +// +kubebuilder:validation:MaxProperties=1 +// +kubebuilder:validation:MinProperties=1 +type ByteCodeSelector struct { + // image is an optional field and used to specify details on how to retrieve an + // eBPF program packaged in a OCI container image from a given registry. + // +optional + Image *ByteCodeImage `json:"image,omitempty"` + + // path is an optional field and used to specify a bytecode object file via + // filepath on a Kubernetes node. + // +optional + // +kubebuilder:validation:Pattern=`^(/[^/\0]+)+/?$` + Path *string `json:"path,omitempty"` +} + +// ByteCodeImage defines how to specify a bytecode container image. +type ByteCodeImage struct { + // url is a required field and is a valid container image URL used to reference + // a remote bytecode image. url must not be an empty string, must not exceed + // 525 characters in length and must be a valid URL. + // +required + // +kubebuilder:validation:Required + // +kubebuilder:validation:MaxLength:=525 + // +kubebuilder:validation:Pattern=`[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}` + Url string `json:"url"` + + // pullPolicy is an optional field that describes a policy for if/when to pull + // a bytecode image. Defaults to IfNotPresent. Allowed values are: + // Always, IfNotPresent and Never + // + // When set to Always, the given image will be pulled even if the image is + // already present on the node. + // + // When set to IfNotPresent, the given image will only be pulled if it is not + // present on the node. + // + // When set to Never, the given image will never be pulled and must be + // loaded on the node by some other means. + // +optional + // +kubebuilder:default:=IfNotPresent + ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty"` + + // imagePullSecret is an optional field and indicates the secret which contains + // the credentials to access the image repository. + // +optional + ImagePullSecret *ImagePullSecretSelector `json:"imagePullSecret,omitempty"` +} + +// ImagePullSecretSelector defines the name and namespace of an image pull secret. +type ImagePullSecretSelector struct { + // name is a required field and is the name of the secret which contains the + // credentials to access the image repository. + // +required + Name string `json:"name"` + + // namespace is a required field and is the namespace of the secret which + // contains the credentials to access the image repository. + // +required + Namespace string `json:"namespace"` +} + +// ----------------------------------------------------------------------------- +// Status Conditions - BPF Programs +// ----------------------------------------------------------------------------- + +// BpfApplicationConditionType is a condition type to indicate the status of a BPF +// application at the cluster level. +type BpfApplicationConditionType string + +const ( + // BpfAppCondPending indicates that bpfman has not yet completed reconciling + // the Bpf Application on all nodes in the cluster. + BpfAppCondPending BpfApplicationConditionType = "Pending" + + // BpfAppCondSuccess indicates that the BPF Application has been + // successfully loaded and attached as requested on all nodes in the + // cluster. + BpfAppCondSuccess BpfApplicationConditionType = "Success" + + // BpfAppCondError indicates that an error has occurred on one or more nodes + // while attempting to apply the configuration described in the CRD. + BpfAppCondError BpfApplicationConditionType = "Error" + + // BpfAppCondDeleteError indicates that the BPF Application was marked for + // deletion, but deletion was unsuccessful on one or more nodes. + BpfAppCondDeleteError BpfApplicationConditionType = "DeleteError" +) + +// Condition is a helper method to promote any given BpfApplicationConditionType +// to a full metav1.Condition in an opinionated fashion. +// +// TODO: this was created in the early days to provide at least SOME status +// information to the user, but the hardcoded messages need to be replaced in +// the future with dynamic and situation-aware messages later. +// +// See: https://github.com/bpfman/bpfman/issues/430 +func (b BpfApplicationConditionType) Condition(message string) metav1.Condition { + cond := metav1.Condition{} + + switch b { + case BpfAppCondPending: + if len(message) == 0 { + message = "Waiting for Bpf Application Object to be reconciled on all nodes" + } + condType := string(BpfAppCondPending) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Pending", + Message: message, + } + case BpfAppCondError: + if len(message) == 0 { + message = "An error has occurred on one or more nodes" + } + condType := string(BpfAppCondError) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Error", + Message: message, + } + case BpfAppCondSuccess: + if len(message) == 0 { + message = "BPF application configuration successfully applied on all nodes" + } + condType := string(BpfAppCondSuccess) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Success", + Message: message, + } + case BpfAppCondDeleteError: + if len(message) == 0 { + message = "Deletion failed on one or more nodes" + } + condType := string(BpfAppCondDeleteError) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "DeleteError", + Message: message, + } + } + + return cond +} + +// BpfApplicationStateConditionType is used to indicate the status of a BPF +// application on a given node. +type BpfApplicationStateConditionType string + +const ( + // BpfAppStateCondPending indicates that bpfman has not yet completed + // reconciling the Bpf Application on the given node. + BpfAppStateCondPending BpfApplicationStateConditionType = "Pending" + + // BpfAppStateCondSuccess indicates that the BPF Application has been + // successfully loaded and attached as requested on the given node. + BpfAppStateCondSuccess BpfApplicationStateConditionType = "Success" + + // BpfAppStateCondError indicates that an error has occurred on the given + // node while attempting to apply the configuration described in the CRD. + BpfAppStateCondError BpfApplicationStateConditionType = "Error" + + // BpfAppStateCondError indicates that an error has occurred on the given + // node while attempting to apply the configuration described in the CRD. + BpfAppStateCondProgramListChangedError BpfApplicationStateConditionType = "ProgramListChangedError" + + // BpfAppStateCondUnloadError indicates that the BPF Application was marked + // for deletion, but unloading one or more programs was unsuccessful on the + // given node. + BpfAppStateCondUnloadError BpfApplicationStateConditionType = "UnloadError" + + // BpfAppStateCondUnloaded indicates that the BPF Application was marked + // for deletion, and has been successfully unloaded. + BpfAppStateCondUnloaded BpfApplicationStateConditionType = "Unloaded" +) + +// Condition is a helper method to promote any given +// BpfApplicationStateConditionType to a full metav1.Condition in an opinionated +// fashion. +func (b BpfApplicationStateConditionType) Condition() metav1.Condition { + cond := metav1.Condition{} + + switch b { + case BpfAppStateCondPending: + condType := string(BpfAppStateCondPending) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Pending", + Message: "Not yet complete", + } + case BpfAppStateCondSuccess: + condType := string(BpfAppStateCondSuccess) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Success", + Message: "The BPF application has been successfully loaded and attached", + } + case BpfAppStateCondError: + condType := string(BpfAppStateCondError) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Error", + Message: "An error has occurred", + } + case BpfAppStateCondUnloadError: + condType := string(BpfAppStateCondUnloadError) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Unload Error", + Message: "Unload failed for one or more programs", + } + case BpfAppStateCondUnloaded: + condType := string(BpfAppStateCondUnloaded) + cond = metav1.Condition{ + Type: condType, + Status: metav1.ConditionTrue, + Reason: "Unloaded", + Message: "The application has been successfully unloaded", + } + } + return cond +} + +type AppLoadStatus string + +const ( + // The initial load condition + AppLoadNotLoaded AppLoadStatus = "NotLoaded" + // All programs for app have been loaded + AppLoadSuccess AppLoadStatus = "LoadSuccess" + // One or more programs for app has not been loaded + AppLoadError AppLoadStatus = "LoadError" + // All programs for app have been unloaded + AppUnLoadSuccess AppLoadStatus = "UnloadSuccess" + // One or more programs for app has not been unloaded + AppUnloadError AppLoadStatus = "UnloadError" + // The app is not selected to run on the node + NotSelected AppLoadStatus = "NotSelected" + // The program list has changed which is not allowed + ProgListChangedError AppLoadStatus = "ProgramListChangedError" +) + +type ProgramLinkStatus string + +const ( + // The initial program attach state + ProgAttachPending ProgramLinkStatus = "Pending" + // All attachments for program are in the correct state + ProgAttachSuccess ProgramLinkStatus = "Success" + // One or more attachments for program are not in the correct state + ProgAttachError ProgramLinkStatus = "Error" + // There was an error updating the attach info + UpdateAttachInfoError ProgramLinkStatus = "UpdateAttachInfoError" +) + +type LinkStatus string + +const ( + // Attach point is attached + ApAttachAttached LinkStatus = "Attached" + // Attach point is not attached + ApAttachNotAttached LinkStatus = "NotAttached" + // An attach was attempted, but there was an error + ApAttachError LinkStatus = "AttachError" + // A detach was attempted, but there was an error + ApDetachError LinkStatus = "DetachError" +) diff --git a/bpfman-operator/apis/v1alpha1/tc_program_types.go b/bpfman-operator/apis/v1alpha1/tc_program_types.go new file mode 100644 index 00000000000..efe56e3d478 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/tc_program_types.go @@ -0,0 +1,133 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type TcProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // TC program should be attached. The TC program is loaded in kernel memory + // when the BPF Application CRD is created and the selected Kubernetes nodes + // are active. The TC program will not be triggered until the program has also + // been attached to an attachment point described in this list. Items may be + // added or removed from the list at any point, causing the TC program to be + // attached or detached. + // + // The attachment point for a TC program is a network interface (or device). + // The interface can be specified by name, by allowing bpfman to discover each + // interface, or by setting the primaryNodeInterface flag, which instructs + // bpfman to use the primary interface of a Kubernetes node. Optionally, the + // TC program can also be installed into a set of network namespaces. + // +optional + Links []TcAttachInfo `json:"links,omitempty"` +} + +type TcAttachInfo struct { + // interfaceSelector is a required field and is used to determine the network + // interface (or interfaces) the TC program is attached. Interface list is set + // by providing a list of interface names, enabling auto discovery, or setting + // the primaryNodeInterface flag, but only one option is allowed. + // +required + InterfaceSelector InterfaceSelector `json:"interfaceSelector"` + + // networkNamespaces is a required field that identifies the set of network + // namespaces in which to attach the eBPF program. + // +required + NetworkNamespaces NetworkNamespaceSelector `json:"networkNamespaces"` + + // direction is a required field and specifies the direction of traffic. + // Allowed values are: + // Ingress, Egress + // + // When set to Ingress, the TC program is triggered when packets are received + // by the interface. + // + // When set to Egress, the TC program is triggered when packets are to be + // transmitted by the interface. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is an optional field and determines the execution order of the TC + // program relative to other TC programs attached to the same attachment point. + // It must be a value between 0 and 1000, where lower values indicate higher + // precedence. For TC programs on the same attachment point with the same + // direction and priority, the most recently attached program has a lower + // precedence. If not provided, priority will default to 1000. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default:=1000 + Priority int32 `json:"priority,omitempty"` + + // proceedOn is an optional field and allows the user to call other TC programs + // in a chain, or not call the next program in a chain based on the exit code + // of a TC program. Allowed values, which are the possible exit codes from a TC + // eBPF program, are: + // UnSpec, OK, ReClassify, Shot, Pipe, Stolen, Queued, Repeat, ReDirect, + // Trap, DispatcherReturn + // + // Multiple values are supported. Default is OK, Pipe and DispatcherReturn. So + // using the default values, if a TC program returns Pipe, the next TC + // program in the chain will be called. If a TC program returns Stolen, the + // next TC program in the chain will NOT be called. + // +optional + // +kubebuilder:default:={Pipe,DispatcherReturn} + ProceedOn []TcProceedOnValue `json:"proceedOn,omitempty"` +} + +type TcProgramInfoState struct { + // links is a list of attachment points for the TC program. Each entry in the + // list includes a linkStatus, which indicates if the attachment was successful + // or not on this node, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + Links []TcAttachInfoState `json:"links,omitempty"` +} + +type TcAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // interfaceName is the name of the interface the TC program should be + // attached. + // +required + InterfaceName string `json:"interfaceName"` + + // netnsPath is the path to the network namespace inside of which the TC + // program should be attached. + // +required + NetnsPath string `json:"netnsPath"` + + // direction is the provisioned direction of traffic, Ingress or Egress, the TC + // program should be attached for a given network device. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is the provisioned 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. + // +required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + Priority int32 `json:"priority"` + + // proceedOn is the provisioned list of proceedOn values. proceedOn allows the + // user to call other TC programs in a chain, or not call the next program in a + // chain based on the exit code of a TC program .Multiple values are supported. + // +required + ProceedOn []TcProceedOnValue `json:"proceedOn"` +} diff --git a/bpfman-operator/apis/v1alpha1/tcx_program_types.go b/bpfman-operator/apis/v1alpha1/tcx_program_types.go new file mode 100644 index 00000000000..9c0b547291c --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/tcx_program_types.go @@ -0,0 +1,113 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +// TcxProgramInfo defines the tcx program details +type TcxProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // TCX program should be attached. The TCX program is loaded in kernel memory + // when the BPF Application CRD is created and the selected Kubernetes nodes + // are active. The TCX program will not be triggered until the program has also + // been attached to an attachment point described in this list. Items may be + // added or removed from the list at any point, causing the TCX program to be + // attached or detached. + // + // The attachment point for a TCX program is a network interface (or device). + // The interface can be specified by name, by allowing bpfman to discover each + // interface, or by setting the primaryNodeInterface flag, which instructs + // bpfman to use the primary interface of a Kubernetes node. Optionally, the + // TCX program can also be installed into a set of network namespaces. + // +optional + Links []TcxAttachInfo `json:"links,omitempty"` +} + +type TcxAttachInfo struct { + // interfaceSelector is a required field and is used to determine the network + // interface (or interfaces) the TCX program is attached. Interface list is set + // by providing a list of interface names, enabling auto discovery, or setting + // the primaryNodeInterface flag, but only one option is allowed. + // +required + InterfaceSelector InterfaceSelector `json:"interfaceSelector"` + + // networkNamespaces is a required field that identifies the set of network + // namespaces in which to attach the eBPF program. + // +required + NetworkNamespaces NetworkNamespaceSelector `json:"networkNamespaces"` + + // direction is a required field and specifies the direction of traffic. + // Allowed values are: + // Ingress, Egress + // + // When set to Ingress, the TC program is triggered when packets are received + // by the interface. + // + // When set to Egress, the TC program is triggered when packets are to be + // transmitted by the interface. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is an optional field and determines the execution order of the TCX + // program relative to other TCX programs attached to the same attachment + // point. It must be a value between 0 and 1000, where lower values indicate + // higher precedence. For TCX programs on the same attachment point with the + // same direction and priority, the most recently attached program has a lower + // precedence. If not provided, priority will default to 1000. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default:=1000 + Priority int32 `json:"priority,omitempty"` +} + +type TcxProgramInfoState struct { + // links is a list of attachment points for the TCX program. Each entry in the + // list includes a linkStatus, which indicates if the attachment was successful + // or not on this node, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + Links []TcxAttachInfoState `json:"links,omitempty"` +} + +type TcxAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // interfaceName is the name of the interface the TCX program should be + // attached. + // +required + InterfaceName string `json:"interfaceName"` + + // netnsPath is the path to the network namespace inside of which the TCX + // program should be attached. + // +required + NetnsPath string `json:"netnsPath"` + + // direction is the provisioned direction of traffic, Ingress or Egress, the + // TCX program should be attached for a given network device. + // +required + // +kubebuilder:validation:Enum=Ingress;Egress + Direction TCDirectionType `json:"direction"` + + // priority is the provisioned priority of the TCX 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. + // +required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + Priority int32 `json:"priority"` +} diff --git a/bpfman-operator/apis/v1alpha1/uprobe_program_types.go b/bpfman-operator/apis/v1alpha1/uprobe_program_types.go new file mode 100644 index 00000000000..9176a452068 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/uprobe_program_types.go @@ -0,0 +1,113 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type UprobeProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // UProbe or URetProbe program should be attached. The eBPF program is loaded + // in kernel memory when the BPF Application CRD is created and the selected + // Kubernetes nodes are active. The eBPF program will not be triggered until + // the program has also been attached to an attachment point described in this + // list. Items may be added or removed from the list at any point, causing the + // eBPF program to be attached or detached. + // + // The attachment point for a UProbe and URetProbe program is a user-space + // binary or function. By default, the eBPF program is triggered at the entry + // of the attachment point, but the attachment point can be adjusted using an + // optional function name and/or offset. Optionally, the eBPF program can be + // installed in a set of containers or limited to a specified PID. + // +optional + Links []UprobeAttachInfo `json:"links,omitempty"` +} + +type UprobeAttachInfo struct { + // function is an optional field and specifies the name of a user-space function + // to attach the UProbe or URetProbe program. If not provided, the eBPF program + // will be triggered on the entry of the target. function must not be an empty + // string, must not exceed 64 characters in length, must start with alpha + // characters and must only contain alphanumeric characters. + // +optional + // +kubebuilder:validation:Pattern="^[a-zA-Z][a-zA-Z0-9_]+." + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=64 + Function string `json:"function,omitempty"` + + // offset is an optional field and the value is added to the address of the + // attachment point function. If not provided, offset defaults to 0. + // +optional + // +kubebuilder:default:=0 + Offset uint64 `json:"offset"` + + // target is a required field and is the user-space library name or the + // absolute path to a binary or library. + // +required + Target string `json:"target"` + + // pid is an optional field and if provided, limits the execution of the UProbe + // or URetProbe to the provided process identification number (PID). If pid is + // not provided, the UProbe or URetProbe executes for all PIDs. + // +optional + Pid *int32 `json:"pid,omitempty"` + + // containers is an optional field that identifies the set of containers in + // which to attach the UProbe or URetProbe program. If containers is not + // specified, the eBPF program will be attached in the bpfman container. + // uprobe. + Containers ContainerSelector `json:"containers"` +} + +type UprobeProgramInfoState struct { + // links is a list of attachment points for the UProbe program. Each entry in + // the list includes a linkStatus, which indicates if the attachment was + // successful or not on this node, a linkId, which is the kernel ID for the + // link if successfully attached, and other attachment specific data. + // +optional + Links []UprobeAttachInfoState `json:"links,omitempty"` +} + +type UprobeAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // function is the provisioned name of the user-space function the UProbe + // program should be attached. + // +optional + Function string `json:"function,omitempty"` + + // offset is the provisioned offset, whose value is added to the address of the + // attachment point function. + // +optional + // +kubebuilder:default:=0 + Offset uint64 `json:"offset"` + + // target is the provisioned user-space library name or the absolute path to a + // binary or library. + // +required + Target string `json:"target"` + + // pid is the provisioned pid. If set, pid limits the execution of the UProbe + // or URetProbe to the provided process identification number (PID). If pid is + // not provided, the UProbe or URetProbe executes for all PIDs. + // +optional + Pid *int32 `json:"pid,omitempty"` + + // If containers is provisioned in the BpfApplication instance, containerPid is + // the derived PID of the container the UProbe or URetProbe this attachment + // point is attached. + // +optional + ContainerPid int32 `json:"containerPid,omitempty"` +} diff --git a/bpfman-operator/apis/v1alpha1/xdp_program_types.go b/bpfman-operator/apis/v1alpha1/xdp_program_types.go new file mode 100644 index 00000000000..872c053ffba --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/xdp_program_types.go @@ -0,0 +1,112 @@ +/* +Copyright 2024 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. +*/ + +// All fields are required unless explicitly marked optional +package v1alpha1 + +type XdpProgramInfo struct { + // links is an optional field and is the list of attachment points to which the + // XDP program should be attached. The XDP program is loaded in kernel memory + // when the BPF Application CRD is created and the selected Kubernetes nodes + // are active. The XDP program will not be triggered until the program has also + // been attached to an attachment point described in this list. Items may be + // added or removed from the list at any point, causing the XDP program to be + // attached or detached. + // + // The attachment point for a XDP program is a network interface (or device). + // The interface can be specified by name, by allowing bpfman to discover each + // interface, or by setting the primaryNodeInterface flag, which instructs + // bpfman to use the primary interface of a Kubernetes node. + // +optional + Links []XdpAttachInfo `json:"links,omitempty"` +} + +type XdpAttachInfo struct { + // interfaceSelector is a required field and is used to determine the network + // interface (or interfaces) the XDP program is attached. Interface list is set + // by providing a list of interface names, enabling auto discovery, or setting + // the primaryNodeInterface flag, but only one option is allowed. + // +required + InterfaceSelector InterfaceSelector `json:"interfaceSelector"` + + // networkNamespaces is a required field that identifies the set of network + // namespaces in which to attach the eBPF program. + // +required + NetworkNamespaces NetworkNamespaceSelector `json:"networkNamespaces"` + + // priority is an optional field and determines the execution order of the XDP + // program relative to other XDP programs attached to the same attachment + // point. It must be a value between 0 and 1000, where lower values indicate + // higher precedence. For XDP programs on the same attachment point with the + // same priority, the most recently attached program has a lower precedence. + // If not provided, priority will default to 1000. + // +optional + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + // +kubebuilder:default:=1000 + Priority int32 `json:"priority,omitempty"` + + // proceedOn is an optional field and allows the user to call other XDP + // programs in a chain, or not call the next program in a chain based on the + // exit code of an XDP program. Allowed values, which are the possible exit + // codes from an XDP eBPF program, are: + // Aborted, Drop, Pass, TX, ReDirect,DispatcherReturn + // + // Multiple values are supported. Default is Pass and DispatcherReturn. So + // using the default values, if an XDP program returns Pass, the next XDP + // program in the chain will be called. If an XDP program returns Drop, the + // next XDP program in the chain will NOT be called. + // +optional + // +kubebuilder:default:={Pass,DispatcherReturn} + ProceedOn []XdpProceedOnValue `json:"proceedOn,omitempty"` +} + +type XdpProgramInfoState struct { + // links is a list of attachment points for the XDP program. Each entry in the + // list includes a linkStatus, which indicates if the attachment was successful + // or not on this node, a linkId, which is the kernel ID for the link if + // successfully attached, and other attachment specific data. + // +optional + Links []XdpAttachInfoState `json:"links,omitempty"` +} + +type XdpAttachInfoState struct { + AttachInfoStateCommon `json:",inline"` + + // interfaceName is the name of the interface the XDP program should be + // attached. + // +required + InterfaceName string `json:"interfaceName"` + + // netnsPath is the path to the network namespace inside of which the XDP + // program should be attached. + // +required + NetnsPath string `json:"netnsPath"` + + // priority is the provisioned 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. + // +required + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1000 + Priority int32 `json:"priority"` + + // proceedOn is the provisioned list of proceedOn values. proceedOn allows the + // user to call other TC programs in a chain, or not call the next program in a + // chain based on the exit code of a TC program .Multiple values are supported. + // +required + ProceedOn []XdpProceedOnValue `json:"proceedOn"` +} diff --git a/bpfman-operator/apis/v1alpha1/zz_generated.deepcopy.go b/bpfman-operator/apis/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..48d1c7e48d8 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,1964 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2025 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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AttachInfoStateCommon) DeepCopyInto(out *AttachInfoStateCommon) { + *out = *in + if in.LinkId != nil { + in, out := &in.LinkId, &out.LinkId + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttachInfoStateCommon. +func (in *AttachInfoStateCommon) DeepCopy() *AttachInfoStateCommon { + if in == nil { + return nil + } + out := new(AttachInfoStateCommon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfAppCommon) DeepCopyInto(out *BpfAppCommon) { + *out = *in + in.NodeSelector.DeepCopyInto(&out.NodeSelector) + if in.GlobalData != nil { + in, out := &in.GlobalData, &out.GlobalData + *out = make(map[string][]byte, len(*in)) + for key, val := range *in { + var outVal []byte + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = make([]byte, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } + in.ByteCode.DeepCopyInto(&out.ByteCode) + if in.MapOwnerSelector != nil { + in, out := &in.MapOwnerSelector, &out.MapOwnerSelector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfAppCommon. +func (in *BpfAppCommon) DeepCopy() *BpfAppCommon { + if in == nil { + return nil + } + out := new(BpfAppCommon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfAppStatus) DeepCopyInto(out *BpfAppStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfAppStatus. +func (in *BpfAppStatus) DeepCopy() *BpfAppStatus { + if in == nil { + return nil + } + out := new(BpfAppStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplication) DeepCopyInto(out *BpfApplication) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplication. +func (in *BpfApplication) DeepCopy() *BpfApplication { + if in == nil { + return nil + } + out := new(BpfApplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BpfApplication) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationList) DeepCopyInto(out *BpfApplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]BpfApplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationList. +func (in *BpfApplicationList) DeepCopy() *BpfApplicationList { + if in == nil { + return nil + } + out := new(BpfApplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BpfApplicationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationProgram) DeepCopyInto(out *BpfApplicationProgram) { + *out = *in + if in.XDP != nil { + in, out := &in.XDP, &out.XDP + *out = new(XdpProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.TC != nil { + in, out := &in.TC, &out.TC + *out = new(TcProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.TCX != nil { + in, out := &in.TCX, &out.TCX + *out = new(TcxProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.UProbe != nil { + in, out := &in.UProbe, &out.UProbe + *out = new(UprobeProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.URetProbe != nil { + in, out := &in.URetProbe, &out.URetProbe + *out = new(UprobeProgramInfo) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationProgram. +func (in *BpfApplicationProgram) DeepCopy() *BpfApplicationProgram { + if in == nil { + return nil + } + out := new(BpfApplicationProgram) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationProgramState) DeepCopyInto(out *BpfApplicationProgramState) { + *out = *in + in.BpfProgramStateCommon.DeepCopyInto(&out.BpfProgramStateCommon) + if in.XDP != nil { + in, out := &in.XDP, &out.XDP + *out = new(XdpProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.TC != nil { + in, out := &in.TC, &out.TC + *out = new(TcProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.TCX != nil { + in, out := &in.TCX, &out.TCX + *out = new(TcxProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.UProbe != nil { + in, out := &in.UProbe, &out.UProbe + *out = new(UprobeProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.URetProbe != nil { + in, out := &in.URetProbe, &out.URetProbe + *out = new(UprobeProgramInfoState) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationProgramState. +func (in *BpfApplicationProgramState) DeepCopy() *BpfApplicationProgramState { + if in == nil { + return nil + } + out := new(BpfApplicationProgramState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationSpec) DeepCopyInto(out *BpfApplicationSpec) { + *out = *in + in.BpfAppCommon.DeepCopyInto(&out.BpfAppCommon) + if in.Programs != nil { + in, out := &in.Programs, &out.Programs + *out = make([]BpfApplicationProgram, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationSpec. +func (in *BpfApplicationSpec) DeepCopy() *BpfApplicationSpec { + if in == nil { + return nil + } + out := new(BpfApplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationState) DeepCopyInto(out *BpfApplicationState) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationState. +func (in *BpfApplicationState) DeepCopy() *BpfApplicationState { + if in == nil { + return nil + } + out := new(BpfApplicationState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BpfApplicationState) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationStateList) DeepCopyInto(out *BpfApplicationStateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]BpfApplicationState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationStateList. +func (in *BpfApplicationStateList) DeepCopy() *BpfApplicationStateList { + if in == nil { + return nil + } + out := new(BpfApplicationStateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BpfApplicationStateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfApplicationStateStatus) DeepCopyInto(out *BpfApplicationStateStatus) { + *out = *in + if in.Programs != nil { + in, out := &in.Programs, &out.Programs + *out = make([]BpfApplicationProgramState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfApplicationStateStatus. +func (in *BpfApplicationStateStatus) DeepCopy() *BpfApplicationStateStatus { + if in == nil { + return nil + } + out := new(BpfApplicationStateStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BpfProgramStateCommon) DeepCopyInto(out *BpfProgramStateCommon) { + *out = *in + if in.ProgramId != nil { + in, out := &in.ProgramId, &out.ProgramId + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BpfProgramStateCommon. +func (in *BpfProgramStateCommon) DeepCopy() *BpfProgramStateCommon { + if in == nil { + return nil + } + out := new(BpfProgramStateCommon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ByteCodeImage) DeepCopyInto(out *ByteCodeImage) { + *out = *in + if in.ImagePullSecret != nil { + in, out := &in.ImagePullSecret, &out.ImagePullSecret + *out = new(ImagePullSecretSelector) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ByteCodeImage. +func (in *ByteCodeImage) DeepCopy() *ByteCodeImage { + if in == nil { + return nil + } + out := new(ByteCodeImage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ByteCodeSelector) DeepCopyInto(out *ByteCodeSelector) { + *out = *in + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(ByteCodeImage) + (*in).DeepCopyInto(*out) + } + if in.Path != nil { + in, out := &in.Path, &out.Path + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ByteCodeSelector. +func (in *ByteCodeSelector) DeepCopy() *ByteCodeSelector { + if in == nil { + return nil + } + out := new(ByteCodeSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClBpfApplicationProgram) DeepCopyInto(out *ClBpfApplicationProgram) { + *out = *in + if in.XDP != nil { + in, out := &in.XDP, &out.XDP + *out = new(ClXdpProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.TC != nil { + in, out := &in.TC, &out.TC + *out = new(ClTcProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.TCX != nil { + in, out := &in.TCX, &out.TCX + *out = new(ClTcxProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.FEntry != nil { + in, out := &in.FEntry, &out.FEntry + *out = new(ClFentryProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.FExit != nil { + in, out := &in.FExit, &out.FExit + *out = new(ClFexitProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.KProbe != nil { + in, out := &in.KProbe, &out.KProbe + *out = new(ClKprobeProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.KRetProbe != nil { + in, out := &in.KRetProbe, &out.KRetProbe + *out = new(ClKretprobeProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.UProbe != nil { + in, out := &in.UProbe, &out.UProbe + *out = new(ClUprobeProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.URetProbe != nil { + in, out := &in.URetProbe, &out.URetProbe + *out = new(ClUprobeProgramInfo) + (*in).DeepCopyInto(*out) + } + if in.TracePoint != nil { + in, out := &in.TracePoint, &out.TracePoint + *out = new(ClTracepointProgramInfo) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClBpfApplicationProgram. +func (in *ClBpfApplicationProgram) DeepCopy() *ClBpfApplicationProgram { + if in == nil { + return nil + } + out := new(ClBpfApplicationProgram) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClBpfApplicationProgramState) DeepCopyInto(out *ClBpfApplicationProgramState) { + *out = *in + in.BpfProgramStateCommon.DeepCopyInto(&out.BpfProgramStateCommon) + if in.XDP != nil { + in, out := &in.XDP, &out.XDP + *out = new(ClXdpProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.TC != nil { + in, out := &in.TC, &out.TC + *out = new(ClTcProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.TCX != nil { + in, out := &in.TCX, &out.TCX + *out = new(ClTcxProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.FEntry != nil { + in, out := &in.FEntry, &out.FEntry + *out = new(ClFentryProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.FExit != nil { + in, out := &in.FExit, &out.FExit + *out = new(ClFexitProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.KProbe != nil { + in, out := &in.KProbe, &out.KProbe + *out = new(ClKprobeProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.KRetProbe != nil { + in, out := &in.KRetProbe, &out.KRetProbe + *out = new(ClKretprobeProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.UProbe != nil { + in, out := &in.UProbe, &out.UProbe + *out = new(ClUprobeProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.URetProbe != nil { + in, out := &in.URetProbe, &out.URetProbe + *out = new(ClUprobeProgramInfoState) + (*in).DeepCopyInto(*out) + } + if in.TracePoint != nil { + in, out := &in.TracePoint, &out.TracePoint + *out = new(ClTracepointProgramInfoState) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClBpfApplicationProgramState. +func (in *ClBpfApplicationProgramState) DeepCopy() *ClBpfApplicationProgramState { + if in == nil { + return nil + } + out := new(ClBpfApplicationProgramState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClBpfApplicationSpec) DeepCopyInto(out *ClBpfApplicationSpec) { + *out = *in + in.BpfAppCommon.DeepCopyInto(&out.BpfAppCommon) + if in.Programs != nil { + in, out := &in.Programs, &out.Programs + *out = make([]ClBpfApplicationProgram, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClBpfApplicationSpec. +func (in *ClBpfApplicationSpec) DeepCopy() *ClBpfApplicationSpec { + if in == nil { + return nil + } + out := new(ClBpfApplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClBpfApplicationStateStatus) DeepCopyInto(out *ClBpfApplicationStateStatus) { + *out = *in + if in.Programs != nil { + in, out := &in.Programs, &out.Programs + *out = make([]ClBpfApplicationProgramState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClBpfApplicationStateStatus. +func (in *ClBpfApplicationStateStatus) DeepCopy() *ClBpfApplicationStateStatus { + if in == nil { + return nil + } + out := new(ClBpfApplicationStateStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClContainerSelector) DeepCopyInto(out *ClContainerSelector) { + *out = *in + in.Pods.DeepCopyInto(&out.Pods) + if in.ContainerNames != nil { + in, out := &in.ContainerNames, &out.ContainerNames + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClContainerSelector. +func (in *ClContainerSelector) DeepCopy() *ClContainerSelector { + if in == nil { + return nil + } + out := new(ClContainerSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFentryAttachInfo) DeepCopyInto(out *ClFentryAttachInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFentryAttachInfo. +func (in *ClFentryAttachInfo) DeepCopy() *ClFentryAttachInfo { + if in == nil { + return nil + } + out := new(ClFentryAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFentryAttachInfoState) DeepCopyInto(out *ClFentryAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFentryAttachInfoState. +func (in *ClFentryAttachInfoState) DeepCopy() *ClFentryAttachInfoState { + if in == nil { + return nil + } + out := new(ClFentryAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFentryLoadInfo) DeepCopyInto(out *ClFentryLoadInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFentryLoadInfo. +func (in *ClFentryLoadInfo) DeepCopy() *ClFentryLoadInfo { + if in == nil { + return nil + } + out := new(ClFentryLoadInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFentryProgramInfo) DeepCopyInto(out *ClFentryProgramInfo) { + *out = *in + out.ClFentryLoadInfo = in.ClFentryLoadInfo + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClFentryAttachInfo, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFentryProgramInfo. +func (in *ClFentryProgramInfo) DeepCopy() *ClFentryProgramInfo { + if in == nil { + return nil + } + out := new(ClFentryProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFentryProgramInfoState) DeepCopyInto(out *ClFentryProgramInfoState) { + *out = *in + out.ClFentryLoadInfo = in.ClFentryLoadInfo + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClFentryAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFentryProgramInfoState. +func (in *ClFentryProgramInfoState) DeepCopy() *ClFentryProgramInfoState { + if in == nil { + return nil + } + out := new(ClFentryProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFexitAttachInfo) DeepCopyInto(out *ClFexitAttachInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFexitAttachInfo. +func (in *ClFexitAttachInfo) DeepCopy() *ClFexitAttachInfo { + if in == nil { + return nil + } + out := new(ClFexitAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFexitAttachInfoState) DeepCopyInto(out *ClFexitAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFexitAttachInfoState. +func (in *ClFexitAttachInfoState) DeepCopy() *ClFexitAttachInfoState { + if in == nil { + return nil + } + out := new(ClFexitAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFexitLoadInfo) DeepCopyInto(out *ClFexitLoadInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFexitLoadInfo. +func (in *ClFexitLoadInfo) DeepCopy() *ClFexitLoadInfo { + if in == nil { + return nil + } + out := new(ClFexitLoadInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFexitProgramInfo) DeepCopyInto(out *ClFexitProgramInfo) { + *out = *in + out.ClFexitLoadInfo = in.ClFexitLoadInfo + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClFexitAttachInfo, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFexitProgramInfo. +func (in *ClFexitProgramInfo) DeepCopy() *ClFexitProgramInfo { + if in == nil { + return nil + } + out := new(ClFexitProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClFexitProgramInfoState) DeepCopyInto(out *ClFexitProgramInfoState) { + *out = *in + out.ClFexitLoadInfo = in.ClFexitLoadInfo + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClFexitAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClFexitProgramInfoState. +func (in *ClFexitProgramInfoState) DeepCopy() *ClFexitProgramInfoState { + if in == nil { + return nil + } + out := new(ClFexitProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKprobeAttachInfo) DeepCopyInto(out *ClKprobeAttachInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKprobeAttachInfo. +func (in *ClKprobeAttachInfo) DeepCopy() *ClKprobeAttachInfo { + if in == nil { + return nil + } + out := new(ClKprobeAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKprobeAttachInfoState) DeepCopyInto(out *ClKprobeAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKprobeAttachInfoState. +func (in *ClKprobeAttachInfoState) DeepCopy() *ClKprobeAttachInfoState { + if in == nil { + return nil + } + out := new(ClKprobeAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKprobeProgramInfo) DeepCopyInto(out *ClKprobeProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClKprobeAttachInfo, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKprobeProgramInfo. +func (in *ClKprobeProgramInfo) DeepCopy() *ClKprobeProgramInfo { + if in == nil { + return nil + } + out := new(ClKprobeProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKprobeProgramInfoState) DeepCopyInto(out *ClKprobeProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClKprobeAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKprobeProgramInfoState. +func (in *ClKprobeProgramInfoState) DeepCopy() *ClKprobeProgramInfoState { + if in == nil { + return nil + } + out := new(ClKprobeProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKretprobeAttachInfo) DeepCopyInto(out *ClKretprobeAttachInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKretprobeAttachInfo. +func (in *ClKretprobeAttachInfo) DeepCopy() *ClKretprobeAttachInfo { + if in == nil { + return nil + } + out := new(ClKretprobeAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKretprobeAttachInfoState) DeepCopyInto(out *ClKretprobeAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKretprobeAttachInfoState. +func (in *ClKretprobeAttachInfoState) DeepCopy() *ClKretprobeAttachInfoState { + if in == nil { + return nil + } + out := new(ClKretprobeAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKretprobeProgramInfo) DeepCopyInto(out *ClKretprobeProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClKretprobeAttachInfo, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKretprobeProgramInfo. +func (in *ClKretprobeProgramInfo) DeepCopy() *ClKretprobeProgramInfo { + if in == nil { + return nil + } + out := new(ClKretprobeProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClKretprobeProgramInfoState) DeepCopyInto(out *ClKretprobeProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClKretprobeAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClKretprobeProgramInfoState. +func (in *ClKretprobeProgramInfoState) DeepCopy() *ClKretprobeProgramInfoState { + if in == nil { + return nil + } + out := new(ClKretprobeProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClNetworkNamespaceSelector) DeepCopyInto(out *ClNetworkNamespaceSelector) { + *out = *in + in.Pods.DeepCopyInto(&out.Pods) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClNetworkNamespaceSelector. +func (in *ClNetworkNamespaceSelector) DeepCopy() *ClNetworkNamespaceSelector { + if in == nil { + return nil + } + out := new(ClNetworkNamespaceSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcAttachInfo) DeepCopyInto(out *ClTcAttachInfo) { + *out = *in + in.InterfaceSelector.DeepCopyInto(&out.InterfaceSelector) + if in.NetworkNamespaces != nil { + in, out := &in.NetworkNamespaces, &out.NetworkNamespaces + *out = new(ClNetworkNamespaceSelector) + (*in).DeepCopyInto(*out) + } + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]TcProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcAttachInfo. +func (in *ClTcAttachInfo) DeepCopy() *ClTcAttachInfo { + if in == nil { + return nil + } + out := new(ClTcAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcAttachInfoState) DeepCopyInto(out *ClTcAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]TcProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcAttachInfoState. +func (in *ClTcAttachInfoState) DeepCopy() *ClTcAttachInfoState { + if in == nil { + return nil + } + out := new(ClTcAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcProgramInfo) DeepCopyInto(out *ClTcProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClTcAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcProgramInfo. +func (in *ClTcProgramInfo) DeepCopy() *ClTcProgramInfo { + if in == nil { + return nil + } + out := new(ClTcProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcProgramInfoState) DeepCopyInto(out *ClTcProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClTcAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcProgramInfoState. +func (in *ClTcProgramInfoState) DeepCopy() *ClTcProgramInfoState { + if in == nil { + return nil + } + out := new(ClTcProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcxAttachInfo) DeepCopyInto(out *ClTcxAttachInfo) { + *out = *in + in.InterfaceSelector.DeepCopyInto(&out.InterfaceSelector) + if in.NetworkNamespaces != nil { + in, out := &in.NetworkNamespaces, &out.NetworkNamespaces + *out = new(ClNetworkNamespaceSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcxAttachInfo. +func (in *ClTcxAttachInfo) DeepCopy() *ClTcxAttachInfo { + if in == nil { + return nil + } + out := new(ClTcxAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcxAttachInfoState) DeepCopyInto(out *ClTcxAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcxAttachInfoState. +func (in *ClTcxAttachInfoState) DeepCopy() *ClTcxAttachInfoState { + if in == nil { + return nil + } + out := new(ClTcxAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcxProgramInfo) DeepCopyInto(out *ClTcxProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClTcxAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcxProgramInfo. +func (in *ClTcxProgramInfo) DeepCopy() *ClTcxProgramInfo { + if in == nil { + return nil + } + out := new(ClTcxProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTcxProgramInfoState) DeepCopyInto(out *ClTcxProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClTcxAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTcxProgramInfoState. +func (in *ClTcxProgramInfoState) DeepCopy() *ClTcxProgramInfoState { + if in == nil { + return nil + } + out := new(ClTcxProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTracepointAttachInfo) DeepCopyInto(out *ClTracepointAttachInfo) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTracepointAttachInfo. +func (in *ClTracepointAttachInfo) DeepCopy() *ClTracepointAttachInfo { + if in == nil { + return nil + } + out := new(ClTracepointAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTracepointAttachInfoState) DeepCopyInto(out *ClTracepointAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTracepointAttachInfoState. +func (in *ClTracepointAttachInfoState) DeepCopy() *ClTracepointAttachInfoState { + if in == nil { + return nil + } + out := new(ClTracepointAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTracepointProgramInfo) DeepCopyInto(out *ClTracepointProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClTracepointAttachInfo, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTracepointProgramInfo. +func (in *ClTracepointProgramInfo) DeepCopy() *ClTracepointProgramInfo { + if in == nil { + return nil + } + out := new(ClTracepointProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClTracepointProgramInfoState) DeepCopyInto(out *ClTracepointProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClTracepointAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClTracepointProgramInfoState. +func (in *ClTracepointProgramInfoState) DeepCopy() *ClTracepointProgramInfoState { + if in == nil { + return nil + } + out := new(ClTracepointProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClUprobeAttachInfo) DeepCopyInto(out *ClUprobeAttachInfo) { + *out = *in + if in.Pid != nil { + in, out := &in.Pid, &out.Pid + *out = new(int32) + **out = **in + } + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = new(ClContainerSelector) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClUprobeAttachInfo. +func (in *ClUprobeAttachInfo) DeepCopy() *ClUprobeAttachInfo { + if in == nil { + return nil + } + out := new(ClUprobeAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClUprobeAttachInfoState) DeepCopyInto(out *ClUprobeAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) + if in.Pid != nil { + in, out := &in.Pid, &out.Pid + *out = new(int32) + **out = **in + } + if in.ContainerPid != nil { + in, out := &in.ContainerPid, &out.ContainerPid + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClUprobeAttachInfoState. +func (in *ClUprobeAttachInfoState) DeepCopy() *ClUprobeAttachInfoState { + if in == nil { + return nil + } + out := new(ClUprobeAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClUprobeProgramInfo) DeepCopyInto(out *ClUprobeProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClUprobeAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClUprobeProgramInfo. +func (in *ClUprobeProgramInfo) DeepCopy() *ClUprobeProgramInfo { + if in == nil { + return nil + } + out := new(ClUprobeProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClUprobeProgramInfoState) DeepCopyInto(out *ClUprobeProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClUprobeAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClUprobeProgramInfoState. +func (in *ClUprobeProgramInfoState) DeepCopy() *ClUprobeProgramInfoState { + if in == nil { + return nil + } + out := new(ClUprobeProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClXdpAttachInfo) DeepCopyInto(out *ClXdpAttachInfo) { + *out = *in + in.InterfaceSelector.DeepCopyInto(&out.InterfaceSelector) + if in.NetworkNamespaces != nil { + in, out := &in.NetworkNamespaces, &out.NetworkNamespaces + *out = new(ClNetworkNamespaceSelector) + (*in).DeepCopyInto(*out) + } + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]XdpProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClXdpAttachInfo. +func (in *ClXdpAttachInfo) DeepCopy() *ClXdpAttachInfo { + if in == nil { + return nil + } + out := new(ClXdpAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClXdpAttachInfoState) DeepCopyInto(out *ClXdpAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]XdpProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClXdpAttachInfoState. +func (in *ClXdpAttachInfoState) DeepCopy() *ClXdpAttachInfoState { + if in == nil { + return nil + } + out := new(ClXdpAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClXdpProgramInfo) DeepCopyInto(out *ClXdpProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClXdpAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClXdpProgramInfo. +func (in *ClXdpProgramInfo) DeepCopy() *ClXdpProgramInfo { + if in == nil { + return nil + } + out := new(ClXdpProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClXdpProgramInfoState) DeepCopyInto(out *ClXdpProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]ClXdpAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClXdpProgramInfoState. +func (in *ClXdpProgramInfoState) DeepCopy() *ClXdpProgramInfoState { + if in == nil { + return nil + } + out := new(ClXdpProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBpfApplication) DeepCopyInto(out *ClusterBpfApplication) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBpfApplication. +func (in *ClusterBpfApplication) DeepCopy() *ClusterBpfApplication { + if in == nil { + return nil + } + out := new(ClusterBpfApplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBpfApplication) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBpfApplicationList) DeepCopyInto(out *ClusterBpfApplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterBpfApplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBpfApplicationList. +func (in *ClusterBpfApplicationList) DeepCopy() *ClusterBpfApplicationList { + if in == nil { + return nil + } + out := new(ClusterBpfApplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBpfApplicationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBpfApplicationState) DeepCopyInto(out *ClusterBpfApplicationState) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBpfApplicationState. +func (in *ClusterBpfApplicationState) DeepCopy() *ClusterBpfApplicationState { + if in == nil { + return nil + } + out := new(ClusterBpfApplicationState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBpfApplicationState) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBpfApplicationStateList) DeepCopyInto(out *ClusterBpfApplicationStateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterBpfApplicationState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBpfApplicationStateList. +func (in *ClusterBpfApplicationStateList) DeepCopy() *ClusterBpfApplicationStateList { + if in == nil { + return nil + } + out := new(ClusterBpfApplicationStateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBpfApplicationStateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerSelector) DeepCopyInto(out *ContainerSelector) { + *out = *in + in.Pods.DeepCopyInto(&out.Pods) + if in.ContainerNames != nil { + in, out := &in.ContainerNames, &out.ContainerNames + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSelector. +func (in *ContainerSelector) DeepCopy() *ContainerSelector { + if in == nil { + return nil + } + out := new(ContainerSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImagePullSecretSelector) DeepCopyInto(out *ImagePullSecretSelector) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePullSecretSelector. +func (in *ImagePullSecretSelector) DeepCopy() *ImagePullSecretSelector { + if in == nil { + return nil + } + out := new(ImagePullSecretSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InterfaceDiscovery) DeepCopyInto(out *InterfaceDiscovery) { + *out = *in + if in.InterfaceAutoDiscovery != nil { + in, out := &in.InterfaceAutoDiscovery, &out.InterfaceAutoDiscovery + *out = new(bool) + **out = **in + } + if in.ExcludeInterfaces != nil { + in, out := &in.ExcludeInterfaces, &out.ExcludeInterfaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.AllowedInterfaces != nil { + in, out := &in.AllowedInterfaces, &out.AllowedInterfaces + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InterfaceDiscovery. +func (in *InterfaceDiscovery) DeepCopy() *InterfaceDiscovery { + if in == nil { + return nil + } + out := new(InterfaceDiscovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InterfaceSelector) DeepCopyInto(out *InterfaceSelector) { + *out = *in + if in.InterfacesDiscoveryConfig != nil { + in, out := &in.InterfacesDiscoveryConfig, &out.InterfacesDiscoveryConfig + *out = new(InterfaceDiscovery) + (*in).DeepCopyInto(*out) + } + if in.Interfaces != nil { + in, out := &in.Interfaces, &out.Interfaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PrimaryNodeInterface != nil { + in, out := &in.PrimaryNodeInterface, &out.PrimaryNodeInterface + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InterfaceSelector. +func (in *InterfaceSelector) DeepCopy() *InterfaceSelector { + if in == nil { + return nil + } + out := new(InterfaceSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkNamespaceSelector) DeepCopyInto(out *NetworkNamespaceSelector) { + *out = *in + in.Pods.DeepCopyInto(&out.Pods) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkNamespaceSelector. +func (in *NetworkNamespaceSelector) DeepCopy() *NetworkNamespaceSelector { + if in == nil { + return nil + } + out := new(NetworkNamespaceSelector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcAttachInfo) DeepCopyInto(out *TcAttachInfo) { + *out = *in + in.InterfaceSelector.DeepCopyInto(&out.InterfaceSelector) + in.NetworkNamespaces.DeepCopyInto(&out.NetworkNamespaces) + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]TcProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcAttachInfo. +func (in *TcAttachInfo) DeepCopy() *TcAttachInfo { + if in == nil { + return nil + } + out := new(TcAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcAttachInfoState) DeepCopyInto(out *TcAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]TcProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcAttachInfoState. +func (in *TcAttachInfoState) DeepCopy() *TcAttachInfoState { + if in == nil { + return nil + } + out := new(TcAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcProgramInfo) DeepCopyInto(out *TcProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]TcAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcProgramInfo. +func (in *TcProgramInfo) DeepCopy() *TcProgramInfo { + if in == nil { + return nil + } + out := new(TcProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcProgramInfoState) DeepCopyInto(out *TcProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]TcAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcProgramInfoState. +func (in *TcProgramInfoState) DeepCopy() *TcProgramInfoState { + if in == nil { + return nil + } + out := new(TcProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcxAttachInfo) DeepCopyInto(out *TcxAttachInfo) { + *out = *in + in.InterfaceSelector.DeepCopyInto(&out.InterfaceSelector) + in.NetworkNamespaces.DeepCopyInto(&out.NetworkNamespaces) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcxAttachInfo. +func (in *TcxAttachInfo) DeepCopy() *TcxAttachInfo { + if in == nil { + return nil + } + out := new(TcxAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcxAttachInfoState) DeepCopyInto(out *TcxAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcxAttachInfoState. +func (in *TcxAttachInfoState) DeepCopy() *TcxAttachInfoState { + if in == nil { + return nil + } + out := new(TcxAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcxProgramInfo) DeepCopyInto(out *TcxProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]TcxAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcxProgramInfo. +func (in *TcxProgramInfo) DeepCopy() *TcxProgramInfo { + if in == nil { + return nil + } + out := new(TcxProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TcxProgramInfoState) DeepCopyInto(out *TcxProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]TcxAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TcxProgramInfoState. +func (in *TcxProgramInfoState) DeepCopy() *TcxProgramInfoState { + if in == nil { + return nil + } + out := new(TcxProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UprobeAttachInfo) DeepCopyInto(out *UprobeAttachInfo) { + *out = *in + if in.Pid != nil { + in, out := &in.Pid, &out.Pid + *out = new(int32) + **out = **in + } + in.Containers.DeepCopyInto(&out.Containers) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UprobeAttachInfo. +func (in *UprobeAttachInfo) DeepCopy() *UprobeAttachInfo { + if in == nil { + return nil + } + out := new(UprobeAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UprobeAttachInfoState) DeepCopyInto(out *UprobeAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) + if in.Pid != nil { + in, out := &in.Pid, &out.Pid + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UprobeAttachInfoState. +func (in *UprobeAttachInfoState) DeepCopy() *UprobeAttachInfoState { + if in == nil { + return nil + } + out := new(UprobeAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UprobeProgramInfo) DeepCopyInto(out *UprobeProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]UprobeAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UprobeProgramInfo. +func (in *UprobeProgramInfo) DeepCopy() *UprobeProgramInfo { + if in == nil { + return nil + } + out := new(UprobeProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UprobeProgramInfoState) DeepCopyInto(out *UprobeProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]UprobeAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UprobeProgramInfoState. +func (in *UprobeProgramInfoState) DeepCopy() *UprobeProgramInfoState { + if in == nil { + return nil + } + out := new(UprobeProgramInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XdpAttachInfo) DeepCopyInto(out *XdpAttachInfo) { + *out = *in + in.InterfaceSelector.DeepCopyInto(&out.InterfaceSelector) + in.NetworkNamespaces.DeepCopyInto(&out.NetworkNamespaces) + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]XdpProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XdpAttachInfo. +func (in *XdpAttachInfo) DeepCopy() *XdpAttachInfo { + if in == nil { + return nil + } + out := new(XdpAttachInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XdpAttachInfoState) DeepCopyInto(out *XdpAttachInfoState) { + *out = *in + in.AttachInfoStateCommon.DeepCopyInto(&out.AttachInfoStateCommon) + if in.ProceedOn != nil { + in, out := &in.ProceedOn, &out.ProceedOn + *out = make([]XdpProceedOnValue, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XdpAttachInfoState. +func (in *XdpAttachInfoState) DeepCopy() *XdpAttachInfoState { + if in == nil { + return nil + } + out := new(XdpAttachInfoState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XdpProgramInfo) DeepCopyInto(out *XdpProgramInfo) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]XdpAttachInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XdpProgramInfo. +func (in *XdpProgramInfo) DeepCopy() *XdpProgramInfo { + if in == nil { + return nil + } + out := new(XdpProgramInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XdpProgramInfoState) DeepCopyInto(out *XdpProgramInfoState) { + *out = *in + if in.Links != nil { + in, out := &in.Links, &out.Links + *out = make([]XdpAttachInfoState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XdpProgramInfoState. +func (in *XdpProgramInfoState) DeepCopy() *XdpProgramInfoState { + if in == nil { + return nil + } + out := new(XdpProgramInfoState) + in.DeepCopyInto(out) + return out +} diff --git a/bpfman-operator/apis/v1alpha1/zz_generated.register.go b/bpfman-operator/apis/v1alpha1/zz_generated.register.go new file mode 100644 index 00000000000..8398936c140 --- /dev/null +++ b/bpfman-operator/apis/v1alpha1/zz_generated.register.go @@ -0,0 +1,76 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2025 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. +*/ + +// Code generated by register-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName specifies the group name used to register the objects. +const GroupName = "bpfman.io" + +// GroupVersion specifies the group and the version used to register the objects. +var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// SchemeGroupVersion is group version used to register these objects +// Deprecated: use GroupVersion instead. +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + // Deprecated: use Install instead + AddToScheme = localSchemeBuilder.AddToScheme + Install = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) +} + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &BpfApplication{}, + &BpfApplicationList{}, + &BpfApplicationState{}, + &BpfApplicationStateList{}, + &ClusterBpfApplication{}, + &ClusterBpfApplicationList{}, + &ClusterBpfApplicationState{}, + &ClusterBpfApplicationStateList{}, + ) + // AddToGroupVersion allows the serialization of client types like ListOptions. + v1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +}