Browse code

libnetwork: add FlushChain methods for improved iptables management

Signed-off-by: Andrey Epifanov <aepifanov@mirantis.com>

Andrey Epifanov authored on 2025/05/29 18:16:20
Showing 2 changed files
... ...
@@ -396,6 +396,14 @@ func (iptable IPTable) ExistChain(chain string, table Table) bool {
396 396
 	return err == nil
397 397
 }
398 398
 
399
+// FlushChain flush chain if it exists
400
+func (iptable IPTable) FlushChain(table Table, chain string) error {
401
+	if !iptable.ExistChain(chain, table) {
402
+		return nil
403
+	}
404
+	return iptable.RawCombinedOutput("-t", string(table), "-F", chain)
405
+}
406
+
399 407
 // SetDefaultPolicy sets the passed default policy for the table/chain
400 408
 func (iptable IPTable) SetDefaultPolicy(table Table, chain string, policy Policy) error {
401 409
 	if err := iptable.RawCombinedOutput("-t", string(table), "-P", chain, string(policy)); err != nil {
... ...
@@ -3,6 +3,7 @@
3 3
 package iptables
4 4
 
5 5
 import (
6
+	"fmt"
6 7
 	"net"
7 8
 	"net/netip"
8 9
 	"os/exec"
... ...
@@ -308,3 +309,38 @@ func mustDumpChain(t *testing.T, table Table, chain string) string {
308 308
 	assert.NilError(t, err, "output:\n%s", out)
309 309
 	return string(out)
310 310
 }
311
+
312
+func TestFlushChain(t *testing.T) {
313
+	_ = firewalldInit()
314
+	if UsingFirewalld() {
315
+		t.Skip("firewalld in host netns cannot create rules in the test's netns")
316
+	}
317
+	defer netnsutils.SetupTestOSContext(t)()
318
+
319
+	iptable := GetIptable(IPv4)
320
+	chain := "TESTFLUSHCHAIN"
321
+	table := Filter
322
+
323
+	// Ensure the chain exists
324
+	assert.NilError(t, iptable.RemoveExistingChain(chain, table))
325
+	_, err := iptable.NewChain(chain, table)
326
+	assert.NilError(t, err)
327
+
328
+	// Add a rule to the chain
329
+	rule := Rule{IPVer: IPv4, Table: table, Chain: chain,
330
+		Args: []string{"-j", "ACCEPT"}}
331
+	assert.NilError(t, rule.Insert())
332
+
333
+	// Flush the chain
334
+	assert.NilError(t, iptable.FlushChain(table, chain))
335
+
336
+	// Check that the chain exists and is empty (only the chain definition remains)
337
+	out, err := exec.Command("iptables", "-t", string(table), "-S", chain).CombinedOutput()
338
+	assert.NilError(t, err)
339
+
340
+	rulesCount := strings.Count(string(out), fmt.Sprintf("-A %s ", chain))
341
+	assert.Check(t, rulesCount == 0)
342
+
343
+	// Cleanup
344
+	_ = iptable.RemoveExistingChain(chain, table)
345
+}