Skip to content

Commit

Permalink
Merge branch 'projectcalico:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Behnam-Shobiri authored Oct 17, 2023
2 parents 3ee5f9e + 0aee31e commit 736eddf
Show file tree
Hide file tree
Showing 33 changed files with 771 additions and 389 deletions.
3 changes: 2 additions & 1 deletion felix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ protobuf proto/felixbackend.pb.go: proto/felixbackend.proto

# We pre-build lots of different variants of the TC programs, defer to the script.
BPF_GPL_O_FILES:=$(addprefix bpf-gpl/,$(shell bpf-gpl/list-objs))
BPF_GPL_O_FILES+=bpf-gpl/bin/tc_preamble.o bpf-gpl/bin/xdp_preamble.o bpf-gpl/bin/policy_default.o
BPF_GPL_O_FILES+=bpf-gpl/bin/tc_preamble.o bpf-gpl/bin/tc_preamble_v6.o \
bpf-gpl/bin/xdp_preamble.o bpf-gpl/bin/policy_default.o

# There's a one-to-one mapping from UT C files to objects and the same for the apache programs..
BPF_GPL_UT_O_FILES:=$(BPF_GPL_UT_C_FILES:.c=.o) $(addprefix bpf-gpl/,$(shell bpf-gpl/list-ut-objs))
Expand Down
10 changes: 8 additions & 2 deletions felix/bpf-gpl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@ 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 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_v46.c connect_balancer_v6.c xdp_preamble.c xdp.c policy_default.c

all: $(OBJS)
ut-objs: $(UT_OBJS)

COMPILE=$(CC) $(CFLAGS) `./calculate-flags $@` -c $< -o $@
connect_time_%v4.ll: connect_balancer.c connect_balancer.d calculate-flags
$(COMPILE)
connect_time_%v6.ll: connect_balancer_v6.c connect_balancer_v6.d calculate-flags
connect_time_%v46.ll: connect_balancer_v46.c connect_balancer_v46.d calculate-flags
$(COMPILE)
connect_time_%v6.ll: connect_balancer_v6.c connect_balancer_v6.d calculate-flags
$(COMPILE) -DIPVER6

UT_CFLAGS=\
-D__BPFTOOL_LOADER__ \
Expand Down Expand Up @@ -127,10 +129,14 @@ bin/xdp%.o: xdp%.ll | bin
$(LINK)
bin/connect_time_%v4.o: connect_time_%v4.ll | bin
$(LINK)
bin/connect_time_%v46.o: connect_time_%v46.ll | bin
$(LINK)
bin/connect_time_%v6.o: connect_time_%v6.ll | bin
$(LINK)
bin/connect_time_%v4_co-re.o: connect_time_%v4.ll | bin
$(LINK)
bin/connect_time_%v46_co-re.o: connect_time_%v46.ll | bin
$(LINK)
bin/connect_time_%v6_co-re.o: connect_time_%v6.ll | bin
$(LINK)
ut/%.o: ut/%.ll
Expand Down
5 changes: 0 additions & 5 deletions felix/bpf-gpl/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,7 @@
#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
6 changes: 3 additions & 3 deletions felix/bpf-gpl/connect.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ 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);
debug_ip(nat_dest->addr), bpf_ntohs((__u16)dport_be), cookie);

