Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const secondInMillis = 1000
type ruleConverter interface {
Convert(Rule, string, bool) []rules.IPTablesRule
BulkConvert([]Rule, string, bool) []rules.IPTablesRule
DeduplicateRules([]rules.IPTablesRule) []rules.IPTablesRule
}

type OutConn struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ func (c *NetOutChain) IPTablesRules(containerHandle string, containerWorkload st
}

iptablesRules := c.Converter.BulkConvert(ruleSpec, logChain, c.ASGLogging)
iptablesRules = c.Converter.DeduplicateRules(iptablesRules)

iptablesRules = append(iptablesRules, c.denyNetworksRules(containerWorkload)...)

if c.Conn.Limit || c.Conn.DryRun {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ var _ = Describe("NetOutChain", func() {
}

converter.BulkConvertReturns(genericRules)

converter.DeduplicateRulesReturns(genericRules)
})

It("prepends allow rules to the container's netout chain", func() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ func (c *RuleConverter) BulkConvert(ruleSpec []Rule, logChainName string, global
return iptablesRules
}

func (c *RuleConverter) DeduplicateRules(iptablesRules []rules.IPTablesRule) []rules.IPTablesRule {
keys := make(map[string]bool)
deduped_rules := []rules.IPTablesRule{}

Choose a reason for hiding this comment

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

Aren't we creating a copy of the rules set here? What would be the memory impact, we have seen cases with millions of rules?

Copy link
Contributor Author

@klapkov klapkov Nov 14, 2023

Choose a reason for hiding this comment

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

We create a map, in which we use the rules as keys and the value is true or false. If on the current iteration of the rules list we have a rule which is not part of the keys map, we add it to keys and set the value to true. This way if a duplicate of that rule is present, we will skip adding it to the dedupedRules, since the value of that rule is set to true. As to the memory concern, this way of removing duplicates was the one I saw used the most in go. Honestly I do not know how will this impact performance. Open to suggestions here


for _, rule := range iptablesRules {
key := strings.Join(rule, " ")
if !keys[key] {

keys[key] = true
deduped_rules = append(deduped_rules, rule)
}
}

return deduped_rules
}

func (c *RuleConverter) Convert(rule Rule, logChainName string, globalLogging bool) []rules.IPTablesRule {
ruleSpec := []rules.IPTablesRule{}
for _, network := range rule.Networks() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,4 +426,62 @@ var _ = Describe("RuleConverter", func() {
})

})
Describe("DeduplicateRules", func() {
var unfiltered_rules []rules.IPTablesRule
Context("when there are duplicate iptables rules", func() {
BeforeEach(func() {
rule1 := rules.IPTablesRule{
"-m", "iprange", "-p", "tcp",
"--dst-range", "1.1.1.1-2.2.2.2",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT",
}
rule2 := rules.IPTablesRule{
"-m", "iprange", "-p", "tcp",
"--dst-range", "1.1.1.1-2.2.2.2",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT",
}
rule3 := rules.IPTablesRule{
"-m", "iprange", "-p", "tcp",
"--dst-range", "3.3.3.3-4.4.4.4",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT",
}
rule4 := rules.IPTablesRule{
"-m", "iprange", "-p", "tcp",
"--dst-range", "1.1.1.1-2.2.2.2",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT",
}
rule5 := rules.IPTablesRule{
"-m", "iprange", "-p", "tcp",
"--dst-range", "4.4.4.4-5.5.5.5",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT",
}

unfiltered_rules = []rules.IPTablesRule{rule1, rule2, rule3, rule4, rule5}
})

It("removes the duplicate iptables rules", func() {
deduped_rules := converter.DeduplicateRules(unfiltered_rules)

Expect(deduped_rules).To(ConsistOf(
rules.IPTablesRule{"-m", "iprange", "-p", "tcp",
"--dst-range", "1.1.1.1-2.2.2.2",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT"},
rules.IPTablesRule{"-m", "iprange", "-p", "tcp",
"--dst-range", "4.4.4.4-5.5.5.5",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT"},
rules.IPTablesRule{"-m", "iprange", "-p", "tcp",
"--dst-range", "3.3.3.3-4.4.4.4",
"-m", "tcp", "--destination-port", "9000:9999",
"--jump", "ACCEPT"},
))
})
})
})
})