diff --git a/bpf/bpf_host.c b/bpf/bpf_host.c index 1d510b41c64a0..749969162a34e 100644 --- a/bpf/bpf_host.c +++ b/bpf/bpf_host.c @@ -366,7 +366,7 @@ handle_ipv6_cont(struct __ctx_buff *ctx, __u32 secctx, const bool from_host, } #endif - if (!info || identity_is_world_ipv6(info->sec_identity)) { + if (!info || (!tc_index_from_ingress_proxy(ctx) && identity_is_world_ipv6(info->sec_identity))) { /* See IPv4 comment. */ return DROP_UNROUTABLE; } @@ -781,7 +781,7 @@ handle_ipv4_cont(struct __ctx_buff *ctx, __u32 secctx, const bool from_host, } #endif - if (!info || identity_is_world_ipv4(info->sec_identity)) { + if (!info || (!tc_index_from_ingress_proxy(ctx) && identity_is_world_ipv4(info->sec_identity))) { /* We have received a packet for which no ipcache entry exists, * we do not know what to do with this packet, drop it. * @@ -790,6 +790,10 @@ handle_ipv4_cont(struct __ctx_buff *ctx, __u32 secctx, const bool from_host, * entry. Therefore we need to test for WORLD_ID. It is clearly * wrong to route a ctx to cilium_host for which we don't know * anything about it as otherwise we'll run into a routing loop. + * + * Note that we do not drop packets from ingress proxy even if + * they are going to WORLD_ID. This is to avoid + * https://github.com/cilium/cilium/issues/21954. */ return DROP_UNROUTABLE; } diff --git a/bpf/bpf_lxc.c b/bpf/bpf_lxc.c index be9c676a06877..ccb1e37627704 100644 --- a/bpf/bpf_lxc.c +++ b/bpf/bpf_lxc.c @@ -1465,7 +1465,7 @@ ipv6_policy(struct __ctx_buff *ctx, struct ipv6hdr *ip6, int ifindex, __u32 src_ /* If packet is coming from the ingress proxy we have to skip * redirection to the ingress proxy as we would loop forever. */ - skip_ingress_proxy = tc_index_skip_ingress_proxy(ctx); + skip_ingress_proxy = tc_index_from_ingress_proxy(ctx); ct_buffer = map_lookup_elem(&CT_TAIL_CALL_BUFFER6, &zero); if (!ct_buffer) @@ -1488,7 +1488,7 @@ ipv6_policy(struct __ctx_buff *ctx, struct ipv6hdr *ip6, int ifindex, __u32 src_ * Always redirect connections that originated from L7 LB. */ if (ct_state_is_from_l7lb(ct_state) || - (ct_state->proxy_redirect && !tc_index_skip_egress_proxy(ctx))) { + (ct_state->proxy_redirect && !tc_index_from_egress_proxy(ctx))) { /* This is a reply, the proxy port does not need to be embedded * into ctx->mark and *proxy_port can be left unset. */ @@ -1792,7 +1792,7 @@ ipv4_policy(struct __ctx_buff *ctx, struct iphdr *ip4, int ifindex, __u32 src_la /* If packet is coming from the ingress proxy we have to skip * redirection to the ingress proxy as we would loop forever. */ - skip_ingress_proxy = tc_index_skip_ingress_proxy(ctx); + skip_ingress_proxy = tc_index_from_ingress_proxy(ctx); orig_sip = ip4->saddr; @@ -1825,7 +1825,7 @@ ipv4_policy(struct __ctx_buff *ctx, struct iphdr *ip4, int ifindex, __u32 src_la /* Skip policy enforcement for return traffic. */ if (ret == CT_REPLY || ret == CT_RELATED) { if (ct_state_is_from_l7lb(ct_state) || - (ct_state->proxy_redirect && !tc_index_skip_egress_proxy(ctx))) { + (ct_state->proxy_redirect && !tc_index_from_egress_proxy(ctx))) { /* This is a reply, the proxy port does not need to be embedded * into ctx->mark and *proxy_port can be left unset. */ diff --git a/bpf/lib/common.h b/bpf/lib/common.h index b5439b5103308..a3cb0575be493 100644 --- a/bpf/lib/common.h +++ b/bpf/lib/common.h @@ -776,8 +776,8 @@ static __always_inline __u32 or_encrypt_key(__u8 key) * cilium_host @egress * bpf_host -> bpf_lxc */ -#define TC_INDEX_F_SKIP_INGRESS_PROXY 1 -#define TC_INDEX_F_SKIP_EGRESS_PROXY 2 +#define TC_INDEX_F_FROM_INGRESS_PROXY 1 +#define TC_INDEX_F_FROM_EGRESS_PROXY 2 #define TC_INDEX_F_SKIP_NODEPORT 4 #define TC_INDEX_F_SKIP_RECIRCULATION 8 #define TC_INDEX_F_SKIP_HOST_FIREWALL 16 diff --git a/bpf/lib/identity.h b/bpf/lib/identity.h index 76243f4125e48..5c3b936f1ea82 100644 --- a/bpf/lib/identity.h +++ b/bpf/lib/identity.h @@ -157,14 +157,14 @@ static __always_inline __u32 inherit_identity_from_host(struct __ctx_buff *ctx, */ if (magic == MARK_MAGIC_PROXY_INGRESS) { *identity = get_identity(ctx); - ctx->tc_index |= TC_INDEX_F_SKIP_INGRESS_PROXY; + ctx->tc_index |= TC_INDEX_F_FROM_INGRESS_PROXY; /* (Return) packets from the egress proxy must skip the redirection to * the proxy, as the packet would loop and/or the connection be reset * otherwise. */ } else if (magic == MARK_MAGIC_PROXY_EGRESS) { *identity = get_identity(ctx); - ctx->tc_index |= TC_INDEX_F_SKIP_EGRESS_PROXY; + ctx->tc_index |= TC_INDEX_F_FROM_EGRESS_PROXY; } else if (magic == MARK_MAGIC_IDENTITY) { *identity = get_identity(ctx); } else if (magic == MARK_MAGIC_HOST) { diff --git a/bpf/lib/proxy.h b/bpf/lib/proxy.h index 927cb39c7e6a0..9149598bffb4b 100644 --- a/bpf/lib/proxy.h +++ b/bpf/lib/proxy.h @@ -362,30 +362,30 @@ out: __maybe_unused; } /** - * tc_index_skip_ingress_proxy - returns true if packet originates from ingress proxy + * tc_index_from_ingress_proxy - returns true if packet originates from ingress proxy */ -static __always_inline bool tc_index_skip_ingress_proxy(struct __ctx_buff *ctx) +static __always_inline bool tc_index_from_ingress_proxy(struct __ctx_buff *ctx) { volatile __u32 tc_index = ctx->tc_index; #ifdef DEBUG - if (tc_index & TC_INDEX_F_SKIP_INGRESS_PROXY) + if (tc_index & TC_INDEX_F_FROM_INGRESS_PROXY) cilium_dbg(ctx, DBG_SKIP_PROXY, tc_index, 0); #endif - return tc_index & TC_INDEX_F_SKIP_INGRESS_PROXY; + return tc_index & TC_INDEX_F_FROM_INGRESS_PROXY; } /** - * tc_index_skip_egress_proxy - returns true if packet originates from egress proxy + * tc_index_from_egress_proxy - returns true if packet originates from egress proxy */ -static __always_inline bool tc_index_skip_egress_proxy(struct __ctx_buff *ctx) +static __always_inline bool tc_index_from_egress_proxy(struct __ctx_buff *ctx) { volatile __u32 tc_index = ctx->tc_index; #ifdef DEBUG - if (tc_index & TC_INDEX_F_SKIP_EGRESS_PROXY) + if (tc_index & TC_INDEX_F_FROM_EGRESS_PROXY) cilium_dbg(ctx, DBG_SKIP_PROXY, tc_index, 0); #endif - return tc_index & TC_INDEX_F_SKIP_EGRESS_PROXY; + return tc_index & TC_INDEX_F_FROM_EGRESS_PROXY; } #endif /* __LIB_PROXY_H_ */