Skip to content

OCPBUGS-100110: Preserve conflist delegate config so DEL does not leak IPs - #336

Open
wizhaoredhat wants to merge 2 commits into
openshift:release-4.23from
wizhaoredhat:cherry_pick_OCPBUGS_94044
Open

OCPBUGS-100110: Preserve conflist delegate config so DEL does not leak IPs#336
wizhaoredhat wants to merge 2 commits into
openshift:release-4.23from
wizhaoredhat:cherry_pick_OCPBUGS_94044

Conversation

@wizhaoredhat

@wizhaoredhat wizhaoredhat commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Cherry pick of 6386911

Summary

This PR fixes an IP leak that occurs when a Multus delegate is a CNI conflist (plugins: [...]). On CMD_DEL, the delegate was invoked with a lossy copy of its configuration, so IPAM plugins that need CNI-specific fields (e.g. Calico, which needs kubeconfig/datastore_type to reach its datastore) failed to release the allocated IP. Over time, pod churn exhausts the IP pool.

Symptom

In a cluster using Calico as a Multus delegate (conflist form), we observed that IPs allocated on pod creation were never released on pod deletion. The delegate's DEL ran against an incomplete config, Calico IPAM could not authenticate to its datastore, and the IP allocation was orphaned. The pool slowly drained until new pods could no longer get an address.

Root cause

When loading a conflist delegate, LoadDelegateNetConfFromConfList stored DelegateNetConf.Bytes by marshaling the structured types.NetConfList (built from cnitypes.PluginConf):

pluginsBytes, err := json.Marshal(netConfList)

cnitypes.PluginConf only models a fixed subset of keys (cniVersion/name/type/capabilities/ipam.type/dns). Any other field — Calico's kubeconfig, datastore_type, and similar plugin-specific options — is silently dropped during that round-trip.

The same lossy marshal happened again on the DEL path in CmdDel, where the code backfilled cniVersion with:

v.Bytes, err = json.Marshal(v.ConfList)

So the config handed to the delegate's DEL was missing exactly the fields the plugin needs to clean up its IPAM state — hence the leak. (ADD happened to work in many setups because the on-disk conf was read more directly, masking the asymmetry.)

Fix

  1. Preserve the original conflist bytes losslessly. LoadDelegateNetConfFromConfList now rebuilds DelegateNetConf.Bytes from the libcni raw bytes via a new rawConfListBytes helper: it takes the list-level keys from confList.Bytes and rebuilds the plugins array from each plugin's own raw bytes. Per-plugin raw bytes are used (rather than confList.Bytes as a whole) because libcni appends plugins loaded from a subdirectory chain into confList.Plugins without updating confList.Bytes; relying on confList.Bytes alone would drop those appended plugins.

  2. Backfill cniVersion without data loss on DEL. CmdDel now uses a new InjectCNIVersionInConfList helper that unmarshals the raw conflist into a generic map, sets only cniVersion, and re-marshals — instead of marshaling the lossy structured NetConfList. DEL now receives the same complete config that ADD did.

  3. Remove the now-redundant representation. The CNINetworkConfigList libcni.NetworkConfigList field on DelegateNetConf is dropped, and conflistAdd is simplified to always parse from the (now-correct) raw bytes. This unifies ADD and DEL on a single source of truth — the lossless Bytes — and removes the duplicate config carried on the struct.

Testing

Added unit tests in pkg/types/conf_test.go:

  • LoadDelegateNetConfFromConfList preserves CNI-specific fields so DEL does not leak — verifies plugin-specific fields (e.g. kubeconfig/datastore_type) survive into DelegateNetConf.Bytes.
  • LoadDelegateNetConfFromConfList keeps plugins appended from a subdirectory chain — verifies plugins appended by libcni (not present in confList.Bytes) are retained.
  • InjectCNIVersionInConfList sets cniVersion without dropping fields — verifies cniVersion backfill is lossless.

Compatibility

No API or manifest changes. The fix only changes how delegate config bytes are reconstructed internally; delegates now receive the complete config on both ADD and DEL, which is the intended behavior.

