Skip to content

Conversation

pippolo84
Copy link
Member

@pippolo84 pippolo84 commented Jul 1, 2024

As suggested in #33432, the autogenerated DeepEqual methods to compare IngressCommonRule structs and EgressCommonRule structs do not take into account that a nil slice in one of the fields should not be compared equal to a empty non-nil slice in the same field.
Since #29608, the semantic of a empty non-nil slice in both Ingress and Egress section of CNPs and CCNPs has been changed to not select any identity.
Therefore, a CNP with a nil ToEndpoints should not compare equal to a CNP with an empty non-nil ToEndpoints fields, otherwise the following update:

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: test
spec:
  endpointSelector:
    matchLabels:
      run: tmp-shell
  egress:
  - toCIDR:
    - 1.1.1.1/32
    toPorts:
      - ports:
          - port: "80"

-->

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: test
spec:
  endpointSelector:
    matchLabels:
      run: tmp-shell
  egress:
  - toCIDR:
    - 1.1.1.1/32
    toEndpoints: [] # <-- this
    toPorts:
      - ports:
          - port: "80"

is incorrectly discarded, instead of being propagated to the policy repository.

Related: #29608
Fixes: #33432

@pippolo84 pippolo84 added kind/bug This is a bug in the Cilium logic. area/daemon Impacts operation of the Cilium daemon. release-note/bug This PR fixes an issue in a previous release of Cilium. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies. needs-backport/1.16 This PR / issue needs backporting to the v1.16 branch labels Jul 1, 2024
@pippolo84
Copy link
Member Author

/test

@pippolo84 pippolo84 marked this pull request as ready for review July 1, 2024 15:25
@pippolo84 pippolo84 requested a review from a team as a code owner July 1, 2024 15:25
@pippolo84 pippolo84 requested a review from aanm July 1, 2024 15:25
@pippolo84
Copy link
Member Author

Also, I think we should extend the proposed behavior to:

  • ToServices, ToGroups and ToNodes on the egress side
  • FromGroups and FromNodes on the ingress side

WDYT @christarazi ?

@pippolo84 pippolo84 changed the title Fix CNP/CCNP update when selectors change from nil to non-empty slices Fix CNP/CCNP update when selectors change from nil to empty non-nil slices Jul 1, 2024
@pippolo84 pippolo84 force-pushed the pr/pippolo84/fix-33432 branch from 6040abc to 28796ee Compare July 1, 2024 15:33
@aanm aanm requested review from christarazi and removed request for aanm July 1, 2024 15:40
Copy link
Member

@christarazi christarazi left a comment

Choose a reason for hiding this comment

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

Nice find, LGTM. Could you add a unit test similar to #33439 to actually test the expected behavior end to end?

@pippolo84 pippolo84 requested a review from a team as a code owner July 9, 2024 17:31
@pippolo84 pippolo84 requested a review from derailed July 9, 2024 17:31
@pippolo84
Copy link
Member Author

pippolo84 commented Jul 9, 2024

Could you add a unit test similar to #33439 to actually test the expected behavior end to end?

Actually we already have a similar test to validate the generated policy map starting from an empty non-nil ToEndpoints slice:

// Case 13: deny all at L3 in case of an empty non-nil toEndpoints slice.
func TestEgressEmptyToEndpoints(t *testing.T) {
td := newTestData()
rule := &rule{
Rule: api.Rule{
EndpointSelector: endpointSelectorA,
Egress: []api.EgressRule{
{
EgressCommonRule: api.EgressCommonRule{
ToEndpoints: []api.EndpointSelector{},
},
ToPorts: []api.PortRule{{
Ports: []api.PortProtocol{
{Port: "80", Protocol: api.ProtoTCP},
},
}},
},
},
}}
buffer := new(bytes.Buffer)
ctxFromA := SearchContext{From: labelsA, Trace: TRACE_VERBOSE}
ctxFromA.Logging = stdlog.New(buffer, "", 0)
t.Log(buffer)
state := traceState{}
res, err := rule.resolveEgressPolicy(td.testPolicyContext, &ctxFromA, &state, NewL4PolicyMap(), nil, nil)
require.NoError(t, err)
require.Nil(t, res)
require.Equal(t, 1, state.selectedRules)
require.Equal(t, 0, state.matchedRules)
}