/* For all protocols, record recent NAT operations in an LRU map; other BPF programs use this
* cache to reverse our DNAT so they can do pre-DNAT policy. */
Expand All @@ -65,7 +65,7 @@ static CALI_BPF_INLINE int do_nat_common(struct bpf_sock_addr *ctx, __u8 proto,
* check the source on the return packets. */
__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);
debug_ip(nat_dest->addr), bpf_ntohs((__u16)dport_be), cookie);
struct sendrec_key key = {
.ip = nat_dest->addr,
.port = dport_be,
Expand All @@ -86,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, ipv46_addr_t *dst)
static CALI_BPF_INLINE int connect(struct bpf_sock_addr *ctx, ipv46_addr_t *dst)
{
int ret = 1; /* OK value */

Expand Down
2 changes: 1 addition & 1 deletion felix/bpf-gpl/connect_balancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int calico_connect_v4(struct bpf_sock_addr *ctx)
{
CALI_DEBUG("calico_connect_v4\n");

return connect_v4(ctx, &ctx->user_ip4);
return connect(ctx, &ctx->user_ip4);
}

SEC("cgroup/sendmsg4")
Expand Down
127 changes: 127 additions & 0 deletions felix/bpf-gpl/connect_balancer_v46.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Project Calico BPF dataplane programs.
// Copyright (c) 2020-2022 Tigera, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later

#include <linux/bpf.h>

// socket_type.h contains the definition of SOCK_XXX constants that we need
// but it's supposed to be imported via socket.h, which we can't import due
// to lack of std lib support for BPF. Bypass its check for now.
#define _SYS_SOCKET_H
#include <bits/socket_type.h>

#include <stdbool.h>

#include "bpf.h"
#include "log.h"
#include "globals.h"
#include "ctlb.h"

#include "sendrecv.h"
#include "connect.h"

SEC("cgroup/connect6")
int calico_connect_v46(struct bpf_sock_addr *ctx)
{
int ret = 1;
__be32 ipv4;

CALI_DEBUG("connect_v46 ip[0-1] %x%x\n",
ctx->user_ip6[0],
ctx->user_ip6[1]);
CALI_DEBUG("connect_v46 ip[2-3] %x%x\n",
ctx->user_ip6[2],
ctx->user_ip6[3]);

/* check if it is a IPv4 mapped as IPv6 and if so, use the v4 table */
if (ctx->user_ip6[0] == 0 && ctx->user_ip6[1] == 0 &&
ctx->user_ip6[2] == bpf_htonl(0x0000ffff)) {
goto v4;
}

CALI_DEBUG("connect_v46: not implemented for v6 yet\n");
goto out;

v4:
ipv4 = ctx->user_ip6[3];

if ((ret = connect(ctx, &ipv4)) != 1) {
goto out;
}

ctx->user_ip6[3] = ipv4;

out:
return ret;
}

SEC("cgroup/sendmsg6")
int calico_sendmsg_v46(struct bpf_sock_addr *ctx)
{
CALI_DEBUG("sendmsg_v46\n");

return 1;
}

SEC("cgroup/recvmsg6")
int calico_recvmsg_v46(struct bpf_sock_addr *ctx)
{
if (CTLB_EXCLUDE_UDP) {
goto out;
}

__be32 ipv4;

CALI_DEBUG("recvmsg_v46 ip[0-1] %x%x\n",
ctx->user_ip6[0],
ctx->user_ip6[1]);
CALI_DEBUG("recvmsg_v46 ip[2-3] %x%x\n",
ctx->user_ip6[2],
ctx->user_ip6[3]);

/* check if it is a IPv4 mapped as IPv6 and if so, use the v4 table */
if (ctx->user_ip6[0] == 0 && ctx->user_ip6[1] == 0 &&
ctx->user_ip6[2] == bpf_htonl(0x0000ffff)) {
goto v4;
}

CALI_DEBUG("recvmsg_v46: not implemented for v6 yet\n");
goto out;


v4:
ipv4 = ctx->user_ip6[3];
CALI_DEBUG("recvmsg_v46 %x:%d\n", bpf_ntohl(ipv4), ctx_port_to_host(ctx->user_port));

if (ctx->type != SOCK_DGRAM) {
CALI_INFO("unexpected sock type %d\n", ctx->type);
goto out;
}

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

struct sendrec_val *revnat = cali_srmsg_lookup_elem(&key);

if (revnat == NULL) {
CALI_DEBUG("revnat miss for %x:%d\n",
bpf_ntohl(ipv4), ctx_port_to_host(ctx->user_port));
/* we are past policy and the packet was allowed. Either the
* mapping does not exist anymore and if the app cares, it
* should check the addresses. It is more likely a packet sent
* to server from outside and no mapping is expected.
*/
goto out;
}

ctx->user_ip6[3] = revnat->ip;
ctx->user_port = revnat->port;
CALI_DEBUG("recvmsg_v46 v4 rev nat to %x:%d\n",
bpf_ntohl(ipv4), ctx_port_to_host(ctx->user_port));

out:
return 1;
}
91 changes: 33 additions & 58 deletions felix/bpf-gpl/connect_balancer_v6.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// 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 All @@ -15,53 +13,49 @@
#include <stdbool.h>

#include "bpf.h"
#include "log.h"
#include "globals.h"
#include "ctlb.h"
#include "log.h"

#include "sendrecv.h"
#include "connect.h"

SEC("cgroup/connect6")
int calico_connect_v6(struct bpf_sock_addr *ctx)
{
int ret = 1;
__be32 ipv4;

CALI_DEBUG("connect_v6 ip[0-1] %x%x\n",
ctx->user_ip6[0],
ctx->user_ip6[1]);
CALI_DEBUG("connect_v6 ip[2-3] %x%x\n",
ctx->user_ip6[2],
ctx->user_ip6[3]);

/* check if it is a IPv4 mapped as IPv6 and if so, use the v4 table */
if (ctx->user_ip6[0] == 0 && ctx->user_ip6[1] == 0 &&
ctx->user_ip6[2] == bpf_htonl(0x0000ffff)) {
goto v4;
}
CALI_DEBUG("calico_connect_v6\n");

CALI_DEBUG("connect_v6: not implemented for v6 yet\n");
goto out;

v4:
ipv4 = ctx->user_ip6[3];

if ((ret = connect_v4(ctx, &ipv4)) != 1) {
goto out;
}
ipv46_addr_t dst = {};
be32_4_ip_to_ipv6_addr_t(&dst, ctx->user_ip6);

ctx->user_ip6[3] = ipv4;
int ret = connect(ctx, &dst);
ipv6_addr_t_to_be32_4_ip(ctx->user_ip6, &dst);

out:
return ret;
}

SEC("cgroup/sendmsg6")
int calico_sendmsg_v6(struct bpf_sock_addr *ctx)
{
CALI_DEBUG("sendmsg_v6\n");
if (CTLB_EXCLUDE_UDP) {
goto out;
}

CALI_DEBUG("sendmsg_v6 %x:%d\n",
bpf_ntohl(ctx->user_ip6[3]), bpf_ntohl(ctx->user_port)>>16);

if (ctx->type != SOCK_DGRAM) {
CALI_INFO("unexpected sock type %d\n", ctx->type);
goto out;
}

ipv46_addr_t dst = {};
be32_4_ip_to_ipv6_addr_t(&dst, ctx->user_ip6);

do_nat_common(ctx, IPPROTO_UDP, &dst, false);
ipv6_addr_t_to_be32_4_ip(ctx->user_ip6, &dst);

out:
return 1;
}

Expand All @@ -72,45 +66,26 @@ int calico_recvmsg_v6(struct bpf_sock_addr *ctx)
goto out;
}

