Skip to content

Commit

Permalink
Merge pull request #125 from olljanat/delete-by-id
Browse files Browse the repository at this point in the history
feat: add DeleteById function
  • Loading branch information
squeed authored Aug 27, 2024
2 parents 65c67c9 + 39ae37f commit 26e4251
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
6 changes: 6 additions & 0 deletions iptables/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ func (ipt *IPTables) DeleteIfExists(table, chain string, rulespec ...string) err
return err
}

// DeleteById deletes the rule with the specified ID in the given table and chain.
func (ipt *IPTables) DeleteById(table, chain string, id int) error {
cmd := []string{"-t", table, "-D", chain, strconv.Itoa(id)}
return ipt.run(cmd...)
}

// List rules in specified table/chain
func (ipt *IPTables) ListById(table, chain string, id int) (string, error) {
args := []string{"-t", table, "-S", chain, strconv.Itoa(id)}
Expand Down
35 changes: 34 additions & 1 deletion iptables/iptables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,17 +301,25 @@ func TestRules(t *testing.T) {
func runRulesTests(t *testing.T, ipt *IPTables) {
t.Logf("testing %s (hasWait=%t, hasCheck=%t)", getIptablesCommand(ipt.Proto()), ipt.hasWait, ipt.hasCheck)

var address1, address2, subnet1, subnet2 string
var address1, address2, address3, address4, subnet1, subnet2, subnet3, subnet4 string
if ipt.Proto() == ProtocolIPv6 {
address1 = "2001:db8::1/128"
address2 = "2001:db8::2/128"
address3 = "2001:db8::3/128"
address4 = "2001:db8::4/128"
subnet1 = "2001:db8:a::/48"
subnet2 = "2001:db8:b::/48"
subnet3 = "2001:db8:c::/48"
subnet4 = "2001:db8:d::/48"
} else {
address1 = "203.0.113.1/32"
address2 = "203.0.113.2/32"
address3 = "203.0.113.3/32"
address4 = "203.0.113.4/32"
subnet1 = "192.0.2.0/24"
subnet2 = "198.51.100.0/24"
subnet3 = "198.51.101.0/24"
subnet4 = "198.51.102.0/24"
}

chain := randChain(t)
Expand Down Expand Up @@ -382,12 +390,32 @@ func runRulesTests(t *testing.T, ipt *IPTables) {
t.Fatalf("List failed: %v", err)
}

// Verify DeleteById functionality by adding two new rules and removing second last
ruleCount1 := len(rules)
err = ipt.Append("filter", chain, "-s", address3, "-d", subnet3, "-j", "ACCEPT")
if err != nil {
t.Fatalf("Append failed: %v", err)
}
err = ipt.Append("filter", chain, "-s", address4, "-d", subnet4, "-j", "ACCEPT")
if err != nil {
t.Fatalf("Append failed: %v", err)
}
err = ipt.DeleteById("filter", chain, ruleCount1)
if err != nil {
t.Fatalf("DeleteById failed: %v", err)
}
rules, err = ipt.List("filter", chain)
if err != nil {
t.Fatalf("List failed: %v", err)
}

expected := []string{
"-N " + chain,
"-A " + chain + " -s " + subnet1 + " -d " + address1 + " -j ACCEPT",
"-A " + chain + " -s " + subnet2 + " -d " + address2 + " -j ACCEPT",
"-A " + chain + " -s " + subnet2 + " -d " + address1 + " -j ACCEPT",
"-A " + chain + " -s " + address1 + " -d " + subnet2 + " -j ACCEPT",
"-A " + chain + " -s " + address4 + " -d " + subnet4 + " -j ACCEPT",
}

if !reflect.DeepEqual(rules, expected) {
Expand All @@ -406,6 +434,7 @@ func runRulesTests(t *testing.T, ipt *IPTables) {
"-A " + chain + " -s " + subnet2 + " -d " + address2 + " " + suffix,
"-A " + chain + " -s " + subnet2 + " -d " + address1 + " " + suffix,
"-A " + chain + " -s " + address1 + " -d " + subnet2 + " " + suffix,
"-A " + chain + " -s " + address4 + " -d " + subnet4 + " " + suffix,
}
}
// older nf_tables returned the second order
Expand Down Expand Up @@ -439,6 +468,7 @@ func runRulesTests(t *testing.T, ipt *IPTables) {
{"0", "0", "ACCEPT", prot, opt, "*", "*", subnet2, address2, ""},
{"0", "0", "ACCEPT", prot, opt, "*", "*", subnet2, address1, ""},
{"0", "0", "ACCEPT", prot, opt, "*", "*", address1, subnet2, ""},
{"0", "0", "ACCEPT", prot, opt, "*", "*", address4, subnet4, ""},
}

if !reflect.DeepEqual(stats, expectedStats) {
Expand All @@ -454,14 +484,17 @@ func runRulesTests(t *testing.T, ipt *IPTables) {
// in the subsequent usage
_, address1CIDR, _ := net.ParseCIDR(address1)
_, address2CIDR, _ := net.ParseCIDR(address2)
_, address4CIDR, _ := net.ParseCIDR(address4)
_, subnet1CIDR, _ := net.ParseCIDR(subnet1)
_, subnet2CIDR, _ := net.ParseCIDR(subnet2)
_, subnet4CIDR, _ := net.ParseCIDR(subnet4)

expectedStructStats := []Stat{
{0, 0, "ACCEPT", prot, opt, "*", "*", subnet1CIDR, address1CIDR, ""},
{0, 0, "ACCEPT", prot, opt, "*", "*", subnet2CIDR, address2CIDR, ""},
{0, 0, "ACCEPT", prot, opt, "*", "*", subnet2CIDR, address1CIDR, ""},
{0, 0, "ACCEPT", prot, opt, "*", "*", address1CIDR, subnet2CIDR, ""},
{0, 0, "ACCEPT", prot, opt, "*", "*", address4CIDR, subnet4CIDR, ""},
}

if !reflect.DeepEqual(structStats, expectedStructStats) {
Expand Down

0 comments on commit 26e4251

Please sign in to comment.