Skip to content

Commit

Permalink
bpf,test: add tests for vxlan helper functions
Browse files Browse the repository at this point in the history
Add unit tests for new vxlan helper functions in tunnel.h

Signed-off-by: Louis DeLosSantos <louis.delos@isovalent.com>
  • Loading branch information
ldelossa authored and pchaigno committed Mar 27, 2024
1 parent e1951e9 commit d00547a
Showing 1 changed file with 193 additions and 0 deletions.
193 changes: 193 additions & 0 deletions bpf/tests/vxlan_helpers_tests.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright Authors of Cilium */

#include "common.h"
#include "bpf/ctx/skb.h"
#include "pktgen.h"

#define TUNNEL_PROTOCOL TUNNEL_PROTOCOL_VXLAN
#define TUNNEL_PORT 8472
#define TUNNEL_PORT_BAD 0
#define VXLAN_VNI 0xDEADBE
#define VXLAN_VNI_NEW 0xCAFEBE
#define UDP_CHECK 0xDEAD

#include "node_config.h"
#include "lib/common.h"
#include "lib/vxlan.h"

/* this had to be used instead of the pktgen__push methods since these methods
* use layer accounting and will fail when pushing an ipv4 header past its
* assumed layer
*/
static __always_inline void
mk_data(const __u8 *buff) {
struct ethhdr *eth = (struct ethhdr *)buff;

memcpy(&eth->h_source, (__u8 *)mac_one, sizeof(mac_three));
memcpy(&eth->h_dest, (__u8 *)mac_one, sizeof(mac_four));
eth->h_proto = ETH_P_IP;

struct iphdr *ipv4 = (struct iphdr *)(buff + sizeof(struct ethhdr));

ipv4->saddr = v4_pod_one;
ipv4->daddr = v4_pod_two;
}

static __always_inline int
mk_packet(struct __ctx_buff *ctx) {
struct pktgen builder;
struct udphdr *l4;
struct vxlanhdr *vx;
/* data is encap'd ipv4 packet, we don't care about l4 */
__u8 encap_data[sizeof(struct ethhdr) + sizeof(struct iphdr)];
void *data;

pktgen__init(&builder, ctx);

l4 = pktgen__push_ipv4_udp_packet(&builder,
(__u8 *)mac_one,
(__u8 *)mac_two,
v4_node_one,
v4_node_two,
666,
bpf_htons(TUNNEL_PORT));
if (!l4)
return TEST_ERROR;

l4->check = UDP_CHECK;

vx = pktgen__push_default_vxlanhdr(&builder);
if (!vx)
return TEST_ERROR;

vx->vx_vni = bpf_htonl(VXLAN_VNI << 8);

mk_data(encap_data);

data = pktgen__push_data(&builder, encap_data, sizeof(encap_data));
if (!data)
return TEST_ERROR;

pktgen__finish(&builder);

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) {
return mk_packet(ctx);
}

CHECK("tc", "vxlan_get_vni_success")
int check3(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_get_vni(data, data_end, ipv4) == VXLAN_VNI);

test_finish();
}

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

CHECK("tc", "vxlan_get_inner_ipv4_success")
int check4(struct __ctx_buff *ctx)
{
test_init();

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

assert(revalidate_data(ctx, &data, &data_end, &ipv4));
assert(vxlan_get_inner_ipv4(data, data_end, ipv4, &inner_ipv4));

assert(inner_ipv4->saddr == v4_pod_one);
assert(inner_ipv4->daddr == v4_pod_two);

test_finish();
}

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

CHECK("tc", "vxlan_rewrite_vni_success")
int check5(struct __ctx_buff *ctx)
{
test_init();

void *data, *data_end = NULL;
struct iphdr *ipv4 = NULL;
struct udphdr *udp = NULL;
__u32 vni = 0;

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

assert(vxlan_rewrite_vni(ctx, data, data_end, ipv4,
VXLAN_VNI_NEW));

/* packet data was touched so revalidate */
assert(revalidate_data(ctx, &data, &data_end, &ipv4));

vni = vxlan_get_vni(data, data_end, ipv4);
assert(vni == VXLAN_VNI_NEW);

/* assert udp checksum was updated */
udp = (struct udphdr *)(data + sizeof(struct ethhdr) + (ipv4->ihl * 4));
assert(udp->check != UDP_CHECK);

test_finish();
}

0 comments on commit d00547a

Please sign in to comment.