__be32 ipv4;

CALI_DEBUG("recvmsg_v6 ip[0-1] %x%x\n",
ctx->user_ip6[0],
ctx->user_ip6[1]);
CALI_DEBUG("recvmsg_v6 ip[2-3] %x%x\n",
ctx->user_ip6[2],
ctx->user_ip6[3]);

/* check if it is a IPv4 mapped as IPv6 and if so, use the v4 table */
if (ctx->user_ip6[0] == 0 && ctx->user_ip6[1] == 0 &&
ctx->user_ip6[2] == bpf_htonl(0x0000ffff)) {
goto v4;
}

CALI_DEBUG("recvmsg_v6: not implemented for v6 yet\n");
goto out;


v4:
ipv4 = ctx->user_ip6[3];
CALI_DEBUG("recvmsg_v6 %x:%d\n", bpf_ntohl(ipv4), ctx_port_to_host(ctx->user_port));
CALI_DEBUG("recvmsg_v6 %x:%d\n", bpf_ntohl(ctx->user_ip6[3]), ctx_port_to_host(ctx->user_port));

if (ctx->type != SOCK_DGRAM) {
CALI_INFO("unexpected sock type %d\n", ctx->type);
goto out;
}

__u64 cookie = bpf_get_socket_cookie(ctx);
CALI_DEBUG("Lookup: ip=%x port=%d(BE) cookie=%x\n", bpf_ntohl(ctx->user_ip6[3]), ctx->user_port, cookie);
struct sendrec_key key = {
.ip = ipv4,
.port = ctx->user_port,
.cookie = bpf_get_socket_cookie(ctx),
.cookie = cookie,
};
be32_4_ip_to_ipv6_addr_t(&key.ip, ctx->user_ip6);

struct sendrec_val *revnat = cali_srmsg_lookup_elem(&key);

if (revnat == NULL) {
CALI_DEBUG("revnat miss for %x:%d\n",
bpf_ntohl(ipv4), ctx_port_to_host(ctx->user_port));
bpf_ntohl(ctx->user_ip6[3]), ctx_port_to_host(ctx->user_port));
/* we are past policy and the packet was allowed. Either the
* mapping does not exist anymore and if the app cares, it
* should check the addresses. It is more likely a packet sent
Expand All @@ -119,10 +94,10 @@ int calico_recvmsg_v6(struct bpf_sock_addr *ctx)
goto out;
}

ctx->user_ip6[3] = revnat->ip;
ipv6_addr_t_to_be32_4_ip(ctx->user_ip6, &revnat->ip);
ctx->user_port = revnat->port;
CALI_DEBUG("recvmsg_v6 v4 rev nat to %x:%d\n",
bpf_ntohl(ipv4), ctx_port_to_host(ctx->user_port));
CALI_DEBUG("recvmsg_v6 rev nat to %x:%d\n",
bpf_ntohl(ctx->user_ip6[3]), ctx_port_to_host(ctx->user_port));

out:
return 1;
Expand Down
Loading

0 comments on commit 736eddf

Please sign in to comment.