brintos

brintos / linux-shallow public Read only

0
0
Text · 4.7 KiB · e7e9f3c Raw
153 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2020 Facebook */3#include <uapi/linux/if_link.h>4#include <test_progs.h>5#include "test_xdp_link.skel.h"6 7#define IFINDEX_LO 18 9void serial_test_xdp_link(void)10{11	struct test_xdp_link *skel1 = NULL, *skel2 = NULL;12	__u32 id1, id2, id0 = 0, prog_fd1, prog_fd2;13	LIBBPF_OPTS(bpf_xdp_attach_opts, opts);14	struct bpf_link_info link_info;15	struct bpf_prog_info prog_info;16	struct bpf_link *link;17	int err;18	__u32 link_info_len = sizeof(link_info);19	__u32 prog_info_len = sizeof(prog_info);20 21	skel1 = test_xdp_link__open_and_load();22	if (!ASSERT_OK_PTR(skel1, "skel_load"))23		goto cleanup;24	prog_fd1 = bpf_program__fd(skel1->progs.xdp_handler);25 26	skel2 = test_xdp_link__open_and_load();27	if (!ASSERT_OK_PTR(skel2, "skel_load"))28		goto cleanup;29	prog_fd2 = bpf_program__fd(skel2->progs.xdp_handler);30 31	memset(&prog_info, 0, sizeof(prog_info));32	err = bpf_prog_get_info_by_fd(prog_fd1, &prog_info, &prog_info_len);33	if (!ASSERT_OK(err, "fd_info1"))34		goto cleanup;35	id1 = prog_info.id;36 37	memset(&prog_info, 0, sizeof(prog_info));38	err = bpf_prog_get_info_by_fd(prog_fd2, &prog_info, &prog_info_len);39	if (!ASSERT_OK(err, "fd_info2"))40		goto cleanup;41	id2 = prog_info.id;42 43	/* set initial prog attachment */44	err = bpf_xdp_attach(IFINDEX_LO, prog_fd1, XDP_FLAGS_REPLACE, &opts);45	if (!ASSERT_OK(err, "fd_attach"))46		goto cleanup;47 48	/* validate prog ID */49	err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);50	if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))51		goto cleanup;52 53	/* BPF link is not allowed to replace prog attachment */54	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);55	if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {56		bpf_link__destroy(link);57		/* best-effort detach prog */58		opts.old_prog_fd = prog_fd1;59		bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);60		goto cleanup;61	}62 63	/* detach BPF program */64	opts.old_prog_fd = prog_fd1;65	err = bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);66	if (!ASSERT_OK(err, "prog_detach"))67		goto cleanup;68 69	/* now BPF link should attach successfully */70	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);71	if (!ASSERT_OK_PTR(link, "link_attach"))72		goto cleanup;73	skel1->links.xdp_handler = link;74 75	/* validate prog ID */76	err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);77	if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))78		goto cleanup;79 80	/* BPF prog attach is not allowed to replace BPF link */81	opts.old_prog_fd = prog_fd1;82	err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, XDP_FLAGS_REPLACE, &opts);83	if (!ASSERT_ERR(err, "prog_attach_fail"))84		goto cleanup;85 86	/* Can't force-update when BPF link is active */87	err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, 0, NULL);88	if (!ASSERT_ERR(err, "prog_update_fail"))89		goto cleanup;90 91	/* Can't force-detach when BPF link is active */92	err = bpf_xdp_detach(IFINDEX_LO, 0, NULL);93	if (!ASSERT_ERR(err, "prog_detach_fail"))94		goto cleanup;95 96	/* BPF link is not allowed to replace another BPF link */97	link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);98	if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {99		bpf_link__destroy(link);100		goto cleanup;101	}102 103	bpf_link__destroy(skel1->links.xdp_handler);104	skel1->links.xdp_handler = NULL;105 106	/* new link attach should succeed */107	link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);108	if (!ASSERT_OK_PTR(link, "link_attach"))109		goto cleanup;110	skel2->links.xdp_handler = link;111 112	err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);113	if (!ASSERT_OK(err, "id2_check_err") || !ASSERT_EQ(id0, id2, "id2_check_val"))114		goto cleanup;115 116	/* updating program under active BPF link works as expected */117	err = bpf_link__update_program(link, skel1->progs.xdp_handler);118	if (!ASSERT_OK(err, "link_upd"))119		goto cleanup;120 121	memset(&link_info, 0, sizeof(link_info));122	err = bpf_link_get_info_by_fd(bpf_link__fd(link),123				      &link_info, &link_info_len);124	if (!ASSERT_OK(err, "link_info"))125		goto cleanup;126 127	ASSERT_EQ(link_info.type, BPF_LINK_TYPE_XDP, "link_type");128	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");129	ASSERT_EQ(link_info.xdp.ifindex, IFINDEX_LO, "link_ifindex");130 131	/* updating program under active BPF link with different type fails */132	err = bpf_link__update_program(link, skel1->progs.tc_handler);133	if (!ASSERT_ERR(err, "link_upd_invalid"))134		goto cleanup;135 136	err = bpf_link__detach(link);137	if (!ASSERT_OK(err, "link_detach"))138		goto cleanup;139 140	memset(&link_info, 0, sizeof(link_info));141	err = bpf_link_get_info_by_fd(bpf_link__fd(link),142				      &link_info, &link_info_len);143 144	ASSERT_OK(err, "link_info");145	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");146	/* ifindex should be zeroed out */147	ASSERT_EQ(link_info.xdp.ifindex, 0, "link_ifindex");148 149cleanup:150	test_xdp_link__destroy(skel1);151	test_xdp_link__destroy(skel2);152}153