diff --git a/build/components/versions.yml b/build/components/versions.yml index 80a01cdc1d..512ffd8f97 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -3,7 +3,7 @@ firmware: libvirt: v10.9.0 edk2: stable202411 core: - 3p-kubevirt: v1.6.2-v12n.49 + 3p-kubevirt: feat/vm/disable-tap-veth-bridge 3p-containerized-data-importer: v1.60.3-v12n.20 distribution: 2.8.3 package: diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 0d75ebb629..8e3caa1121 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -13,8 +13,10 @@ secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} shell: + installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | + echo "$date rebuild 4" echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt @@ -28,6 +30,8 @@ altPackages: - pkg-config - libtool - gcc-c++ +- clang +- libbpf-devel packages: - libmnl - ncurses @@ -113,6 +117,7 @@ shell: - export GOOS=linux - export GOARCH=amd64 - export CGO_ENABLED=0 + - export BPF_CLANG=clang - echo ============== Build container-disk =================== {{- $_ := set $ "ProjectName" (list .ImageName "container-disk" | join "/") }} @@ -201,6 +206,13 @@ shell: - | {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/sidecars ./cmd/sidecars/`) | nindent 6 }} + - echo ============== Build bpf_bridge.o ===================== + {{- $_ := set $ "ProjectName" (list $.ImageName "bpf-bridge-obj" | join "/") }} + - mkdir -p /kubevirt-binaries/network-bpf-bridge-binding-assets + - | + {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./pkg/network/bpfbridge/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o`) | nindent 6 }} + - echo "Built bpf object:" && ls -l /kubevirt-binaries/network-bpf-bridge-binding-assets/ && file /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o || true + - echo ============== Build virtctl ========================== {{- $_ := set $ "ProjectName" (list .ImageName "virtctl" | join "/") }} - | diff --git a/images/virt-handler/werf.inc.yaml b/images/virt-handler/werf.inc.yaml index 760e013749..be325737b8 100644 --- a/images/virt-handler/werf.inc.yaml +++ b/images/virt-handler/werf.inc.yaml @@ -31,6 +31,12 @@ import: after: install includePaths: - .version +- image: {{ .ModuleNamePrefix }}virt-artifact + add: /kubevirt-binaries/network-bpf-bridge-binding-assets/ + to: /usr/share/network-bpf-bridge-binding + after: install + includePaths: + - bpf_bridge.o - image: {{ .ModuleNamePrefix }}virt-artifact add: /kubevirt/cmd/{{ .ImageName }}/ to: /etc diff --git a/images/virtualization-artifact/pkg/common/annotations/annotations.go b/images/virtualization-artifact/pkg/common/annotations/annotations.go index b72fa48663..2d3ab4e336 100644 --- a/images/virtualization-artifact/pkg/common/annotations/annotations.go +++ b/images/virtualization-artifact/pkg/common/annotations/annotations.go @@ -209,6 +209,8 @@ const ( AnnNetworksSpec = "network.deckhouse.io/networks-spec" // AnnNetworksStatus is the annotation for view current network configuration into Pod. AnnNetworksStatus = "network.deckhouse.io/networks-status" + // AnnTapProvisionByDVPSupported is the annotation that indicates DVP supports TAP provision for the Pod. + AnnTapProvisionByDVPSupported = "network.deckhouse.io/tap-provision-by-dvp-supported" // AnnVirtualDiskOriginalAnnotations is the annotation for storing original VirtualDisk annotations. AnnVirtualDiskOriginalAnnotations = AnnAPIGroupV + "/vd-original-annotations" diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index c03765de14..9a6d31f2e7 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -810,8 +810,9 @@ func (b *KVVM) SetNetworkInterface(name, macAddress string, acpiIndex int) { Name: name, Model: devPreset.InterfaceModel, ACPIIndex: acpiIndex, + Binding: &virtv1.PluginBinding{Name: "bpfbridge"}, } - iface.Bridge = &virtv1.InterfaceBridge{} + if macAddress != "" { iface.MacAddress = macAddress } diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go index 7c29d677fe..e71d4c5809 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -500,5 +500,10 @@ func setNetworksAnnotation(kvvm *KVVM, networkSpec network.InterfaceSpecList) er return err } kvvm.SetKVVMIAnnotation(annotations.AnnNetworksSpec, networkConfigStr) + // Signal that DVP provisions TAP devices natively (bpfbridge). Without this annotation + // SDN falls back to legacy tap+bridge wiring for additional interfaces, which conflicts + // with the bpfbridge binding and breaks L2 connectivity for VMs created with secondary + // networks from the start (as opposed to hotplugged later). + kvvm.SetKVVMIAnnotation(annotations.AnnTapProvisionByDVPSupported, "true") return nil } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go index a2de001ae5..21cb477af7 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -1176,7 +1176,8 @@ func (h *SyncKvvmHandler) patchPodNetworkAnnotation(ctx context.Context, s state return nil, fmt.Errorf("failed to serialize network spec: %w", err) } - if pod.Annotations[annotations.AnnNetworksSpec] == networkConfigStr { + if pod.Annotations[annotations.AnnNetworksSpec] == networkConfigStr && + pod.Annotations[annotations.AnnTapProvisionByDVPSupported] == "true" { return desired, nil } @@ -1185,6 +1186,7 @@ func (h *SyncKvvmHandler) patchPodNetworkAnnotation(ctx context.Context, s state pod.Annotations = make(map[string]string) } pod.Annotations[annotations.AnnNetworksSpec] = networkConfigStr + pod.Annotations[annotations.AnnTapProvisionByDVPSupported] = "true" if err := h.client.Patch(ctx, pod, patch); err != nil { return nil, fmt.Errorf("failed to patch pod %s network annotation: %w", pod.Name, err) } diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index 01d4228c8c..1d774a9c47 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -39,6 +39,11 @@ spec: {{- end }} evictionStrategy: LiveMigrate vmRolloutStrategy: LiveUpdate + network: + binding: + bpfbridge: + domainAttachmentType: tap + migration: {} developerConfiguration: logVerbosity: virtLauncher: {{ $logVerbosity }}