Skip to content

bpf: support for adding DSCP for egress traffic#10881

Merged
mazdakn merged 21 commits intoprojectcalico:masterfrom
mazdakn:dscp-bpf
Sep 9, 2025
Merged

bpf: support for adding DSCP for egress traffic#10881
mazdakn merged 21 commits intoprojectcalico:masterfrom
mazdakn:dscp-bpf

Conversation

@mazdakn
Copy link
Member

@mazdakn mazdakn commented Aug 25, 2025

Description

Add support for setting DSCP for egress traffic leaving cluster.
This is the follow up on the main PRs:

The follow up PR includes a change to only set DSCP for traffic leaving cluster.

Related issues/PRs

Todos

  • Tests
  • Documentation
  • Release note

Release Note

TBD

Reminder for the reviewer

Make sure that this PR has the correct labels and milestone set.

Every PR needs one docs-* label.

  • docs-pr-required: This change requires a change to the documentation that has not been completed yet.
  • docs-completed: This change has all necessary documentation completed.
  • docs-not-required: This change has no user-facing impact and requires no docs.

Every PR needs one release-note-* label.

  • release-note-required: This PR has user-facing changes. Most PRs should have this label.
  • release-note-not-required: This PR has no user-facing changes.

Other optional labels:

  • cherry-pick-candidate: This PR should be cherry-picked to an earlier release. For bug fixes only.
  • needs-operator-pr: This PR is related to install and requires a corresponding change to the operator.

Copilot AI review requested due to automatic review settings August 25, 2025 23:27
@mazdakn mazdakn requested a review from a team as a code owner August 25, 2025 23:27
@marvin-tigera marvin-tigera added this to the Calico v3.31.0 milestone Aug 25, 2025
@marvin-tigera marvin-tigera added release-note-required Change has user-facing impact (no matter how small) docs-pr-required Change is not yet documented labels Aug 25, 2025

This comment was marked as outdated.

@mazdakn mazdakn changed the title [WIP] ebpf: support for adding DSCP for egress traffic bpf: support for adding DSCP for egress traffic Aug 29, 2025
@mazdakn mazdakn added docs-not-required Docs not required for this change release-note-not-required Change has no user-facing impact and removed release-note-required Change has user-facing impact (no matter how small) docs-pr-required Change is not yet documented labels Sep 2, 2025

This comment was marked as outdated.

@mazdakn mazdakn requested a review from Copilot September 4, 2025 00:06

This comment was marked as outdated.

@mazdakn mazdakn requested a review from Copilot September 4, 2025 00:10

This comment was marked as outdated.

// The 2 least significant bits are assigned to ECN and must not be touched.
ip_hdr(ctx)->tos = (__u8) ((ip_hdr(ctx)->tos & 0x03) | (dscp << 2));

__wsum ip_csum = bpf_csum_diff(0, 0, (__u32 *)ctx->ip_header, sizeof(struct iphdr), 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you should set csum to 0 if you want to compute the csum of the entire ip header the checksum is computed as the 16-bit ones' complement of the ones' complement sum of all 16-bit words in the header. This includes the Header Checksum field itself, which is set to zero during computation.

Copy link
Contributor

@tomastigera tomastigera left a comment

Choose a reason for hiding this comment

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

nothing fundamental, mostly nits

Comment on lines +119 to +121
if (EGRESS_DSCP < 0) {
return TC_ACT_UNSPEC;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to take it out from this function? Could -1 be technically a valid value? (guess not since all valid values are 6bits only). Perhaps a flag that this field is set?

Copy link
Member Author

Choose a reason for hiding this comment

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

Adding a flag to check if this value is set is probably an overkill. we can check EGRESS_DSCP >= 0 in the caller part.


func withEgressDSCP(value int8) testOption {
return func(o *testOpts) {
o.dscp = &value
Copy link
Contributor

Choose a reason for hiding this comment

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

if -1 is invalid, you could have used -1 as invalid as well instead of using a pointer

Copy link
Member Author

Choose a reason for hiding this comment

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

I added it this way only to consider the default value of type. Since default value of int, 0, is a valid DSCP value.
I managed to find the initialization part, so now type is int.

return nil, err
}

ap.DSCP = -1
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

}
}

ap.DSCP = -1
Copy link
Contributor

Choose a reason for hiding this comment

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

you set the dscp to -1 but then you deny packets if it is set to -1 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

It wasn't dropping packets, but clearly the return value was confusing. Changed the return val to bool.

deny_reason(ctx, CALI_REASON_DROPPED_BY_QOS);
goto deny;
}
if (set_dscp(ctx) == TC_ACT_SHOT) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (set_dscp(ctx) == TC_ACT_SHOT) {
if ((CALI_F_FROM_WEP || CALI_F_TO_HEP) && EGRESS_DSCP >= 0 && !set_dscp(ctx)) {

you could make the set_dscp return bool. I'd suggest name it qos_set_dscp will suggest to rename the rate functions to qos_* too

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements DSCP (Differentiated Services Code Point) support for BPF dataplane in Calico, extending the existing iptables/nftables DSCP functionality to the eBPF implementation. The changes enable setting DSCP values for egress traffic leaving the cluster when using the BPF dataplane.

Key Changes

  • Removed BPF dataplane skip conditions from DSCP tests to enable testing with BPF
  • Added BPF-specific DSCP implementation in the C code with IPv4/IPv6 support
  • Extended BPF program configuration to include DSCP parameters

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
felix/fv/dscp_test.go Enables DSCP tests for BPF dataplane and conditionally skips iptables-specific verification
felix/fv/bpf_test.go Removes obsolete BPFIPv6Support function that returned false
felix/dataplane/linux/bpf_ep_mgr.go Adds DSCP configuration logic for workload and host endpoints
felix/bpf/ut/qos_test.go Adds comprehensive unit tests for DSCP functionality in both IPv4 and IPv6
felix/bpf/ut/bpf_prog_test.go Extends test framework with DSCP configuration support
felix/bpf/tc/attach.go Adds DSCP field to AttachPoint struct and configuration
felix/bpf/libbpf/libbpf_common.go Adds DSCP field to TcGlobalData struct
felix/bpf/libbpf/libbpf_api.h Updates C API to include DSCP parameter
felix/bpf/libbpf/libbpf.go Passes DSCP value to C implementation
felix/bpf-gpl/tc.c Integrates DSCP setting into packet processing flow
felix/bpf-gpl/qos.h Implements DSCP setting logic for IPv4 and IPv6 packets
felix/bpf-gpl/globals.h Adds DSCP field to global data structure
felix/bpf-gpl/bpf.h Defines EGRESS_DSCP macro for accessing DSCP configuration

Copy link
Contributor

@tomastigera tomastigera left a comment

Choose a reason for hiding this comment

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

LGTM ... it would be great in the follow up PR to add a FV test that would set the DSCP. There are tests with external client (mainly for nodeports) and that could verify various scenarios. And we can use tcpdump to verify that the value is set when expected.

@mazdakn mazdakn merged commit bd40575 into projectcalico:master Sep 9, 2025
2 of 3 checks passed
@mazdakn mazdakn deleted the dscp-bpf branch September 9, 2025 15:46
@mazdakn
Copy link
Member Author

mazdakn commented Sep 9, 2025

@tomastigera we have some FV for this:

It("applying DSCP annotation should result is adding correct rules", func() {

But I'm going to add more for a couple of more scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-not-required Docs not required for this change release-note-not-required Change has no user-facing impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants