From c91e292b44dccccb5bd3cc0406178aaea85c7a60 Mon Sep 17 00:00:00 2001 From: Chris Tauchen Date: Fri, 21 Aug 2026 11:58:52 +0100 Subject: [PATCH 1/5] DOCS-2997: Point existing pages at L2 bridge networking Update five existing pages so they account for the new L2 bridge networking set. The KubeVirt networking page uses the word bridge for KubeVirt's interface binding mode, which is a different thing from an L2 bridge network. That page now says so, and its statement that live migration requires BGP without overlay is scoped to the pod network path it describes, since it does not hold for a VM on an L2 network. The pod MAC address and specific IP address pages documented the flat form of their annotations only. Both now cover the per-interface form. The MAC page also points at KubeVirt's own field, and notes that setting both to conflicting values is rejected. The IP address page explains why an L2 workload should use ipAddrs rather than ipAddrsNoIpam. The multiple networks page points Multus readers at the L2 path and at the additional installation setting it needs. The eBPF use cases page records L2 bridge networking as a consumer of the eBPF data plane, with its higher kernel requirement. Co-Authored-By: Claude Opus 5 (1M context) --- .../networking/configuring/multiple-networks.mdx | 5 +++++ .../networking/configuring/pod-mac-address.mdx | 10 ++++++++++ .../networking/ipam/use-specific-ip.mdx | 9 +++++++++ .../networking/kubevirt/kubevirt-networking.mdx | 15 +++++++++++++-- .../operations/ebpf/use-cases-ebpf.mdx | 5 +++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/calico-enterprise/networking/configuring/multiple-networks.mdx b/calico-enterprise/networking/configuring/multiple-networks.mdx index 6b8b056287..cec7e2f0a8 100644 --- a/calico-enterprise/networking/configuring/multiple-networks.mdx +++ b/calico-enterprise/networking/configuring/multiple-networks.mdx @@ -249,3 +249,8 @@ spec: - kns.default - ksa.default.default ``` + +## L2 bridge networks + +To attach a workload to one of your existing VLANs rather than to another routed network, see [L2 bridge networking](../l2-bridge/about-l2-bridge.mdx). +It uses Multus in the same way, and additionally requires `multiInterfaceMode: Multus` in the [Installation](../../reference/installation/api.mdx) resource. diff --git a/calico-enterprise/networking/configuring/pod-mac-address.mdx b/calico-enterprise/networking/configuring/pod-mac-address.mdx index bfed9fc5f0..329c127d34 100644 --- a/calico-enterprise/networking/configuring/pod-mac-address.mdx +++ b/calico-enterprise/networking/configuring/pod-mac-address.mdx @@ -33,3 +33,13 @@ Annotate the pod with cni.projectcalico.org/hwAddr set to the desired MAC addres ``` The annotation must be present when the pod is created; adding it later has no effect. + +## Setting the MAC address on other interfaces + +The annotation above applies to a pod's primary interface. +To set the MAC address on an additional interface, prefix the annotation with the interface name — for example, `cni.projectcalico.org/vlan10.hwAddr`. + +For a KubeVirt VM, prefer KubeVirt's own `macAddress` field on the interface. +$[prodname] honors it, and it keeps the setting with the rest of the interface configuration. +If you set both the field and the annotation, they must agree, or the interface is rejected. +See [Bring a VM over with its IP and MAC](../l2-bridge/vm-identity.mdx). diff --git a/calico-enterprise/networking/ipam/use-specific-ip.mdx b/calico-enterprise/networking/ipam/use-specific-ip.mdx index d1af18e8f4..d1adfd6771 100644 --- a/calico-enterprise/networking/ipam/use-specific-ip.mdx +++ b/calico-enterprise/networking/ipam/use-specific-ip.mdx @@ -63,3 +63,12 @@ tunnel address. To prevent this, there are several options: ## Additional resources For help configuring $[prodname] CNI and $[prodname] IPAM, see [Configuring the $[prodname] CNI Plugins](../../reference/component-resources/configuration.mdx). + +## Requesting an address on another interface + +The annotations above apply to a pod's primary interface. +To request an address on an additional interface, prefix the annotation with the interface name — for example, `cni.projectcalico.org/vlan10.ipAddrs`. + +For a workload on an [L2 bridge network](../l2-bridge/about-l2-bridge.mdx), use `ipAddrs` rather than `ipAddrsNoIpam`. +Bypassing IPAM leaves $[prodname] without a record of the address, and on an L2 network that record is what lets $[prodname] tell the workload's own traffic from spoofed traffic. +See [Bring a VM over with its IP and MAC](../l2-bridge/vm-identity.mdx). diff --git a/calico-enterprise/networking/kubevirt/kubevirt-networking.mdx b/calico-enterprise/networking/kubevirt/kubevirt-networking.mdx index 0691761388..71f2859c89 100644 --- a/calico-enterprise/networking/kubevirt/kubevirt-networking.mdx +++ b/calico-enterprise/networking/kubevirt/kubevirt-networking.mdx @@ -25,6 +25,14 @@ $[prodname]'s KubeVirt support ensures that: ### Supported networking mode: bridge +:::note + +The **bridge** on this page is KubeVirt's interface binding mode, which connects a VM to its own pod's interface on the $[prodname] pod network. +It is unrelated to [L2 bridge networking](../l2-bridge/about-l2-bridge.mdx), which puts workloads on your existing VLANs through a Linux bridge on the node. +The two features use the same word for different things. + +::: + $[prodname] supports KubeVirt live migration using the **bridge** binding mode. In bridge mode, the VM is connected to the pod network through a Linux bridge, and the VM uses the same IP address that $[prodname] assigns to the pod. This is required because: @@ -42,8 +50,11 @@ policy enforcement. ### BGP networking required -Live migration currently requires BGP networking without overlay. Overlay networking (VXLAN, IP-in-IP) -support is planned for a future release. +Live migration on the $[prodname] pod network, as described on this page, currently requires BGP networking without overlay. +Overlay networking (VXLAN, IP-in-IP) support is planned for a future release. + +This requirement applies to the pod network path only. +Live migration of a VM on an [L2 bridge network](../l2-bridge/about-l2-bridge.mdx) does not depend on BGP, because the VM's address is reachable on your own VLAN rather than routed by $[prodname]. ### KubeVirt VM IP address persistence diff --git a/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx b/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx index e88477bef3..1e2a3137b2 100644 --- a/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx +++ b/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx @@ -93,3 +93,8 @@ We believe the right solution is to leverage eBPF, along with existing mechanism ## Additional resources To learn more and see performance metrics from our test environment, see the blog, [Introducing the eBPF data plane](https://www.projectcalico.org/introducing-the-calico-ebpf-dataplane/). + +## L2 bridge networking + +[L2 bridge networking](../../networking/l2-bridge/about-l2-bridge.mdx) requires the eBPF data plane. +Enforcing policy on a bridged, VLAN-tagged segment is not possible with the iptables data plane, and the eBPF data plane also raises the minimum kernel version for that feature to 5.18. From 64d1973f869549299162cf3bb17ba54ee1e31d3e Mon Sep 17 00:00:00 2001 From: Chris Tauchen Date: Thu, 27 Aug 2026 13:51:01 +0100 Subject: [PATCH 2/5] DOCS-2997: Update the link text for the VM IP and MAC guide The page is retitled around the task it performs, because it serves both a VM migrating in with an existing address and a new VM that needs a fixed one. --- calico-enterprise/networking/configuring/pod-mac-address.mdx | 2 +- calico-enterprise/networking/ipam/use-specific-ip.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/calico-enterprise/networking/configuring/pod-mac-address.mdx b/calico-enterprise/networking/configuring/pod-mac-address.mdx index 329c127d34..c9f89cbdaa 100644 --- a/calico-enterprise/networking/configuring/pod-mac-address.mdx +++ b/calico-enterprise/networking/configuring/pod-mac-address.mdx @@ -42,4 +42,4 @@ To set the MAC address on an additional interface, prefix the annotation with th For a KubeVirt VM, prefer KubeVirt's own `macAddress` field on the interface. $[prodname] honors it, and it keeps the setting with the rest of the interface configuration. If you set both the field and the annotation, they must agree, or the interface is rejected. -See [Bring a VM over with its IP and MAC](../l2-bridge/vm-identity.mdx). +See [Set a VM's IP and MAC address](../l2-bridge/vm-identity.mdx). diff --git a/calico-enterprise/networking/ipam/use-specific-ip.mdx b/calico-enterprise/networking/ipam/use-specific-ip.mdx index d1adfd6771..09cdf0d06a 100644 --- a/calico-enterprise/networking/ipam/use-specific-ip.mdx +++ b/calico-enterprise/networking/ipam/use-specific-ip.mdx @@ -71,4 +71,4 @@ To request an address on an additional interface, prefix the annotation with the For a workload on an [L2 bridge network](../l2-bridge/about-l2-bridge.mdx), use `ipAddrs` rather than `ipAddrsNoIpam`. Bypassing IPAM leaves $[prodname] without a record of the address, and on an L2 network that record is what lets $[prodname] tell the workload's own traffic from spoofed traffic. -See [Bring a VM over with its IP and MAC](../l2-bridge/vm-identity.mdx). +See [Set a VM's IP and MAC address](../l2-bridge/vm-identity.mdx). From ba801a1d4c683ae266cdef57238883266a0af9fe Mon Sep 17 00:00:00 2001 From: Chris Tauchen Date: Thu, 27 Aug 2026 17:06:16 +0100 Subject: [PATCH 3/5] DOCS-2997: Add L2Workload to the IPPool allowed uses The IPPool CRD accepts L2Workload and the L2 bridge setup guide tells readers to create a pool with it, but the reference listed neither the value nor the combination, implying it was not legal. --- calico-enterprise/reference/resources/ippool.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/calico-enterprise/reference/resources/ippool.mdx b/calico-enterprise/reference/resources/ippool.mdx index ce5663ea81..f1c183e2ee 100644 --- a/calico-enterprise/reference/resources/ippool.mdx +++ b/calico-enterprise/reference/resources/ippool.mdx @@ -49,7 +49,7 @@ spec: | disabled | When set to true, $[prodname] IPAM will not assign addresses from this pool. | true, false | boolean | `false` | | disableBGPExport _(since v3.11.0)_ | Disable exporting routes from this IP Pool’s CIDR over BGP. | true, false | boolean | `false` | | nodeSelector | Selects the nodes where $[prodname] IPAM should assign pod addresses from this pool. Can be overridden if a pod [explicitly identifies this IP pool by annotation](../component-resources/configuration.mdx#using-kubernetes-annotations). | | [selector](#node-selector) | all() | -| allowedUses _(since v3.11.0)_ | Controls whether the pool will be used for automatic assignments of certain types. See [below](#allowed-uses). | Workload, Tunnel, HostSecondaryInterface, LoadBalancer | list of strings | `["Workload", "Tunnel"]` | +| allowedUses _(since v3.11.0)_ | Controls whether the pool will be used for automatic assignments of certain types. See [below](#allowed-uses). | Workload, Tunnel, HostSecondaryInterface, LoadBalancer, L2Workload | list of strings | `["Workload", "Tunnel"]` | | awsSubnetID _(since v3.11.0)_ | May be set to the ID of an AWS VPC Subnet that contains the CIDR of this IP pool to activate the AWS-backed pool feature. See [below](#aws-backed-pools). | Valid AWS Subnet ID. | string | | | assignmentMode | Controls whether the pool will be used for automatic assignments or only if requested manually | Automatic, Manual | strings | `Automatic` | @@ -73,6 +73,7 @@ Combining options for the `allowedUses` field is limited. You can specify only t * `allowedUses: ["Workload"]` * `allowedUses: ["LoadBalancer"]` * `allowedUses: ["HostSecondaryInterface"]` + * `allowedUses: ["L2Workload"]` If the `allowedUses` field is not specified, it defaults to `["Workload", "Tunnel"]` for compatibility with older versions of Calico. It is not possible to specify a pool with no allowed uses. From 777e704e4599128be9e6d696c7a7773b52f71996 Mon Sep 17 00:00:00 2001 From: Chris Tauchen Date: Thu, 27 Aug 2026 17:07:01 +0100 Subject: [PATCH 4/5] DOCS-2997: Keep Additional resources last on two pages The new L2 sections were appended after Additional resources, which reads as though the links belong to the section above them. --- calico-enterprise/networking/ipam/use-specific-ip.mdx | 8 ++++---- calico-enterprise/operations/ebpf/use-cases-ebpf.mdx | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/calico-enterprise/networking/ipam/use-specific-ip.mdx b/calico-enterprise/networking/ipam/use-specific-ip.mdx index 09cdf0d06a..f004544bdc 100644 --- a/calico-enterprise/networking/ipam/use-specific-ip.mdx +++ b/calico-enterprise/networking/ipam/use-specific-ip.mdx @@ -60,10 +60,6 @@ tunnel address. To prevent this, there are several options: - To prevent $[prodname] from using IPs from a certain pool for internal IPIP and/or VXLAN tunnel addresses, you can set the `allowedUses` field on the [IP Pool](../../reference/resources/ippool.mdx) to `["Workload"]`. -## Additional resources - -For help configuring $[prodname] CNI and $[prodname] IPAM, see [Configuring the $[prodname] CNI Plugins](../../reference/component-resources/configuration.mdx). - ## Requesting an address on another interface The annotations above apply to a pod's primary interface. @@ -72,3 +68,7 @@ To request an address on an additional interface, prefix the annotation with the For a workload on an [L2 bridge network](../l2-bridge/about-l2-bridge.mdx), use `ipAddrs` rather than `ipAddrsNoIpam`. Bypassing IPAM leaves $[prodname] without a record of the address, and on an L2 network that record is what lets $[prodname] tell the workload's own traffic from spoofed traffic. See [Set a VM's IP and MAC address](../l2-bridge/vm-identity.mdx). + +## Additional resources + +For help configuring $[prodname] CNI and $[prodname] IPAM, see [Configuring the $[prodname] CNI Plugins](../../reference/component-resources/configuration.mdx). diff --git a/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx b/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx index 1e2a3137b2..e865b40e6c 100644 --- a/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx +++ b/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx @@ -90,11 +90,11 @@ Is eBPF a replacement for iptables? Not exactly. It’s hard to imagine everythi We believe the right solution is to leverage eBPF, along with existing mechanisms in the Linux kernel, to achieve your desired outcome. That’s why $[prodname] offers support for multiple data planes, including standard Linux, Windows HNS, and Linux eBPF. Since we have established that both eBPF and iptables are useful, the only logical thing to do in our opinion is to support both. $[prodname] gives you the choice so you can choose the best tool for the job. -## Additional resources - -To learn more and see performance metrics from our test environment, see the blog, [Introducing the eBPF data plane](https://www.projectcalico.org/introducing-the-calico-ebpf-dataplane/). - ## L2 bridge networking [L2 bridge networking](../../networking/l2-bridge/about-l2-bridge.mdx) requires the eBPF data plane. Enforcing policy on a bridged, VLAN-tagged segment is not possible with the iptables data plane, and the eBPF data plane also raises the minimum kernel version for that feature to 5.18. + +## Additional resources + +To learn more and see performance metrics from our test environment, see the blog, [Introducing the eBPF data plane](https://www.projectcalico.org/introducing-the-calico-ebpf-dataplane/). From a69ec26742eea1e373a5a8e5275feb3d54277f7f Mon Sep 17 00:00:00 2001 From: Chris Tauchen Date: Thu, 27 Aug 2026 17:16:35 +0100 Subject: [PATCH 5/5] DOCS-2997: Explain L2Workload, and align the kernel statement Say what an L2Workload pool is for in the allowed uses section, rather than leaving readers to infer it from the value name. State the kernel requirement as the bridge port locked flag here too, so this page does not contradict the support reference. --- calico-enterprise/operations/ebpf/use-cases-ebpf.mdx | 2 +- calico-enterprise/reference/resources/ippool.mdx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx b/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx index e865b40e6c..9d3c55bc7b 100644 --- a/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx +++ b/calico-enterprise/operations/ebpf/use-cases-ebpf.mdx @@ -93,7 +93,7 @@ We believe the right solution is to leverage eBPF, along with existing mechanism ## L2 bridge networking [L2 bridge networking](../../networking/l2-bridge/about-l2-bridge.mdx) requires the eBPF data plane. -Enforcing policy on a bridged, VLAN-tagged segment is not possible with the iptables data plane, and the eBPF data plane also raises the minimum kernel version for that feature to 5.18. +Enforcing policy on a bridged, VLAN-tagged segment is not possible with the iptables data plane. That feature also needs a kernel supporting the bridge port `locked` flag, which arrived upstream in 5.18 and is backported by some distributions. ## Additional resources diff --git a/calico-enterprise/reference/resources/ippool.mdx b/calico-enterprise/reference/resources/ippool.mdx index f1c183e2ee..41873c8b40 100644 --- a/calico-enterprise/reference/resources/ippool.mdx +++ b/calico-enterprise/reference/resources/ippool.mdx @@ -66,6 +66,7 @@ IP pool by creating blocks of incorrect size. When automatically assigning IP addresses to workloads, only pools with "Workload" in their `allowedUses` field are consulted. Similarly, when assigning IPs for tunnel devices, only "Tunnel" pools are eligible. Finally, when assigning IP addresses for AWS secondary ENIs, only pools with allowed use "HostSecondaryInterface" are candidates. +Pools marked "L2Workload" are used for workloads attached to an [L2 bridge network](../../networking/l2-bridge/about-l2-bridge.mdx), whose addresses live on a VLAN outside the cluster rather than on the pod network. Marking a pool this way also stops $[prodname] programming a blackhole route for it and advertising it over BGP, neither of which is correct for those addresses. Combining options for the `allowedUses` field is limited. You can specify only the following options and option combinations: * `allowedUses: ["Tunnel","Workload"]` (default)