A clusterNetwork loaded from a .conflist path was reconstructed via the
lossy cnitypes.PluginConf, dropping CNI-specific fields (calico's
kubeconfig/datastore_type/policy, etc). ADD survived by using the
complete CNINetworkConfigList, but DEL used the stripped Bytes, so
calico could not build its datastore client, never released the IP, and
leaked one address per teardown.

- LoadDelegateNetConfFromConfList: rebuild Bytes losslessly from the
  libcni raw bytes (per-plugin, covering subdirectory-chain plugins)
  instead of marshaling the lossy NetConfList; assign Bytes once after
  deviceID/cni-args injection (fixes deviceID-without-cni-args drop)
- collapse the redundant CNINetworkConfigList field; conflistAdd now
  uses Bytes uniformly, removing the dual source of truth and the TODO
- CmdDel: inject cniVersion onto raw Bytes via InjectCNIVersionInConfList
  instead of re-marshaling the lossy ConfList (second stripping point)
- add regression tests for field preservation, subdirectory-chain
  plugins, and cniVersion injection

Signed-off-by: Chen Tang <tangchen1234567@gmail.com>
CmdDel: do not clobber delegate Bytes when cniVersion injection
fails. Assign to a temporary and only overwrite on success, so DEL
keeps the original config instead of running with nil input, which
would risk leaking the IP.

Signed-off-by: Chen Tang <tangchen1234567@gmail.com>
@openshift-ci-robot openshift-ci-robot added jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 28, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@wizhaoredhat: This pull request references Jira Issue OCPBUGS-100110, which is invalid:

  • release note text must be set and not match the template OR release note type must be set to "Release Note Not Required". For more information you can reference the OpenShift Bug Process.
  • expected Jira Issue OCPBUGS-100110 to depend on a bug targeting a version in 5.0.0 and in one of the following states: MODIFIED, ON_QA, VERIFIED, but no dependents were found

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Cherry pick of 6386911

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cab1f35a-6df3-4b9c-ae9c-3b1089f158c8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@openshift-ci
openshift-ci Bot requested review from dougbtv and s1061123 July 28, 2026 20:57
@wizhaoredhat

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@wizhaoredhat: This pull request references Jira Issue OCPBUGS-100110, which is invalid:

  • release note text must be set and not match the template OR release note type must be set to "Release Note Not Required". For more information you can reference the OpenShift Bug Process.
  • expected dependent Jira Issue OCPBUGS-94044 to target a version in 5.0.0, but it targets "5.0" instead

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

/jira refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@wizhaoredhat

Copy link
Copy Markdown
Contributor Author

/approve

@wizhaoredhat

Copy link
Copy Markdown
Contributor Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added the jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. label Jul 28, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@wizhaoredhat: This pull request references Jira Issue OCPBUGS-100110, which is valid. The bug has been moved to the POST state.

7 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.23.0) matches configured target version for branch (4.23.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)
  • release note text is set and does not match the template
  • dependent bug Jira Issue OCPBUGS-94044 is in the state MODIFIED, which is one of the valid states (MODIFIED, ON_QA, VERIFIED)
  • dependent Jira Issue OCPBUGS-94044 targets the "5.0.0" version, which is one of the valid target versions: 5.0.0
  • bug has dependents
Details

In response to this:

/jira refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot removed the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Jul 28, 2026
@wizhaoredhat

Copy link
Copy Markdown
Contributor Author

/cherry-pick release-4.22

@openshift-cherrypick-robot

Copy link
Copy Markdown

@wizhaoredhat: once the present PR merges, I will cherry-pick it on top of release-4.22 in a new PR and assign it to you.

Details

In response to this:

/cherry-pick release-4.22

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci

openshift-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

@wizhaoredhat: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/security d928bf7 link false /test security

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@vinnie1110 vinnie1110 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 30, 2026
@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: vinnie1110, wizhaoredhat

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 30, 2026
@wizhaoredhat

Copy link
Copy Markdown
Contributor Author

Hold due to #338

@wizhaoredhat

Copy link
Copy Markdown
Contributor Author

/hold

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants