Skip to content

Commit

Permalink
ipv6
Browse files Browse the repository at this point in the history
Signed-off-by: Geliang Tang <[email protected]>
  • Loading branch information
Geliang Tang committed Oct 12, 2024
1 parent f1ae111 commit 67d4f46
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 7 deletions.
13 changes: 13 additions & 0 deletions net/mptcp/bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,17 @@ __bpf_kfunc __u8 bpf_next_bit(struct mptcp_id_bitmap *bitmap)
return find_next_zero_bit(bitmap->map, MPTCP_PM_MAX_ADDR_ID + 1, 1);
}

__bpf_kfunc bool bpf_ipv6_addr_v4mapped(const struct mptcp_addr_info *a)
{
return ipv6_addr_v4mapped(&a->addr6);
}

__bpf_kfunc void bpf_ipv6_addr_set_v4mapped(const __be32 addr,
struct mptcp_addr_info *v4mapped)
{
ipv6_addr_set_v4mapped(addr, &v4mapped->addr6);
}

__bpf_kfunc bool bpf_mptcp_subflow_queues_empty(struct sock *sk)
{
return tcp_rtx_queue_empty(sk);
Expand Down Expand Up @@ -666,6 +677,8 @@ BTF_ID_FLAGS(func, bpf_bitmap_zero)
BTF_ID_FLAGS(func, bpf_test_bit)
BTF_ID_FLAGS(func, bpf_set_bit)
BTF_ID_FLAGS(func, bpf_next_bit)
BTF_ID_FLAGS(func, bpf_ipv6_addr_v4mapped)
BTF_ID_FLAGS(func, bpf_ipv6_addr_set_v4mapped)
BTF_ID_FLAGS(func, mptcp_pm_remove_addr)
BTF_ID_FLAGS(func, mptcp_pm_remove_addr_entry, KF_SLEEPABLE)
BTF_ID_FLAGS(func, __mptcp_subflow_connect, KF_SLEEPABLE)
Expand Down
17 changes: 10 additions & 7 deletions tools/testing/selftests/bpf/prog_tests/mptcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@ static int userspace_pm_dump_addr(char *output)
if (!ASSERT_STRNEQ(buf, output, sizeof(buf), "dump_addr"))
return -1;

printf("\n\n\n\ndump: %s\n\n", buf);
return 0;
}

Expand Down Expand Up @@ -893,7 +894,7 @@ static int userspace_pm_rm_addr(__u8 id)
return 0;
}

static void run_userspace_pm(void)
static void run_userspace_pm(bool ipv6)
{
int server_fd, client_fd, accept_fd;
int err;
Expand Down Expand Up @@ -950,14 +951,15 @@ static void run_userspace_pm(void)
send_byte(accept_fd);
recv_byte(client_fd);

err = userspace_pm_add_addr(ADDR_3, 200);
err = userspace_pm_add_addr(ipv6 ? ADDR6_3 : ADDR_3, 200);
if (!ASSERT_OK(err, "userspace_pm_add_addr"))
goto close_accept;

send_byte(accept_fd);
recv_byte(client_fd);

err = userspace_pm_dump_addr("id 200 flags signal 10.0.1.3\n");
err = userspace_pm_dump_addr(ipv6 ? "id 200 flags signal dead:beef:1::3\n" :
"id 200 flags signal 10.0.1.3\n");
if (!ASSERT_OK(err, "userspace_pm_dump_addr"))
goto close_accept;

Expand Down Expand Up @@ -995,14 +997,14 @@ static void test_userspace_pm(void)
if (!ASSERT_OK(err, "userspace_pm_init: userspace pm"))
goto fail;

run_userspace_pm();
run_userspace_pm(false);

userspace_pm_cleanup();
fail:
cleanup_netns(nstoken);
}

static void test_bpf_pm(struct bpf_object *obj, char *pm)
static void test_bpf_pm(struct bpf_object *obj, char *pm, bool ipv6)
{
struct nstoken *nstoken;
struct bpf_link *link;
Expand All @@ -1022,7 +1024,7 @@ static void test_bpf_pm(struct bpf_object *obj, char *pm)
if (!ASSERT_OK(err, "userspace_pm_init: bpf pm"))
goto close_netns;

run_userspace_pm();
run_userspace_pm(ipv6);

userspace_pm_cleanup();
close_netns:
Expand Down Expand Up @@ -1062,7 +1064,8 @@ static void test_userspace_bpf(void)
if (!ASSERT_OK(mptcp_bpf_userspace_pm__load(skel), "load: userspace_pm"))
goto fail;

test_bpf_pm(skel->obj, "userspace_pm");
//test_bpf_pm(skel->obj, "userspace_pm", skel->kconfig->CONFIG_MPTCP_IPV6);
test_bpf_pm(skel->obj, "userspace_pm", 1);

fail:
mptcp_bpf_userspace_pm__destroy(skel);
Expand Down
14 changes: 14 additions & 0 deletions tools/testing/selftests/bpf/progs/mptcp_bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#ifndef __MPTCP_BPF_H__
#define __MPTCP_BPF_H__

#include <string.h>
#include "bpf_experimental.h"

/* mptcp helpers from include/net/mptcp.h */
Expand All @@ -23,6 +24,9 @@
#define ENOMEM 12 /* Out of Memory */
#define EINVAL 22 /* Invalid argument */

#define sk_ipv6only __sk_common.skc_ipv6only
#define ipv6_only_sock(sk) (sk->sk_ipv6only)

/* list helpers from include/linux/list.h */
static inline int list_is_head(const struct list_head *list,
const struct list_head *head)
Expand Down Expand Up @@ -55,6 +59,12 @@ static inline int list_is_head(const struct list_head *list,
#define mptcp_for_each_address(__msk, __entry) \
list_for_each_entry(__entry, &((__msk)->pm.userspace_pm_local_addr_list), list)

#define ipv6_addr_equal(a1, a2) ((a1).s6_addr32[0] == (a2).s6_addr32[0] && \
(a1).s6_addr32[1] == (a2).s6_addr32[1] && \
(a1).s6_addr32[2] == (a2).s6_addr32[2] && \
(a1).s6_addr32[3] == (a2).s6_addr32[3])
#define ipv6_addr_cmp(a1, a2) memcmp((a1), (a2), sizeof(struct in6_addr));

static __always_inline struct sock *
mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow)
{
Expand Down Expand Up @@ -99,6 +109,10 @@ extern bool bpf_test_bit(u8 nr, struct mptcp_id_bitmap *bitmap) __ksym;
extern void bpf_set_bit(u8 nr, struct mptcp_id_bitmap *bitmap) __ksym;
extern u8 bpf_next_bit(struct mptcp_id_bitmap *bitmap) __ksym;

extern bool bpf_ipv6_addr_v4mapped(const struct mptcp_addr_info *a) __ksym;
extern void bpf_ipv6_addr_set_v4mapped(const __be32 addr,
struct mptcp_addr_info *v4mapped) __ksym;

extern int mptcp_pm_remove_addr(struct mptcp_sock *msk,
const struct mptcp_rm_list *rm_list) __ksym;
extern void mptcp_pm_remove_addr_entry(struct mptcp_sock *msk,
Expand Down
45 changes: 45 additions & 0 deletions tools/testing/selftests/bpf/progs/mptcp_bpf_userspace_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "bpf_tracing_net.h"
#include "mptcp_bpf.h"

extern bool CONFIG_MPTCP_IPV6 __kconfig __weak;
char _license[] SEC("license") = "GPL";

SEC("struct_ops")
Expand All @@ -24,6 +25,16 @@ static bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
if (a->family == b->family) {
if (a->family == AF_INET)
addr_equals = a->addr.s_addr == b->addr.s_addr;
#if CONFIG_MPTCP_IPV6
else
addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6);
} else if (a->family == AF_INET) {
if (bpf_ipv6_addr_v4mapped(b))
addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3];
} else if (b->family == AF_INET) {
if (bpf_ipv6_addr_v4mapped(a))
addr_equals = a->addr6.s6_addr32[3] == b->addr.s_addr;
#endif
}

if (!addr_equals)
Expand Down Expand Up @@ -179,7 +190,20 @@ static bool mptcp_pm_addr_families_match(const struct sock *sk,
{
bool mptcp_is_v4 = sk->sk_family == AF_INET;

#if CONFIG_MPTCP_IPV6
bool loc_is_v4 = loc->family == AF_INET || bpf_ipv6_addr_v4mapped(loc);
bool rem_is_v4 = rem->family == AF_INET || bpf_ipv6_addr_v4mapped(rem);

if (mptcp_is_v4)
return loc_is_v4 && rem_is_v4;

if (ipv6_only_sock(sk))
return !loc_is_v4 && !rem_is_v4;

return loc_is_v4 == rem_is_v4;
#else
return mptcp_is_v4 && loc->family == AF_INET && rem->family == AF_INET;
#endif
}

static struct mptcp_pm_addr_entry *
Expand Down Expand Up @@ -267,6 +291,16 @@ static struct sock *mptcp_pm_find_ssk(struct mptcp_sock *msk,
issk->inet_daddr != remote->addr.s_addr)
continue;
break;
#if CONFIG_MPTCP_IPV6
case AF_INET6: {
const struct ipv6_pinfo *pinfo = bpf_core_cast(ssk, struct ipv6_pinfo);

if (!ipv6_addr_equal(local->addr6, pinfo->saddr) ||
!ipv6_addr_equal(remote->addr6, ssk->sk_v6_daddr))
continue;
break;
}
#endif
default:
continue;
}
Expand All @@ -287,6 +321,17 @@ int BPF_PROG(mptcp_pm_subflow_destroy, struct mptcp_sock *msk,
int err = -EINVAL;
struct sock *ssk;

#if CONFIG_MPTCP_IPV6
if (local->addr.family == AF_INET && bpf_ipv6_addr_v4mapped(remote)) {
bpf_ipv6_addr_set_v4mapped(local->addr.addr.s_addr, remote);
local->addr.family = AF_INET6;
}
if (remote->family == AF_INET && bpf_ipv6_addr_v4mapped(&local->addr)) {
bpf_ipv6_addr_set_v4mapped(remote->addr.s_addr, &local->addr);
remote->family = AF_INET6;
}
#endif

if (local->addr.family != remote->family)
return err;

Expand Down
1 change: 1 addition & 0 deletions tools/testing/selftests/bpf/progs/test_fill_link_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdbool.h>

extern bool CONFIG_X86_KERNEL_IBT __kconfig __weak;
extern bool CONFIG_MPTCP_IPV6 __kconfig __weak;

/* This function is here to have CONFIG_X86_KERNEL_IBT
* used and added to object BTF.
Expand Down

0 comments on commit 67d4f46

Please sign in to comment.