Skip to content

Commit dd83e31

Browse files
committed
Set DSCP only on traffic leaving cluster
1 parent b85c50f commit dd83e31

File tree

7 files changed

+230
-67
lines changed

7 files changed

+230
-67
lines changed

felix/bpf-gpl/conntrack_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Project Calico BPF dataplane programs.
2-
// Copyright (c) 2020-2021 Tigera, Inc. All rights reserved.
2+
// Copyright (c) 2020-2025 Tigera, Inc. All rights reserved.
33
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
44

55
#ifndef __CALI_CONNTRACK_TYPES_H__
@@ -39,6 +39,7 @@ enum cali_ct_type {
3939
#define CALI_CT_FLAG_NP_REMOTE 0x1000 /* marks connections from local host to remote backend of a nodeport */
4040
#define CALI_CT_FLAG_NP_NO_DSR 0x2000 /* marks connections from a client which is excluded from DSR */
4141
#define CALI_CT_FLAG_SKIP_REDIR_PEER 0x4000 /* marks connections from a client which is excluded from redir */
42+
#define CALI_CT_FLAG_CLUSTER_EXTERNAL 0x8000 /* marks connections with source or destination outside cluster */
4243

4344
struct calico_ct_leg {
4445
__u64 bytes;

felix/bpf-gpl/qos.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,13 @@ static CALI_BPF_INLINE int qos_enforce_packet_rate(struct cali_tc_ctx *ctx)
108108
return TC_ACT_SHOT;
109109
}
110110

111-
static CALI_BPF_INLINE bool qos_set_dscp(struct cali_tc_ctx *ctx)
111+
static CALI_BPF_INLINE bool qos_dscp_needs_update(struct cali_tc_ctx *ctx)
112+
{
113+
return ((ctx->state->flags & CALI_ST_CLUSTER_EXTERNAL) && EGRESS_DSCP >= 0);
114+
}
115+
116+
static CALI_BPF_INLINE bool qos_dscp_set(struct cali_tc_ctx *ctx)
112117
{
113-
// TODO (mazdak): set DSCP only if traffic is leaving cluster
114118
__s8 dscp = EGRESS_DSCP;
115119
CALI_DEBUG("setting dscp to %d", dscp);
116120

felix/bpf-gpl/routes.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static CALI_BPF_INLINE enum cali_rt_flags cali_rt_lookup_flags(ipv46_addr_t *add
9696
#define cali_rt_flags_local_tunneled_host(t) (((t) & (CALI_RT_LOCAL | CALI_RT_HOST | CALI_RT_TUNNELED)) == (CALI_RT_LOCAL | CALI_RT_HOST | CALI_RT_TUNNELED))
9797
#define cali_rt_flags_is_in_pool(t) (((t) & CALI_RT_IN_POOL) == CALI_RT_IN_POOL)
9898
#define cali_rt_flags_skip_ingress_redirect(t) (((t) & CALI_RT_SKIP_INGRESS_REDIRECT))
99+
#define cali_rt_flags_external(t) (!((t) & (CALI_RT_WORKLOAD | CALI_RT_HOST)))
99100

100101
static CALI_BPF_INLINE bool rt_addr_is_local_host(ipv46_addr_t *addr)
101102
{
@@ -117,6 +118,17 @@ static CALI_BPF_INLINE bool rt_addr_is_local_tunneled_host(ipv46_addr_t *addr)
117118
return cali_rt_flags_local_tunneled_host(cali_rt_lookup_flags(addr));
118119
}
119120

121+
static CALI_BPF_INLINE bool rt_addr_is_external(ipv46_addr_t *addr)
122+
{
123+
return cali_rt_flags_external(cali_rt_lookup_flags(addr));
124+
}
125+
126+
static CALI_BPF_INLINE bool rt_addr_is_host_or_in_pool(ipv46_addr_t *addr)
127+
{
128+
__u32 flags = cali_rt_lookup_flags(addr);
129+
return cali_rt_flags_host(flags) || cali_rt_flags_is_in_pool(flags);
130+
}
131+
120132
// Don't perform SNAT if either:
121133
// - packet is destined to an address in an IP pool;
122134
// - packet is destined to local host; or

felix/bpf-gpl/tc.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,9 @@ static CALI_BPF_INLINE void calico_tc_process_ct_lookup(struct cali_tc_ctx *ctx)
366366
if (ctx->state->ct_result.flags & CALI_CT_FLAG_NAT_OUT) {
367367
ctx->state->flags |= CALI_ST_NAT_OUTGOING;
368368
}
369+
if (ctx->state->ct_result.flags & CALI_CT_FLAG_CLUSTER_EXTERNAL) {
370+
ctx->state->flags |= CALI_ST_CLUSTER_EXTERNAL;
371+
}
369372

370373
if (CALI_F_TO_HOST && !CALI_F_NAT_IF &&
371374
(ct_result_rc(ctx->state->ct_result.rc) == CALI_CT_ESTABLISHED ||
@@ -545,17 +548,33 @@ static CALI_BPF_INLINE void calico_tc_process_ct_lookup(struct cali_tc_ctx *ctx)
545548
ctx->state->flags |= CALI_ST_NAT_OUTGOING;
546549
}
547550
}
551+
// Check if traffic is leaving cluster. We might need to set DSCP later.
552+
if (cali_rt_flags_is_in_pool(r->flags) && rt_addr_is_external(&ctx->state->post_nat_ip_dst)) {
553+
CALI_DEBUG("Outside cluster dest " IP_FMT "", debug_ip(ctx->state->post_nat_ip_dst));
554+
ctx->state->flags |= CALI_ST_CLUSTER_EXTERNAL;
555+
}
548556
/* If 3rd party CNI is used and dest is outside cluster. See commit fc711b192f for details. */
549-
if (!(r->flags & CALI_RT_IN_POOL)) {
557+
if (!(cali_rt_flags_is_in_pool(r->flags))) {
550558
CALI_DEBUG("Source " IP_FMT " not in IP pool", debug_ip(ctx->state->ip_src));
551-
r = cali_rt_lookup(&ctx->state->post_nat_ip_dst);
552-
if (!r || !(r->flags & (CALI_RT_WORKLOAD | CALI_RT_HOST))) {
559+
if (rt_addr_is_external(&ctx->state->post_nat_ip_dst)) {
553560
CALI_DEBUG("Outside cluster dest " IP_FMT "", debug_ip(ctx->state->post_nat_ip_dst));
554561
ctx->state->flags |= CALI_ST_SKIP_FIB;
555562
}
556563
}
557564
}
558565

566+
// If either source or destination is outside cluster, set flag as might need to update DSCP later.
567+
if ((CALI_F_TO_HEP) && (rt_addr_is_local_host(&ctx->state->ip_src)) &&
568+
(rt_addr_is_external(&ctx->state->post_nat_ip_dst))) {
569+
CALI_DEBUG("Outside cluster dest " IP_FMT "", debug_ip(ctx->state->post_nat_ip_dst));
570+
ctx->state->flags |= CALI_ST_CLUSTER_EXTERNAL;
571+
}
572+
if ((CALI_F_FROM_HEP) && (rt_addr_is_host_or_in_pool(&ctx->state->post_nat_ip_dst)) &&
573+
(rt_addr_is_external(&ctx->state->ip_src))) {
574+
CALI_DEBUG("Outside cluster source " IP_FMT "", debug_ip(ctx->state->ip_src));
575+
ctx->state->flags |= CALI_ST_CLUSTER_EXTERNAL;
576+
}
577+
559578
/* [SMC] I had to add this revalidation when refactoring the conntrack code to use the context and
560579
* adding possible packet pulls in the VXLAN logic. I believe it is spurious but the verifier is
561580
* not clever enough to spot that we'd have already bailed out if one of the pulls failed. */
@@ -1327,7 +1346,7 @@ int calico_tc_skb_accepted_entrypoint(struct __sk_buff *skb)
13271346
deny_reason(ctx, CALI_REASON_DROPPED_BY_QOS);
13281347
goto deny;
13291348
}
1330-
if ((CALI_F_FROM_WEP || CALI_F_TO_HEP) && EGRESS_DSCP >= 0 && !qos_set_dscp(ctx)) {
1349+
if ((CALI_F_FROM_WEP || CALI_F_TO_HEP) && qos_dscp_needs_update(ctx) && !qos_dscp_set(ctx)) {
13311350
goto deny;
13321351
}
13331352
ctx->fwd = calico_tc_skb_accepted(ctx);
@@ -1408,6 +1427,9 @@ int calico_tc_skb_new_flow_entrypoint(struct __sk_buff *skb)
14081427
if (state->flags & CALI_ST_NAT_OUTGOING) {
14091428
ct_ctx_nat->flags |= CALI_CT_FLAG_NAT_OUT;
14101429
}
1430+
if (state->flags & CALI_ST_CLUSTER_EXTERNAL) {
1431+
ct_ctx_nat->flags |= CALI_CT_FLAG_CLUSTER_EXTERNAL;
1432+
}
14111433
if (CALI_F_TO_HOST && state->flags & CALI_ST_SKIP_FIB) {
14121434
ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB;
14131435
}

felix/bpf-gpl/types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ enum cali_state_flags {
158158
CALI_ST_SKIP_REDIR_PEER = 0x800,
159159
/* CALI_ST_SKIP_REDIR_ONCE skips redirection once for this particular packet */
160160
CALI_ST_SKIP_REDIR_ONCE = 0x1000,
161+
/* CALI_ST_CLUSTER_EXTERNAL is set if the packet is heading toward or originating from
162+
* an endpoint outside the cluster */
163+
CALI_ST_CLUSTER_EXTERNAL = 0x2000,
161164
};
162165

163166
struct fwd {

0 commit comments

Comments
 (0)