Skip to content

Commit

Permalink
Merge pull request projectcalico#7949 from tomastigera/tomas-bpf-ipv6
Browse files Browse the repository at this point in the history
[BPF] ipv6 dataplane code passes first unittests
  • Loading branch information
marvin-tigera authored Aug 25, 2023
2 parents 2ff1514 + 55b82f3 commit f1807de
Show file tree
Hide file tree
Showing 76 changed files with 5,053 additions and 1,389 deletions.
27 changes: 19 additions & 8 deletions felix/bpf-gpl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ LD := llc-12

UT_C_FILES:=$(shell find ut -name '*.c')
UT_OBJS:=$(UT_C_FILES:.c=.o) $(shell ./list-ut-objs)
UT_OBJS+=ut/ip_parse_test_v6.o

OBJS:=$(shell ./list-objs)
OBJS+=bin/tc_preamble.o
OBJS+=bin/tc_preamble_v6.o
OBJS+=bin/xdp_preamble.o
OBJS+=bin/policy_default.o
C_FILES:=tc_preamble.c tc.c tc6.c connect_balancer.c connect_balancer_v6.c xdp_preamble.c xdp.c policy_default.c
C_FILES:=tc_preamble.c tc.c connect_balancer.c connect_balancer_v6.c xdp_preamble.c xdp.c policy_default.c

all: $(OBJS)
ut-objs: $(UT_OBJS)
Expand All @@ -72,12 +74,15 @@ UT_CFLAGS=\
-I .

# Mini-UT programs that test one or two functions. These are each in their own files.
ut/%.ll: ut/%.c ut/ut.h tc.c tc.d
ut/%.ll: ut/%.c ut/ut.h
$(CC) $(UT_CFLAGS) $(CFLAGS) -c $< -o $@

tc_preamble.ll: tc_preamble.c tc_preamble.d
$(CC) $(CFLAGS) -c $< -o $@

tc_preamble_v6.ll: tc_preamble.c tc_preamble.d
$(CC) $(CFLAGS) -DIPVER6 -c $< -o $@

xdp_preamble.ll: xdp_preamble.c xdp_preamble.d
$(CC) $(CFLAGS) -DCALI_COMPILE_FLAGS=64 -c $< -o $@

Expand All @@ -90,14 +95,14 @@ to%.ll: tc.c tc.d calculate-flags
$(COMPILE)
from%.ll: tc.c tc.d calculate-flags
$(COMPILE)
#to%_v6.ll: tc6.c tc.d calculate-flags
# $(COMPILE)
#from%_v6.ll: tc6.c tc.d calculate-flags
# $(COMPILE)
to%_v6.ll: tc.c tc.d calculate-flags
$(COMPILE)
from%_v6.ll: tc.c tc.d calculate-flags
$(COMPILE)
test%.ll: tc.c tc.d calculate-flags
$(COMPILE)
#test%_v6.ll: tc6.c tc.d calculate-flags
# $(COMPILE)
test%_v6.ll: tc.c tc.d calculate-flags
$(COMPILE)
xdp%.ll: xdp.c xdp.d calculate-flags
$(COMPILE)
test_xdp%.ll: xdp.c xdp.d calculate-flags
Expand All @@ -106,6 +111,8 @@ test_xdp%.ll: xdp.c xdp.d calculate-flags
LINK=$(LD) -march=bpf -filetype=obj -o $@ $<
bin/tc_preamble.o: tc_preamble.ll | bin
$(LINK)
bin/tc_preamble_v6.o: tc_preamble_v6.ll | bin
$(LINK)
bin/xdp_preamble.o: xdp_preamble.ll | bin
$(LINK)
bin/policy_default.o: policy_default.ll | bin
Expand All @@ -128,6 +135,10 @@ bin/connect_time_%v6_co-re.o: connect_time_%v6.ll | bin
$(LINK)
ut/%.o: ut/%.ll
$(LINK)
ut/ip_parse_test_v6.ll: ut/ip_parse_test.c
$(CC) $(UT_CFLAGS) $(CFLAGS) -DIPVER6 -c $< -o $@
ut/ip_parse_test_v6.o: ut/ip_parse_test_v6.ll
$(LINK)

bin:
mkdir -p bin
Expand Down
10 changes: 8 additions & 2 deletions felix/bpf-gpl/arp.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#ifndef __CALI_ARP_H__
#define __CALI_ARP_H__

#include "ip_addr.h"

struct arp_key {
__u32 ip;
ipv46_addr_t ip;
__u32 ifindex;
};

Expand All @@ -15,6 +17,10 @@ struct arp_value {
char mac_dst[6];
};

CALI_MAP(cali_v4_arp, 2, BPF_MAP_TYPE_LRU_HASH, struct arp_key, struct arp_value, 10000, 0)
#ifdef IPVER6
CALI_MAP_NAMED(cali_v6_arp, cali_arp, 2, BPF_MAP_TYPE_LRU_HASH, struct arp_key, struct arp_value, 10000, 0)
#else
CALI_MAP_NAMED(cali_v4_arp, cali_arp, 2, BPF_MAP_TYPE_LRU_HASH, struct arp_key, struct arp_value, 10000, 0)
#endif

#endif /* __CALI_ARP_H__ */
48 changes: 37 additions & 11 deletions felix/bpf-gpl/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
#include <bpf_core_read.h>
#include <stddef.h>
#include <linux/ip.h>
#include "globals.h"

/* CALI_BPF_INLINE must be defined before we include any of our headers. They
* assume it exists!
*/
#define CALI_BPF_INLINE inline __attribute__((always_inline))

#include "globals.h"

#define BPF_REDIR_EGRESS 0
#define BPF_REDIR_INGRESS 1

Expand Down Expand Up @@ -98,7 +102,12 @@
#define CALI_FIB_LOOKUP_ENABLED true
#endif

#ifdef IPVER6
#undef CALI_FIB_LOOKUP_ENABLED
#define CALI_FIB_LOOKUP_ENABLED false
#else
#define CALI_FIB_ENABLED (!CALI_F_L3 && CALI_FIB_LOOKUP_ENABLED && (CALI_F_TO_HOST || CALI_F_TO_HEP))
#endif

#define COMPILE_TIME_ASSERT(expr) {typedef char array[(expr) ? 1 : -1];}
static CALI_BPF_INLINE void __compile_asserts(void) {
Expand Down Expand Up @@ -215,8 +224,18 @@ static CALI_BPF_INLINE __attribute__((noreturn)) void bpf_exit(int rc) {
}
#pragma clang diagnostic pop

#ifdef IPVER6

#define debug_ip(ip) (bpf_htonl((ip).d))
#define ip_is_dnf(ip) (true)

#else

#define debug_ip(ip) bpf_htonl(ip)

#define ip_is_dnf(ip) ((ip)->frag_off & bpf_htons(0x4000))
#define ip_frag_no(ip) ((ip)->frag_off & bpf_htons(0x1fff))
#endif

static CALI_BPF_INLINE void ip_dec_ttl(struct iphdr *ip)
{
Expand All @@ -229,7 +248,11 @@ static CALI_BPF_INLINE void ip_dec_ttl(struct iphdr *ip)
ip->check = (__be16) (sum + (sum >> 16));
}

#ifdef IPVER6
#define ip_ttl_exceeded(ip) (CALI_F_TO_HOST && !CALI_F_TUNNEL && (ip)->hop_limit <= 1)
#else
#define ip_ttl_exceeded(ip) (CALI_F_TO_HOST && !CALI_F_TUNNEL && (ip)->ttl <= 1)
#endif

#if CALI_F_XDP

Expand Down Expand Up @@ -275,35 +298,38 @@ CALI_PATCH_DEFINE(__skb_mark, 0x4d424b53) /* be 0x4d424b53 = ASCII(SKBM) */

#define map_symbol(name, ver) name##ver

#define MAP_LOOKUP_FN(name, ver) \
static CALI_BPF_INLINE void * name##_lookup_elem(const void* key) \
#define MAP_LOOKUP_FN(fname, name, ver) \
static CALI_BPF_INLINE void * fname##_lookup_elem(const void* key) \
{ \
return bpf_map_lookup_elem(&map_symbol(name, ver), key); \
}

#define MAP_UPDATE_FN(name, ver) \
static CALI_BPF_INLINE int name##_update_elem(const void* key, const void* value, __u64 flags)\
#define MAP_UPDATE_FN(fname, name, ver) \
static CALI_BPF_INLINE int fname##_update_elem(const void* key, const void* value, __u64 flags)\
{ \
return bpf_map_update_elem(&map_symbol(name, ver), key, value, flags); \
}

#define MAP_DELETE_FN(name, ver) \
static CALI_BPF_INLINE int name##_delete_elem(const void* key) \
#define MAP_DELETE_FN(fname, name, ver) \
static CALI_BPF_INLINE int fname##_delete_elem(const void* key) \
{ \
return bpf_map_delete_elem(&map_symbol(name, ver), key); \
}

#define CALI_MAP(name, ver, map_type, key_type, val_type, size, flags) \
#define CALI_MAP_NAMED(name, fname, ver, map_type, key_type, val_type, size, flags) \
struct { \
__uint(type, map_type); \
__type(key, key_type); \
__type(value, val_type); \
__uint(max_entries, size); \
__uint(map_flags, flags); \
}map_symbol(name, ver) SEC(".maps"); \
MAP_LOOKUP_FN(name, ver) \
MAP_UPDATE_FN(name, ver) \
MAP_DELETE_FN(name, ver)
MAP_LOOKUP_FN(fname, name, ver) \
MAP_UPDATE_FN(fname, name, ver) \
MAP_DELETE_FN(fname, name, ver)

#define CALI_MAP(name, ver, map_type, key_type, val_type, size, flags) \
CALI_MAP_NAMED(name, name, ver, map_type, key_type, val_type, size, flags)

#define CALI_MAP_V1(name, map_type, key_type, val_type, size, flags) \
CALI_MAP(name,, map_type, key_type, val_type, size, flags)
Expand Down
2 changes: 1 addition & 1 deletion felix/bpf-gpl/calculate-flags
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ if [[ "${filename}" =~ test_.* ]]; then
args+=("-DUNITTEST")
fi

if [[ "${filename}" =~ .*_v6.o ]]; then
if [[ "${filename}" =~ .*_v6.ll ]]; then
args+=("-DIPVER6")
fi

Expand Down
15 changes: 8 additions & 7 deletions felix/bpf-gpl/connect.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "bpf.h"
#include "nat_lookup.h"

static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto, __be32 *dst, bool connect)
static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto, ipv46_addr_t *dst, bool connect)
{
int err = 0;
/* We do not know what the source address is yet, we only know that it
Expand All @@ -24,7 +24,8 @@ static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto,
nat_lookup_result res = NAT_LOOKUP_ALLOW;
__u16 dport_he = (__u16)(bpf_ntohl(ctx->user_port)>>16);
struct calico_nat_dest *nat_dest;
nat_dest = calico_v4_nat_lookup(0, *dst, proto, dport_he, false, &res,
ipv46_addr_t voidip = VOID_IP;
nat_dest = calico_nat_lookup(&voidip, dst, proto, dport_he, false, &res,
proto == IPPROTO_UDP && !connect ? CTLB_UDP_NOT_SEEN_TIMEO : 0, /* enforce affinity UDP */
proto == IPPROTO_UDP && !connect /* update affinity timer */);
if (!nat_dest) {
Expand All @@ -49,11 +50,11 @@ static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto,
.port = dport_be,
.proto = proto,
};
struct sendrecv4_val val = {
struct sendrec_val val = {
.ip = *dst,
.port = ctx->user_port,
};
int rc = cali_v4_ct_nats_update_elem(&natk, &val, 0);
int rc = cali_ct_nats_update_elem(&natk, &val, 0);
if (rc) {
/* if this happens things are really bad! report */
CALI_INFO("Failed to update ct_nats map rc=%d\n", rc);
Expand All @@ -65,13 +66,13 @@ static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto,
__u64 cookie = bpf_get_socket_cookie(ctx);
CALI_DEBUG("Store: ip=%x port=%d cookie=%x\n",
bpf_ntohl(nat_dest->addr), bpf_ntohs((__u16)dport_be), cookie);
struct sendrecv4_key key = {
struct sendrec_key key = {
.ip = nat_dest->addr,
.port = dport_be,
.cookie = cookie,
};

if (cali_v4_srmsg_update_elem(&key, &val, 0)) {
if (cali_srmsg_update_elem(&key, &val, 0)) {
/* if this happens things are really bad! report */
CALI_INFO("Failed to update map\n");
goto out;
Expand All @@ -85,7 +86,7 @@ static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto,
return err;
}

static CALI_BPF_INLINE int connect_v4(struct bpf_sock_addr *ctx, __be32 *dst)
static CALI_BPF_INLINE int connect_v4(struct bpf_sock_addr *ctx, ipv46_addr_t *dst)
{
int ret = 1; /* OK value */

Expand Down
4 changes: 2 additions & 2 deletions felix/bpf-gpl/connect_balancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ int calico_recvmsg_v4(struct bpf_sock_addr *ctx)

__u64 cookie = bpf_get_socket_cookie(ctx);
CALI_DEBUG("Lookup: ip=%x port=%d(BE) cookie=%x\n",ctx->user_ip4, ctx->user_port, cookie);
struct sendrecv4_key key = {
struct sendrec_key key = {
.ip = ctx->user_ip4,
.port = ctx->user_port,
.cookie = cookie,
};

struct sendrecv4_val *revnat = cali_v4_srmsg_lookup_elem(&key);
struct sendrec_val *revnat = cali_srmsg_lookup_elem(&key);

if (revnat == NULL) {
CALI_DEBUG("revnat miss for %x:%d\n",
Expand Down
6 changes: 4 additions & 2 deletions felix/bpf-gpl/connect_balancer_v6.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright (c) 2020-2022 Tigera, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later

#undef IPVER6 /* XXX */

#include <linux/bpf.h>

// socket_type.h contains the definition of SOCK_XXX constants that we need
Expand Down Expand Up @@ -98,13 +100,13 @@ int calico_recvmsg_v6(struct bpf_sock_addr *ctx)
goto out;
}

struct sendrecv4_key key = {
struct sendrec_key key = {
.ip = ipv4,
.port = ctx->user_port,
.cookie = bpf_get_socket_cookie(ctx),
};

struct sendrecv4_val *revnat = cali_v4_srmsg_lookup_elem(&key);
struct sendrec_val *revnat = cali_srmsg_lookup_elem(&key);

if (revnat == NULL) {
CALI_DEBUG("revnat miss for %x:%d\n",
Expand Down
Loading

0 comments on commit f1807de

Please sign in to comment.