Adding a socket to both sockmap and kcm is not supported due to collision on sk_user_data usage.
If selftests is run without KCM support we will issue a warning and continue with the tests. Signed-off-by: John Fastabend <john.fastab...@gmail.com> --- tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/sockmap_kcm.c | 14 +++++++ tools/testing/selftests/bpf/test_maps.c | 64 ++++++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/bpf/sockmap_kcm.c diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index d99dd6f..f290554 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \ test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ - sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \ + sockmap_verdict_prog.o sockmap_kcm.o dev_cgroup.o sample_ret0.o test_tracepoint.o \ test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \ sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \ diff --git a/tools/testing/selftests/bpf/sockmap_kcm.c b/tools/testing/selftests/bpf/sockmap_kcm.c new file mode 100644 index 0000000..4377adc --- /dev/null +++ b/tools/testing/selftests/bpf/sockmap_kcm.c @@ -0,0 +1,14 @@ +#include <linux/bpf.h> +#include "bpf_helpers.h" +#include "bpf_util.h" +#include "bpf_endian.h" + +int _version SEC("version") = 1; + +SEC("socket_kcm") +int bpf_prog1(struct __sk_buff *skb) +{ + return skb->len; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index 9b552c0..be20f1d 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c @@ -20,6 +20,7 @@ #include <sys/socket.h> #include <netinet/in.h> #include <linux/bpf.h> +#include <linux/kcm.h> #include <bpf/bpf.h> #include <bpf/libbpf.h> @@ -479,14 +480,16 @@ static void test_devmap(int task, void *data) #define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o" #define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o" #define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o" +#define KCM_PROG "./sockmap_kcm.o" static void test_sockmap(int tasks, void *data) { struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break; - int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break; + int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break, kcm; int ports[] = {50200, 50201, 50202, 50204}; int err, i, fd, udp, sfd[6] = {0xdeadbeef}; u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; - int parse_prog, verdict_prog, msg_prog; + int parse_prog, verdict_prog, msg_prog, kcm_prog; + struct kcm_attach attach_info; struct sockaddr_in addr; int one = 1, s, sc, rc; struct bpf_object *obj; @@ -744,6 +747,62 @@ static void test_sockmap(int tasks, void *data) goto out_sockmap; } + /* Test adding a KCM socket into map */ +#define AF_KCM 41 + kcm = socket(AF_KCM, SOCK_DGRAM, KCMPROTO_CONNECTED); + if (kcm == -1) { + printf("Warning, KCM+Sockmap could not be tested.\n"); + goto skip_kcm; + } + + err = bpf_prog_load(KCM_PROG, + BPF_PROG_TYPE_SOCKET_FILTER, + &obj, &kcm_prog); + if (err) { + printf("Failed to load SK_SKB parse prog\n"); + goto out_sockmap; + } + + i = 2; + memset(&attach_info, 0, sizeof(attach_info)); + attach_info.fd = sfd[i]; + attach_info.bpf_fd = kcm_prog; + err = ioctl(kcm, SIOCKCMATTACH, &attach_info); + if (!err) { + perror("Failed KCM attached to sockmap fd: "); + goto out_sockmap; + } + + err = bpf_map_delete_elem(fd, &i); + if (err) { + printf("Failed delete sockmap from empty map %i %i\n", err, errno); + goto out_sockmap; + } + + err = ioctl(kcm, SIOCKCMATTACH, &attach_info); + if (err) { + perror("Failed KCM attach"); + goto out_sockmap; + } + + err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); + if (!err) { + printf("Failed sockmap attached KCM sock!\n"); + goto out_sockmap; + } + err = ioctl(kcm, SIOCKCMUNATTACH, &attach_info); + if (err) { + printf("Failed detach KCM sock!\n"); + goto out_sockmap; + } + + err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); + if (err) { + printf("Failed post-kcm update sockmap '%i:%i'\n", + i, sfd[i]); + goto out_sockmap; + } + /* Test map update elem afterwards fd lives in fd and map_fd */ for (i = 2; i < 6; i++) { err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY); @@ -776,6 +835,7 @@ static void test_sockmap(int tasks, void *data) } } +skip_kcm: /* Put sfd[2] (sending fd below) into msg map to test sendmsg bpf */ i = 0; err = bpf_map_update_elem(map_fd_msg, &i, &sfd[2], BPF_ANY); -- 1.9.1