But I have added once more to test the propagation of rules update in the policy repository using the same CNP as in #33432 (see commit 8c2eee0)

I did that because before the fix the update would have been discarded here:

if oldCNP.DeepEqual(cnp) {
return nil
}

Is this enough? I'm afraid a more comprehensive e2e test (from the policy watcher down to the policy map) might not be trivial.

@pippolo84 pippolo84 requested a review from christarazi July 9, 2024 17:47
Copy link
Contributor

@derailed derailed left a comment

Choose a reason for hiding this comment

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

@pippolo84 Great catch Fabio!

XorNil is a helper that returns true only if one of the two input slices
is nil and the other is not.

It is useful when comparing two slices and the semantic of a nil slice
is different from the semantic of an empty non-nil one.

Signed-off-by: Fabio Falzoi <fabio.falzoi@isovalent.com>
The semantic of a nil slice in one of the IngressCommonRule fields is
different from the semantic of an empty non-nil slice. In order to
compare two IngressCommonRule instances correctly, we add a custom
DeepEqual method the explicitly checks for this case before calling the
autogenerated method.

This allows to correctly propagate CNP/CCNP updates when, for example,
the FromEndpoints selector is changed from nil to an empty non-nil
slice. In the latter case, the CNP should not select any identity,
falling back to the default behavior (e.g: default deny for an allow
policy).

Fixes: e97df7b ("policy: Do not select any identity with ingress empty slices")
Fixes: cilium#33432

Signed-off-by: Fabio Falzoi <fabio.falzoi@isovalent.com>
The semantic of a nil slice in one of the EgressCommonRule fields is
different from the semantic of an empty non-nil slice. In order to
compare two EgressCommonRule instances correctly, we add a custom
DeepEqual method the explicitly checks for this case before calling the
autogenerated method.

This allows to correctly propagate CNP/CCNP updates when, for example,
the ToEndpoints selector is changed from nil to an empty non-nil
slice. In the latter case, the CNP should not select any identity,
falling back to the default behavior (e.g: default deny for an allow
policy).

Fixes: 6ccd044 ("policy: Do not select any identity with egress empty slices")
Fixes: cilium#33432

Signed-off-by: Fabio Falzoi <fabio.falzoi@isovalent.com>
Add a non regression test for GitHub issue cilium#33432: updating a CNP with a
nil ToEndpoints slice to an empty non-nil ToEndpoints slice should
result in the update not being discarded and the rules in the policy
repository reporting the empty non-nil ToEndpoints slice.

Related: cilium#33432

Signed-off-by: Fabio Falzoi <fabio.falzoi@isovalent.com>
@pippolo84 pippolo84 force-pushed the pr/pippolo84/fix-33432 branch from 8c2eee0 to fc74339 Compare July 10, 2024 09:18
@pippolo84 pippolo84 requested a review from a team as a code owner July 10, 2024 09:18
@pippolo84
Copy link
Member Author

/test

@pippolo84
Copy link
Member Author

CI triage:

  • ci-e2e failure tracked here
  • ci-ginkgo trackere here

Rerunning

@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Jul 12, 2024
@julianwiedmann julianwiedmann added this pull request to the merge queue Jul 12, 2024
Merged via the queue into cilium:main with commit 7294716 Jul 12, 2024
@giorio94 giorio94 mentioned this pull request Jul 15, 2024
27 tasks
@giorio94 giorio94 added backport-pending/1.16 The backport for Cilium 1.16.x for this PR is in progress. and removed needs-backport/1.16 This PR / issue needs backporting to the v1.16 branch labels Jul 15, 2024
@github-actions github-actions bot added backport-done/1.16 The backport for Cilium 1.16.x for this PR is done. and removed backport-pending/1.16 The backport for Cilium 1.16.x for this PR is in progress. labels Jul 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/daemon Impacts operation of the Cilium daemon. backport-done/1.16 The backport for Cilium 1.16.x for this PR is done. kind/bug This is a bug in the Cilium logic. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/bug This PR fixes an issue in a previous release of Cilium. sig/policy Impacts whether traffic is allowed or denied based on user-defined policies.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Different behaviour for CNP creation vs CNP update
7 participants