Skip to content

Commit

Permalink
bpf: use ctx_is_overlay() in encrypted-overlay path
Browse files Browse the repository at this point in the history
This cleans up some raw packet parsing. And avoids false-positives when
non-Cilium endpoints send traffic to TUNNEL_PORT.

Signed-off-by: Julian Wiedmann <jwi@isovalent.com>
  • Loading branch information
julianwiedmann committed Apr 5, 2024
1 parent 296f222 commit 42d745e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 98 deletions.
44 changes: 17 additions & 27 deletions bpf/bpf_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -1311,9 +1311,8 @@ int cil_from_host(struct __ctx_buff *ctx)

#if defined(ENABLE_ENCRYPTED_OVERLAY)
/*
* If the traffic is indeed overlay traffic and it should be encrypted
* CTX_ACT_REDIRECT is returned, unless an error occurred, and the caller can
* return this code to TC.
* If the traffic should be encrypted then CTX_ACT_REDIRECT is returned.
* Unless an error occurred, and the caller can return this code to TC.
*
* CTX_ACT_OK is returned if the traffic should continue normal processing.
*
Expand All @@ -1322,23 +1321,12 @@ int cil_from_host(struct __ctx_buff *ctx)
static __always_inline int do_encrypt_overlay(struct __ctx_buff *ctx)
{
int ret = CTX_ACT_OK;
__u16 proto = 0;
struct iphdr __maybe_unused *ipv4;
void __maybe_unused *data, *data_end = NULL;

/* we require a valid layer 2 to proceed */
if (!validate_ethertype(ctx, &proto))
return ret;

if (proto != bpf_htons(ETH_P_IP))
return ret;

if (!revalidate_data(ctx, &data, &data_end, &ipv4))
return DROP_INVALID;

if (!vxlan_skb_is_vxlan_v4(data, data_end, ipv4, TUNNEL_PORT))
return ret;

if (vxlan_get_vni(data, data_end, ipv4) == ENCRYPTED_OVERLAY_ID)
ret = encrypt_overlay_and_redirect(ctx, data, data_end, ipv4);

Expand Down Expand Up @@ -1443,21 +1431,23 @@ int cil_to_netdev(struct __ctx_buff *ctx __maybe_unused)
#endif

#if defined(ENABLE_ENCRYPTED_OVERLAY)
/* Determine if this is overlay traffic that should be recirculated
* to the stack for XFRM encryption.
*/
ret = do_encrypt_overlay(ctx);
if (ret == CTX_ACT_REDIRECT) {
/* we are redirecting back into the stack, so TRACE_TO_STACK
* for tracepoint
if (ctx_is_overlay(ctx)) {
/* Determine if this is overlay traffic that should be recirculated
* to the stack for XFRM encryption.
*/
send_trace_notify(ctx, TRACE_TO_STACK, 0, 0, 0,
0, TRACE_REASON_ENCRYPT_OVERLAY, 0);
return ret;
ret = do_encrypt_overlay(ctx);
if (ret == CTX_ACT_REDIRECT) {
/* we are redirecting back into the stack, so TRACE_TO_STACK
* for tracepoint
*/
send_trace_notify(ctx, TRACE_TO_STACK, 0, 0, 0,
0, TRACE_REASON_ENCRYPT_OVERLAY, 0);
return ret;
}
if (IS_ERR(ret))
return send_drop_notify_error(ctx, 0, ret, CTX_ACT_DROP,
METRIC_EGRESS);
}
else if (IS_ERR(ret))
return send_drop_notify_error(ctx, 0, ret, CTX_ACT_DROP,
METRIC_EGRESS);
#endif /* ENABLE_ENCRYPTED_OVERLAY */

#ifdef ENABLE_WIREGUARD
Expand Down
31 changes: 0 additions & 31 deletions bpf/lib/vxlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,6 @@
#include <linux/if_ether.h>
#include "lib/csum.h"

/*
* Returns true if the skb associated with data pointers is a vxlan encapsulated
* packet.
*
* The determination is made by comparing the UDP destination port with
* the tunnel_port provided to the function.
*/
static __always_inline bool
vxlan_skb_is_vxlan_v4(const void *data, const void *data_end,
const struct iphdr *ipv4, const __u16 tunnel_port)
{
struct udphdr *udp = NULL;
__u32 l3_size = 0;

if (ipv4->protocol != IPPROTO_UDP)
return false;

l3_size = ipv4->ihl * 4;

if (data + sizeof(struct ethhdr) + l3_size + sizeof(struct udphdr)
+ sizeof(struct vxlanhdr) > data_end)
return false;

udp = (struct udphdr *)(data + sizeof(struct ethhdr) + l3_size);

if (udp->dest == bpf_htons(tunnel_port))
return true;

return false;
}

/*
* Returns the VNI in the native host's endian format of a xvlan encap'd packet.
*
Expand Down
40 changes: 0 additions & 40 deletions bpf/tests/vxlan_helpers_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,46 +74,6 @@ mk_packet(struct __ctx_buff *ctx) {
return 0;
}

PKTGEN("tc", "vxlan_skb_is_vxlan_v4_success")
static __always_inline int
pktgen_vxlan_mock_check1(struct __ctx_buff *ctx) {
return mk_packet(ctx);
}

CHECK("tc", "vxlan_skb_is_vxlan_v4_success")
int check1(struct __ctx_buff *ctx)
{
test_init();

void *data, *data_end = NULL;
struct iphdr *ipv4 = NULL;

assert(revalidate_data(ctx, &data, &data_end, &ipv4));
assert(vxlan_skb_is_vxlan_v4(data, data_end, ipv4, TUNNEL_PORT));

test_finish();
}

PKTGEN("tc", "vxlan_skb_is_vxlan_v4_failure")
static __always_inline int
pktgen_vxlan_mock_check2(struct __ctx_buff *ctx) {
return mk_packet(ctx);
}

CHECK("tc", "vxlan_skb_is_vxlan_v4_failure")
int check2(struct __ctx_buff *ctx)
{
test_init();

void *data, *data_end = NULL;
struct iphdr *ipv4 = NULL;

assert(revalidate_data(ctx, &data, &data_end, &ipv4));
assert(!vxlan_skb_is_vxlan_v4(data, data_end, ipv4, TUNNEL_PORT_BAD));

test_finish();
}

PKTGEN("tc", "vxlan_get_vni_success")
static __always_inline int
pktgen_vxlan_mock_check3(struct __ctx_buff *ctx) {
Expand Down

0 comments on commit 42d745e

Please sign in to comment.