Skip to content

Conversation

@aojea
Copy link
Contributor

@aojea aojea commented Oct 19, 2025

Add a new ConntrackDelete() function that operates directly on flows, same as the ConntrackCreate() and ConntrackUpdate() functions.

We already have ConntrackDeleteFilters() that is very useful to batch operations and to express the intent based on filter matches, but having the function that operate on flows allow to create much more complex filtering.

Summary by CodeRabbit

  • New Features

    • Add ability to delete connection-tracking flows for both IPv4 and IPv6 via the public API, following existing create/update patterns.
    • Conntrack flow handling now includes zone attribute support when present.
  • Tests

    • Add tests covering IPv4 and IPv6 conntrack deletion workflows, validating create/list/delete and cleanup in isolated network namespaces.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Oct 19, 2025

Walkthrough

Adds package-level and Handle methods to delete conntrack flows via netlink (ConntrackDelete), extends ConntrackFlow serialization to include CTA_ZONE when Zone != 0, and adds IPv4/IPv6 tests that create a flow, delete it, and verify removal.

Changes

Cohort / File(s) Change Summary
Conntrack delete API & implementation
conntrack_linux.go
Added func ConntrackDelete(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error and func (h *Handle) ConntrackDelete(...) error which build a netlink CT_DELETE request, serialize ConntrackFlow to netlink attributes (now including CTA_ZONE when Zone != 0), attach attributes, send via the handle, and propagate errors.
Conntrack delete tests (IPv4 & IPv6)
conntrack_test.go
Added TestConntrackDeleteV4 and TestConntrackDeleteV6 that create a conntrack entry, assert presence, call deletion via the package/handle path, and assert the entry is removed; tests include kernel-module checks and per-test network namespace setup/teardown.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant PackageAPI as ConntrackDelete()
    participant Handle as Handle.ConntrackDelete()
    participant Netlink as Netlink Socket

    User->>PackageAPI: ConntrackDelete(table, family, flow)
    PackageAPI->>Handle: pkgHandle.ConntrackDelete(table, family, flow)

    Handle->>Handle: build CT_DELETE netlink message
    Note right of Handle: serialize ConntrackFlow -> netlink attrs\n(include CTA_ZONE if Zone != 0)
    Handle->>Netlink: send CT_DELETE with attrs

    alt success
        Netlink-->>Handle: ACK/OK
        Handle-->>PackageAPI: nil
    else error
        Netlink-->>Handle: error
        Handle-->>PackageAPI: error
    end

    PackageAPI-->>User: return
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review netlink attribute encoding for ConntrackFlow, especially CTA_ZONE placement and types.
  • Verify CT_DELETE message type/flags and error propagation.
  • Inspect new tests for correct namespace isolation, module loading guards, and cleanup.

Possibly related PRs

Poem

🐰 I hop through sockets, keen and fleet,

I spot a flow and make it meet defeat,
I tuck a zone into my netlink tweet,
IPv4 or v6—gone in a beat,
I munch a clover to celebrate sweet.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title 'add ConntrackDelete command' clearly and concisely summarizes the main change in the pull request: adding a new ConntrackDelete function to the netlink package.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
conntrack_test.go (2)

1501-1609: Misleading comment and unnecessary pkgHandle swap.

The comment states that deletion is "via the package-level wrapper ConntrackDelete (which uses pkgHandle)" but Line 1595 calls h.ConntrackDelete directly (the handle method). The pkgHandle swap at lines 1533-1535 is therefore unused and misleading.

Either:

  • Update the comment to state deletion is via the handle method, and remove the pkgHandle swap (lines 1533-1535), or
  • Call ConntrackDelete(ConntrackTable, InetFamily(nl.FAMILY_V4), &flow) instead at Line 1595 to actually use the package-level wrapper

Other tests in this file (e.g., TestConntrackCreateV4) consistently call handle methods directly without swapping pkgHandle, so the first option aligns better with existing patterns.

Apply this diff to align with existing test patterns:

-// TestConntrackDeleteV4 creates an IPv4 conntrack entry, verifies it exists,
-// deletes it via the package-level wrapper ConntrackDelete (which uses pkgHandle),
-// and verifies it was removed.
+// TestConntrackDeleteV4 creates an IPv4 conntrack entry, verifies it exists,
+// deletes it via the handle method, and verifies it was removed.
 func TestConntrackDeleteV4(t *testing.T) {
 	// Print timestamps in UTC
 	os.Setenv("TZ", "")
@@ -1530,10 +1530,6 @@
 		t.Fatalf("failed to create netlink handle: %s", err)
 	}
 
-	// Point pkgHandle to the namespaced handle so the package-level wrapper acts in this ns.
-	orig := pkgHandle
-	pkgHandle = h
-	defer func() { pkgHandle = orig }()
-
 	flow := ConntrackFlow{
 		FamilyType: FAMILY_V4,

1611-1719: Same issue: misleading comment and unnecessary pkgHandle swap.

Same issue as TestConntrackDeleteV4. The comment claims the package-level wrapper is used but Line 1705 calls h.ConntrackDelete directly. The pkgHandle swap at lines 1643-1645 is unused.

Apply this diff:

-// TestConntrackDeleteV6 creates an IPv6 conntrack entry, verifies it exists,
-// deletes it via the package-level wrapper ConntrackDelete (which uses pkgHandle),
-// and verifies it was removed.
+// TestConntrackDeleteV6 creates an IPv6 conntrack entry, verifies it exists,
+// deletes it via the handle method, and verifies it was removed.
 func TestConntrackDeleteV6(t *testing.T) {
 	// Print timestamps in UTC
 	os.Setenv("TZ", "")
@@ -1639,10 +1639,6 @@
 		t.Fatalf("failed to create netlink handle: %s", err)
 	}
 
-	// Point pkgHandle to the namespaced handle so the package-level wrapper acts in this ns.
-	orig := pkgHandle
-	pkgHandle = h
-	defer func() { pkgHandle = orig }()
-
 	flow := ConntrackFlow{
 		FamilyType: FAMILY_V6,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19840db and a0ec4a9.

📒 Files selected for processing (2)
  • conntrack_linux.go (2 hunks)
  • conntrack_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
conntrack_linux.go (3)
conntrack_unspecified.go (3)
  • ConntrackTableType (7-7)
  • InetFamily (10-10)
  • ConntrackFlow (13-13)
handle_linux.go (1)
  • Handle (24-27)
nl/conntrack_linux.go (1)
  • IPCTNL_MSG_CT_DELETE (68-68)
conntrack_test.go (8)
netlink_test.go (1)
  • KernelVersion (290-308)
handle_linux.go (1)
  • NewHandleAt (139-141)
nl/nl_linux.go (2)
  • FAMILY_V4 (25-25)
  • FAMILY_V6 (26-26)
conntrack_linux.go (18)
  • ConntrackFlow (321-332)
  • IPTuple (279-287)
  • ProtoInfo (242-244)
  • ProtoInfoTCP (248-250)
  • ProtoInfoTCP (253-253)
  • ConntrackCreate (64-66)
  • ConntrackTable (22-22)
  • ConntrackTableList (51-53)
  • ConntrackFilter (767-773)
  • ConntrackFilterType (744-744)
  • ConntrackOrigSrcIP (747-747)
  • ConntrackOrigDstIP (748-748)
  • ConntrackReplySrcIP (749-749)
  • ConntrackReplyDstIP (750-750)
  • ConntrackOrigSrcPort (752-752)
  • ConntrackOrigDstPort (753-753)
  • ConntrackDelete (76-78)
  • InetFamily (34-34)
conntrack_unspecified.go (4)
  • ConntrackFlow (13-13)
  • ConntrackTableList (23-25)
  • ConntrackFilter (19-19)
  • InetFamily (10-10)
nl/tc_linux.go (1)
  • IPPROTO_TCP (1247-1247)
nl/conntrack_linux.go (1)
  • TCP_CONNTRACK_ESTABLISHED (38-38)
netlink.go (1)
  • NewIPNet (35-40)
🔇 Additional comments (2)
conntrack_linux.go (2)

74-78: LGTM!

The package-level function follows the established pattern of ConntrackCreate and ConntrackUpdate, correctly delegating to the handle method.


157-172: LGTM!

The implementation correctly follows the pattern of ConntrackCreate and ConntrackUpdate, using the appropriate IPCTNL_MSG_CT_DELETE operation. Reusing flow.toNlData() is appropriate since the flow tuple identifies which entry to delete.

@aojea
Copy link
Contributor Author

aojea commented Oct 19, 2025

/assign @aboch

This is the primitive that was missing, similar to the conntrack userspace tool, and I'm running into scenarios that relying on filters make the code very complex, this allows to do more complex filtering of conntrack entries without having to rely on custom filters

The test failing does not look related

=== RUN   TestXfrmStateWithPcpunumWithSADir
    xfrm_state_linux_test.go:305: invalid argument: Invalid attribute SA_PCPU
--- FAIL: TestXfrmStateWithPcpunumWithSADir (0.00s)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
conntrack_linux.go (1)

157-172: Harden delete: align family, include zone, and treat not-found as success

  • Align flow.FamilyType with passed family to avoid mismatches.
  • Include CTA_ZONE when set to delete flows in non-default zones.
  • Mirror ConntrackDeleteFilters semantics: fs.ErrNotExist should be non-fatal.

Apply:

 func (h *Handle) ConntrackDelete(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
-	req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
-	attr, err := flow.toNlData()
+	req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
+	// Ensure flow family matches header family without mutating caller's flow.
+	tmp := *flow
+	if tmp.FamilyType == 0 {
+		tmp.FamilyType = uint8(family)
+	} else if tmp.FamilyType != uint8(family) {
+		return fmt.Errorf("family mismatch: flow.FamilyType=%d, arg=%d", tmp.FamilyType, family)
+	}
+	attr, err := tmp.toNlData()
 	if err != nil {
 		return err
 	}
 
 	for _, a := range attr {
 		req.AddData(a)
 	}
 
-	_, err = req.Execute(unix.NETLINK_NETFILTER, 0)
-	return err
+	// Include zone when set to target zone-specific entries.
+	if tmp.Zone != 0 {
+		req.AddData(nl.NewRtAttr(nl.CTA_ZONE, nl.BEUint16Attr(tmp.Zone)))
+	}
+
+	_, err = req.Execute(unix.NETLINK_NETFILTER, 0)
+	if err != nil && errors.Is(err, fs.ErrNotExist) {
+		// Be idempotent and consistent with ConntrackDeleteFilters.
+		return nil
+	}
+	return err
 }

Please confirm tests for zoned entries (non-zero zone) pass after this change. If helpful, I can add a focused test for delete-in-zone.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a0ec4a9 and 95ea400.

📒 Files selected for processing (2)
  • conntrack_linux.go (2 hunks)
  • conntrack_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • conntrack_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
conntrack_linux.go (3)
conntrack_unspecified.go (3)
  • ConntrackTableType (7-7)
  • InetFamily (10-10)
  • ConntrackFlow (13-13)
handle_linux.go (1)
  • Handle (24-27)
nl/conntrack_linux.go (1)
  • IPCTNL_MSG_CT_DELETE (68-68)
🔇 Additional comments (1)
conntrack_linux.go (1)

74-79: Wrapper looks good

Delegates to pkgHandle consistently with Create/Update; naming and CLI comment align with existing style.

@aboch
Copy link
Collaborator

aboch commented Oct 26, 2025

@aojea Please remove "feat: " from the commit message

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
conntrack_linux.go (1)

74-79: Doc nit: drop “using the handle” for pkg-level API.

Align wording with Create/Update comments.

-// ConntrackDelete deletes an existing conntrack flow in the desired table using the handle
+// ConntrackDelete deletes an existing conntrack flow in the desired table
 // conntrack -D [table]		Delete conntrack flow
 func ConntrackDelete(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
 	return pkgHandle.ConntrackDelete(table, family, flow)
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95ea400 and 448b3ca.

📒 Files selected for processing (2)
  • conntrack_linux.go (2 hunks)
  • conntrack_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • conntrack_test.go
🧰 Additional context used
🧬 Code graph analysis (1)
conntrack_linux.go (3)
conntrack_unspecified.go (3)
  • ConntrackTableType (7-7)
  • InetFamily (10-10)
  • ConntrackFlow (13-13)
handle_linux.go (1)
  • Handle (24-27)
nl/conntrack_linux.go (1)
  • IPCTNL_MSG_CT_DELETE (68-68)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
conntrack_test.go (2)

1624-1732: Test description is misleading and contains unnecessary code (same issue as V4 test).

Same issues as TestConntrackDeleteV4: the comment claims to test the package-level wrapper but actually uses h.ConntrackDelete() at line 1718, making the pkgHandle manipulation at lines 1656-1658 unnecessary.

Apply the same fix as suggested for TestConntrackDeleteV4.


1624-1732: Add test coverage for non-zero zones (same gap as V4 test).

Same as TestConntrackDeleteV4, this test should include a case with Zone != 0 to ensure zone-specific deletes work correctly.

conntrack_linux.go (1)

157-172: Zone field is not serialized, breaking non-zero zone deletes.

Based on learnings, ConntrackDelete is designed to allow flexible matching on any combination of fields, but the Zone field is never serialized by toNlData() (lines 357-443). When a user specifies flow.Zone != 0 to delete a flow in a specific zone, the zone attribute won't be sent in the netlink request, causing the delete to fail or match the wrong flow.

Apply this diff to add zone support:

 func (h *Handle) ConntrackDelete(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
 	req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
 	attr, err := flow.toNlData()
 	if err != nil {
 		return err
 	}
 
 	for _, a := range attr {
 		req.AddData(a)
 	}
+
+	if flow.Zone != 0 {
+		req.AddData(nl.NewRtAttr(nl.CTA_ZONE, nl.BEUint16Attr(flow.Zone)))
+	}
 
 	_, err = req.Execute(unix.NETLINK_NETFILTER, 0)
 	return err
 }
🧹 Nitpick comments (1)
conntrack_test.go (1)

1514-1732: Consider adding test coverage for the package-level ConntrackDelete wrapper.

Both tests use h.ConntrackDelete() directly. While the Handle method is the primary functionality, the package-level ConntrackDelete() function (lines 74-78 in conntrack_linux.go) is also untested. Consider adding a test that exercises the package-level API or modifying one of the existing tests to use ConntrackDelete() instead of h.ConntrackDelete() by properly setting up pkgHandle.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 448b3ca and e61d0c9.

📒 Files selected for processing (2)
  • conntrack_linux.go (2 hunks)
  • conntrack_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: aojea
Repo: vishvananda/netlink PR: 1134
File: conntrack_linux.go:157-173
Timestamp: 2025-11-23T11:16:08.391Z
Learning: In the netlink library's conntrack implementation, ConntrackDelete is designed to allow flexible matching where users can specify any combination of fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels) in the ConntrackFlow to match and delete flows. EINVAL or no-match errors simply indicate that no flow matching the specified criteria exists. This is intentional behavior, not a bug.
📚 Learning: 2025-11-23T11:16:08.391Z
Learnt from: aojea
Repo: vishvananda/netlink PR: 1134
File: conntrack_linux.go:157-173
Timestamp: 2025-11-23T11:16:08.391Z
Learning: In the netlink library's conntrack implementation, ConntrackDelete is designed to allow flexible matching where users can specify any combination of fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels) in the ConntrackFlow to match and delete flows. EINVAL or no-match errors simply indicate that no flow matching the specified criteria exists. This is intentional behavior, not a bug.

Applied to files:

  • conntrack_test.go
  • conntrack_linux.go
🧬 Code graph analysis (2)
conntrack_test.go (6)
netlink_test.go (1)
  • KernelVersion (290-308)
nl/nl_linux.go (2)
  • FAMILY_V4 (25-25)
  • FAMILY_V6 (26-26)
conntrack_linux.go (10)
  • ConntrackFlow (321-332)
  • IPTuple (279-287)
  • ProtoInfo (242-244)
  • ProtoInfoTCP (248-250)
  • ProtoInfoTCP (253-253)
  • ConntrackCreate (64-66)
  • ConntrackTable (22-22)
  • ConntrackTableList (51-53)
  • ConntrackDelete (76-78)
  • InetFamily (34-34)
conntrack_unspecified.go (3)
  • ConntrackFlow (13-13)
  • ConntrackTableList (23-25)
  • InetFamily (10-10)
nl/tc_linux.go (1)
  • IPPROTO_TCP (1247-1247)
netlink.go (1)
  • NewIPNet (35-40)
conntrack_linux.go (3)
conntrack_unspecified.go (3)
  • ConntrackTableType (7-7)
  • InetFamily (10-10)
  • ConntrackFlow (13-13)
handle_linux.go (1)
  • Handle (24-27)
nl/conntrack_linux.go (1)
  • IPCTNL_MSG_CT_DELETE (68-68)
🔇 Additional comments (1)
conntrack_linux.go (1)

74-78: LGTM - Package-level wrapper follows established pattern.

The implementation correctly delegates to pkgHandle.ConntrackDelete and mirrors the existing ConntrackCreate and ConntrackUpdate wrappers.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
conntrack_linux.go (1)

442-445: LGTM! Zone serialization correctly implemented.

The conditional serialization of CTA_ZONE when non-zero follows the established pattern and uses the correct attribute type and encoding. This addresses the zone support for delete operations.

Optionally, consider updating the comment block at lines 356-395 to document that CTA_ZONE is also included in the message structure when Zone != 0, for completeness.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 219bba2 and 5ae2171.

📒 Files selected for processing (1)
  • conntrack_linux.go (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: aojea
Repo: vishvananda/netlink PR: 1134
File: conntrack_linux.go:157-173
Timestamp: 2025-11-23T11:16:08.391Z
Learning: In the netlink library's conntrack implementation, ConntrackDelete is designed to allow flexible matching where users can specify any combination of fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels) in the ConntrackFlow to match and delete flows. EINVAL or no-match errors simply indicate that no flow matching the specified criteria exists. This is intentional behavior, not a bug.
📚 Learning: 2025-11-23T11:16:08.391Z
Learnt from: aojea
Repo: vishvananda/netlink PR: 1134
File: conntrack_linux.go:157-173
Timestamp: 2025-11-23T11:16:08.391Z
Learning: In the netlink library's conntrack implementation, ConntrackDelete is designed to allow flexible matching where users can specify any combination of fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels) in the ConntrackFlow to match and delete flows. EINVAL or no-match errors simply indicate that no flow matching the specified criteria exists. This is intentional behavior, not a bug.

Applied to files:

  • conntrack_linux.go
🧬 Code graph analysis (1)
conntrack_linux.go (4)
conntrack_unspecified.go (3)
  • ConntrackTableType (7-7)
  • InetFamily (10-10)
  • ConntrackFlow (13-13)
handle_linux.go (1)
  • Handle (24-27)
nl/conntrack_linux.go (2)
  • IPCTNL_MSG_CT_DELETE (68-68)
  • CTA_ZONE (124-124)
nl/nl_linux.go (2)
  • NewRtAttr (402-410)
  • BEUint16Attr (1020-1024)
🔇 Additional comments (2)
conntrack_linux.go (2)

74-78: LGTM! Package-level function follows established patterns.

The function correctly delegates to the handle and mirrors the design of ConntrackCreate and ConntrackUpdate.


157-172: LGTM! Implementation correctly supports flexible flow matching.

The method mirrors ConntrackCreate and ConntrackUpdate patterns and correctly uses flow.toNlData() to enable flexible matching on any combination of flow fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels, zone), as intended by design.

Based on learnings, this flexible matching approach allows users to specify any subset of fields to identify flows for deletion.

@aojea
Copy link
Contributor Author

aojea commented Nov 23, 2025

hi @aboch , once you have time I will ask you if you can prioritize this review, this patch will simplify a lot of the logic for handling conntrack deletion in kubernetes kubernetes/kubernetes#135399 (comment) that is causing performance issues due to the explosion of filters

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
conntrack_test.go (1)

1514-1621: Fix stale test description; delete logic and zone coverage look good.

The create/list/delete logic (including ctZone and zoneFilter) is solid and now properly exercises non‑zero zone behavior for both IPv4 and IPv6.

The comments at Lines 1514–1516 and 1623–1625 still say the tests delete via the package-level ConntrackDelete wrapper using pkgHandle, but the code actually calls h.ConntrackDelete(...) and never touches pkgHandle. That’s confusing for readers.

Consider updating the comments to reflect the actual behavior, e.g.:

-// TestConntrackDeleteV4 creates an IPv4 conntrack entry, verifies it exists,
-// deletes it via the package-level wrapper ConntrackDelete (which uses pkgHandle),
-// and verifies it was removed.
+// TestConntrackDeleteV4 creates an IPv4 conntrack entry, verifies it exists,
+// deletes it via Handle.ConntrackDelete, and verifies it was removed.
@@
-// TestConntrackDeleteV6 creates an IPv6 conntrack entry, verifies it exists,
-// deletes it via the package-level wrapper ConntrackDelete (which uses pkgHandle),
-// and verifies it was removed.
+// TestConntrackDeleteV6 creates an IPv6 conntrack entry, verifies it exists,
+// deletes it via Handle.ConntrackDelete, and verifies it was removed.

Also applies to: 1623-1730

🧹 Nitpick comments (1)
conntrack_linux.go (1)

74-79: Clarify package-level ConntrackDelete comment to match other wrappers.

The wrapper correctly delegates to pkgHandle.ConntrackDelete, consistent with the existing Create/Update functions. The comment, though, says “using the handle”, which is how the method variants are described.

For consistency with the other top-level wrappers, consider dropping the “using the handle” wording:

-// ConntrackDelete deletes an existing conntrack flow in the desired table using the handle
+// ConntrackDelete deletes an existing conntrack flow in the desired table.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ae2171 and 458a957.

📒 Files selected for processing (2)
  • conntrack_linux.go (4 hunks)
  • conntrack_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: aojea
Repo: vishvananda/netlink PR: 1134
File: conntrack_linux.go:157-173
Timestamp: 2025-11-23T11:16:08.391Z
Learning: In the netlink library's conntrack implementation, ConntrackDelete is designed to allow flexible matching where users can specify any combination of fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels) in the ConntrackFlow to match and delete flows. EINVAL or no-match errors simply indicate that no flow matching the specified criteria exists. This is intentional behavior, not a bug.
📚 Learning: 2025-11-23T11:16:08.391Z
Learnt from: aojea
Repo: vishvananda/netlink PR: 1134
File: conntrack_linux.go:157-173
Timestamp: 2025-11-23T11:16:08.391Z
Learning: In the netlink library's conntrack implementation, ConntrackDelete is designed to allow flexible matching where users can specify any combination of fields (forward tuple, reply tuple, mark, timeout, protoinfo, labels) in the ConntrackFlow to match and delete flows. EINVAL or no-match errors simply indicate that no flow matching the specified criteria exists. This is intentional behavior, not a bug.

Applied to files:

  • conntrack_test.go
  • conntrack_linux.go
🔇 Additional comments (2)
conntrack_linux.go (2)

157-172: Handle.ConntrackDelete implementation is consistent with Create/Update and flexible matching design.

This method mirrors ConntrackCreate/ConntrackUpdate: build a CT_DELETE request with the given family, serialize the provided flow via toNlData(), attach all attributes, and execute. That matches the intended design where callers can specify any combination of fields (tuples, mark, timeout, protoinfo, labels, zone) as the delete key, and rely on kernel matching semantics. Based on learnings, this behavior (including EINVAL/no-match when nothing matches) is correct and expected.

No changes needed here.


394-396: Zone serialization in ConntrackFlow.toNlData correctly completes zone support.

The added CTA_ZONE documentation and the conditional:

if s.Zone != 0 {
	ctZone := nl.NewRtAttr(nl.CTA_ZONE, nl.BEUint16Attr(s.Zone))
	payload = append(payload, ctZone)
}

ensure that non-zero Zone values are now serialized for create/update/delete, matching how parseRawData and ConntrackFlow.String() already handle zones. This brings the write path in line with the read/formatting behavior and allows ConntrackDelete to honor zone-based matching.

Looks good as implemented.

Also applies to: 444-447

Add a new ConntrackDelete() function that operates directly on flows,
same as the ConntrackCreate() and ConntrackUpdate() functions.

We already have ConntrackDeleteFilters() that is very useful to batch
operations and to express the intent based on filter matches, but having
the function that operate on flows allow to create much more complex
filtering without having to use an additional abstraction with filters.

Signed-off-by: Antonio Ojea <aojea@google.com>
this allows to use the zone for conntrack delete

Signed-off-by: Antonio Ojea <aojea@google.com>
@aojea aojea changed the title feat: add ConntrackDelete command add ConntrackDelete command Nov 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants