Skip to content

Commit

Permalink
Use longer (and thus more descriptive) nftables chain names (#9528)
Browse files Browse the repository at this point in the history
* Use longer (and thus more descriptive) nftables chain names

* Fix build
  • Loading branch information
caseydavenport authored Nov 27, 2024
1 parent 29533a3 commit b254289
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 29 deletions.
8 changes: 4 additions & 4 deletions felix/dataplane/linux/int_dataplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ func NewIntDataplaneDriver(config Config) *InternalDataplane {
rules.IPSetIDThisHostIPs,
ipSetsV4,
config.MaxIPSetSize))
dp.RegisterManager(newPolicyManager(rawTableV4, mangleTableV4, filterTableV4, ruleRenderer, 4))
dp.RegisterManager(newPolicyManager(rawTableV4, mangleTableV4, filterTableV4, ruleRenderer, 4, config.RulesConfig.NFTables))

// Clean up any leftover BPF state.
err := bpfnat.RemoveConnectTimeLoadBalancer("")
Expand All @@ -769,7 +769,7 @@ func NewIntDataplaneDriver(config Config) *InternalDataplane {
bpfutils.RemoveBPFSpecialDevices()
} else {
// In BPF mode we still use iptables for raw egress policy.
dp.RegisterManager(newRawEgressPolicyManager(rawTableV4, ruleRenderer, 4, ipSetsV4.SetFilter))
dp.RegisterManager(newRawEgressPolicyManager(rawTableV4, ruleRenderer, 4, ipSetsV4.SetFilter, config.RulesConfig.NFTables))
}

interfaceRegexes := make([]string, len(config.RulesConfig.WorkloadIfacePrefixes))
Expand Down Expand Up @@ -1032,9 +1032,9 @@ func NewIntDataplaneDriver(config Config) *InternalDataplane {
rules.IPSetIDThisHostIPs,
ipSetsV6,
config.MaxIPSetSize))
dp.RegisterManager(newPolicyManager(rawTableV6, mangleTableV6, filterTableV6, ruleRenderer, 6))
dp.RegisterManager(newPolicyManager(rawTableV6, mangleTableV6, filterTableV6, ruleRenderer, 6, config.RulesConfig.NFTables))
} else {
dp.RegisterManager(newRawEgressPolicyManager(rawTableV6, ruleRenderer, 6, ipSetsV6.SetFilter))
dp.RegisterManager(newRawEgressPolicyManager(rawTableV6, ruleRenderer, 6, ipSetsV6.SetFilter, config.RulesConfig.NFTables))
}

dp.RegisterManager(newEndpointManager(
Expand Down
24 changes: 14 additions & 10 deletions felix/dataplane/linux/policy_mgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,28 @@ type policyManager struct {
ipSetFilterDirty bool // Only used in "raw only" mode.
neededIPSets map[proto.PolicyID]set.Set[string]
ipSetsCallback func(neededIPSets set.Set[string])
nftablesEnabled bool
}

type policyRenderer interface {
PolicyToIptablesChains(policyID *proto.PolicyID, policy *proto.Policy, ipVersion uint8) []*generictables.Chain
ProfileToIptablesChains(profileID *proto.ProfileID, policy *proto.Profile, ipVersion uint8) (inbound, outbound *generictables.Chain)
}

func newPolicyManager(rawTable, mangleTable, filterTable Table, ruleRenderer policyRenderer, ipVersion uint8) *policyManager {
func newPolicyManager(rawTable, mangleTable, filterTable Table, ruleRenderer policyRenderer, ipVersion uint8, nft bool) *policyManager {
return &policyManager{
rawTable: rawTable,
mangleTable: mangleTable,
filterTable: filterTable,
ruleRenderer: ruleRenderer,
ipVersion: ipVersion,
rawTable: rawTable,
mangleTable: mangleTable,
filterTable: filterTable,
ruleRenderer: ruleRenderer,
ipVersion: ipVersion,
nftablesEnabled: nft,
}
}

func newRawEgressPolicyManager(rawTable Table, ruleRenderer policyRenderer, ipVersion uint8,
ipSetsCallback func(neededIPSets set.Set[string]),
nft bool,
) *policyManager {
return &policyManager{
rawTable: rawTable,
Expand All @@ -68,6 +71,7 @@ func newRawEgressPolicyManager(rawTable Table, ruleRenderer policyRenderer, ipVe
ipSetFilterDirty: true,
neededIPSets: make(map[proto.PolicyID]set.Set[string]),
ipSetsCallback: ipSetsCallback,
nftablesEnabled: nft,
}
}

Expand Down Expand Up @@ -113,8 +117,8 @@ func (m *policyManager) OnUpdate(msg interface{}) {
m.mangleTable.UpdateChains([]*generictables.Chain{outbound})
case *proto.ActiveProfileRemove:
log.WithField("id", msg.Id).Debug("Removing profile chains")
inName := rules.ProfileChainName(rules.ProfileInboundPfx, msg.Id)
outName := rules.ProfileChainName(rules.ProfileOutboundPfx, msg.Id)
inName := rules.ProfileChainName(rules.ProfileInboundPfx, msg.Id, m.nftablesEnabled)
outName := rules.ProfileChainName(rules.ProfileOutboundPfx, msg.Id, m.nftablesEnabled)
m.filterTable.RemoveChainByName(inName)
m.filterTable.RemoveChainByName(outName)
m.mangleTable.RemoveChainByName(outName)
Expand All @@ -125,8 +129,8 @@ func (m *policyManager) cleanUpPolicy(id *proto.PolicyID) {
if m.rawEgressOnly {
m.updateNeededIPSets(id, nil)
}
inName := rules.PolicyChainName(rules.PolicyInboundPfx, id)
outName := rules.PolicyChainName(rules.PolicyOutboundPfx, id)
inName := rules.PolicyChainName(rules.PolicyInboundPfx, id, m.nftablesEnabled)
outName := rules.PolicyChainName(rules.PolicyOutboundPfx, id, m.nftablesEnabled)
// As above, we need to clean up in all the tables.
m.filterTable.RemoveChainByName(inName)
m.filterTable.RemoveChainByName(outName)
Expand Down
12 changes: 6 additions & 6 deletions felix/dataplane/linux/policy_mgr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var _ = Describe("Policy manager", func() {
mangleTable = newMockTable("mangle")
filterTable = newMockTable("filter")
ruleRenderer = newMockPolRenderer()
policyMgr = newPolicyManager(rawTable, mangleTable, filterTable, ruleRenderer, 4)
policyMgr = newPolicyManager(rawTable, mangleTable, filterTable, ruleRenderer, 4, false)
})

It("shouldn't touch iptables", func() {
Expand Down Expand Up @@ -277,7 +277,7 @@ var _ = Describe("Raw egress policy manager", func() {
func(ipSets set.Set[string]) {
neededIPSets = ipSets
numCallbackCalls++
})
}, false)
})

It("correctly reports no IP sets at start of day", func() {
Expand Down Expand Up @@ -399,8 +399,8 @@ func (m *ipSetsMatcher) NegatedFailureMessage(actual interface{}) (message strin
type mockPolRenderer struct{}

func (r *mockPolRenderer) PolicyToIptablesChains(policyID *proto.PolicyID, policy *proto.Policy, ipVersion uint8) []*generictables.Chain {
inName := rules.PolicyChainName(rules.PolicyInboundPfx, policyID)
outName := rules.PolicyChainName(rules.PolicyOutboundPfx, policyID)
inName := rules.PolicyChainName(rules.PolicyInboundPfx, policyID, false)
outName := rules.PolicyChainName(rules.PolicyOutboundPfx, policyID, false)
return []*generictables.Chain{
{Name: inName},
{Name: outName},
Expand All @@ -409,10 +409,10 @@ func (r *mockPolRenderer) PolicyToIptablesChains(policyID *proto.PolicyID, polic

func (r *mockPolRenderer) ProfileToIptablesChains(profID *proto.ProfileID, policy *proto.Profile, ipVersion uint8) (inbound, outbound *generictables.Chain) {
inbound = &generictables.Chain{
Name: rules.ProfileChainName(rules.ProfileInboundPfx, profID),
Name: rules.ProfileChainName(rules.ProfileInboundPfx, profID, false),
}
outbound = &generictables.Chain{
Name: rules.ProfileChainName(rules.ProfileOutboundPfx, profID),
Name: rules.ProfileChainName(rules.ProfileOutboundPfx, profID, false),
}
return
}
Expand Down
4 changes: 3 additions & 1 deletion felix/rules/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ func (r *DefaultRuleRenderer) PolicyGroupToIptablesChains(group *PolicyGroup) []
chainToJumpTo := PolicyChainName(
polChainPrefix,
&proto.PolicyID{Tier: group.Tier, Name: polName},
r.NFTables,
)
rules = append(rules, generictables.Rule{
Match: match,
Expand Down Expand Up @@ -473,6 +474,7 @@ func (r *DefaultRuleRenderer) endpointIptablesChain(
chainsToJumpTo = append(chainsToJumpTo, PolicyChainName(
policyPrefix,
&proto.PolicyID{Tier: tier.Name, Name: p},
r.NFTables,
))
}
} else {
Expand Down Expand Up @@ -541,7 +543,7 @@ func (r *DefaultRuleRenderer) endpointIptablesChain(
if chainType == chainTypeNormal {
// Then, jump to each profile in turn.
for _, profileID := range profileIds {
profChainName := ProfileChainName(profilePrefix, &proto.ProfileID{Name: profileID})
profChainName := ProfileChainName(profilePrefix, &proto.ProfileID{Name: profileID}, r.NFTables)
rules = append(rules,
generictables.Rule{Match: r.NewMatch(), Action: r.Jump(profChainName)},
// If policy marked packet as accepted, it returns, setting the
Expand Down
25 changes: 17 additions & 8 deletions felix/rules/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,20 @@ import (
"github.com/projectcalico/calico/felix/hashutils"
"github.com/projectcalico/calico/felix/ipsets"
"github.com/projectcalico/calico/felix/iptables"
"github.com/projectcalico/calico/felix/nftables"
"github.com/projectcalico/calico/felix/proto"
)

// ruleRenderer defined in rules_defs.go.

func (r *DefaultRuleRenderer) PolicyToIptablesChains(policyID *proto.PolicyID, policy *proto.Policy, ipVersion uint8) []*generictables.Chain {
inbound := generictables.Chain{
Name: PolicyChainName(PolicyInboundPfx, policyID),
Name: PolicyChainName(PolicyInboundPfx, policyID, r.NFTables),
// Note that the policy name includes the tier, so it does not need to be separately specified.
Rules: r.ProtoRulesToIptablesRules(policy.InboundRules, ipVersion, fmt.Sprintf("Policy %s ingress", policyID.Name)),
}
outbound := generictables.Chain{
Name: PolicyChainName(PolicyOutboundPfx, policyID),
Name: PolicyChainName(PolicyOutboundPfx, policyID, r.NFTables),
// Note that the policy name also includes the tier, so it does not need to be separately specified.
Rules: r.ProtoRulesToIptablesRules(policy.OutboundRules, ipVersion, fmt.Sprintf("Policy %s egress", policyID.Name)),
}
Expand All @@ -45,11 +46,11 @@ func (r *DefaultRuleRenderer) PolicyToIptablesChains(policyID *proto.PolicyID, p

func (r *DefaultRuleRenderer) ProfileToIptablesChains(profileID *proto.ProfileID, profile *proto.Profile, ipVersion uint8) (inbound, outbound *generictables.Chain) {
inbound = &generictables.Chain{
Name: ProfileChainName(ProfileInboundPfx, profileID),
Name: ProfileChainName(ProfileInboundPfx, profileID, r.NFTables),
Rules: r.ProtoRulesToIptablesRules(profile.InboundRules, ipVersion, fmt.Sprintf("Profile %s ingress", profileID.Name)),
}
outbound = &generictables.Chain{
Name: ProfileChainName(ProfileOutboundPfx, profileID),
Name: ProfileChainName(ProfileOutboundPfx, profileID, r.NFTables),
Rules: r.ProtoRulesToIptablesRules(profile.OutboundRules, ipVersion, fmt.Sprintf("Profile %s egress", profileID.Name)),
}
return
Expand Down Expand Up @@ -797,18 +798,26 @@ func (r *DefaultRuleRenderer) CalculateRuleMatch(pRule *proto.Rule, ipVersion ui
return match
}

func PolicyChainName(prefix PolicyChainNamePrefix, polID *proto.PolicyID) string {
func PolicyChainName(prefix PolicyChainNamePrefix, polID *proto.PolicyID, nft bool) string {
maxLen := iptables.MaxChainNameLength
if nft {
maxLen = nftables.MaxChainNameLength
}
return hashutils.GetLengthLimitedID(
string(prefix),
polID.Tier+"/"+polID.Name,
iptables.MaxChainNameLength,
maxLen,
)
}

func ProfileChainName(prefix ProfileChainNamePrefix, profID *proto.ProfileID) string {
func ProfileChainName(prefix ProfileChainNamePrefix, profID *proto.ProfileID, nft bool) string {
maxLen := iptables.MaxChainNameLength
if nft {
maxLen = nftables.MaxChainNameLength
}
return hashutils.GetLengthLimitedID(
string(prefix),
profID.Name,
iptables.MaxChainNameLength,
maxLen,
)
}

0 comments on commit b254289

Please sign in to comment.