|
9 | 9 | #define ping_cmd "ping -q -c1 -w1 127.0.0.1 > /dev/null"
|
10 | 10 |
|
11 | 11 | #include "test_tc_link.skel.h"
|
| 12 | + |
| 13 | +#include "netlink_helpers.h" |
12 | 14 | #include "tc_helpers.h"
|
13 | 15 |
|
14 | 16 | void serial_test_tc_links_basic(void)
|
@@ -1787,6 +1789,65 @@ void serial_test_tc_links_ingress(void)
|
1787 | 1789 | test_tc_links_ingress(BPF_TCX_INGRESS, false, false);
|
1788 | 1790 | }
|
1789 | 1791 |
|
| 1792 | +struct qdisc_req { |
| 1793 | + struct nlmsghdr n; |
| 1794 | + struct tcmsg t; |
| 1795 | + char buf[1024]; |
| 1796 | +}; |
| 1797 | + |
| 1798 | +static int qdisc_replace(int ifindex, const char *kind, bool block) |
| 1799 | +{ |
| 1800 | + struct rtnl_handle rth = { .fd = -1 }; |
| 1801 | + struct qdisc_req req; |
| 1802 | + int err; |
| 1803 | + |
| 1804 | + err = rtnl_open(&rth, 0); |
| 1805 | + if (!ASSERT_OK(err, "open_rtnetlink")) |
| 1806 | + return err; |
| 1807 | + |
| 1808 | + memset(&req, 0, sizeof(req)); |
| 1809 | + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); |
| 1810 | + req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REPLACE | NLM_F_REQUEST; |
| 1811 | + req.n.nlmsg_type = RTM_NEWQDISC; |
| 1812 | + req.t.tcm_family = AF_UNSPEC; |
| 1813 | + req.t.tcm_ifindex = ifindex; |
| 1814 | + req.t.tcm_parent = 0xfffffff1; |
| 1815 | + |
| 1816 | + addattr_l(&req.n, sizeof(req), TCA_KIND, kind, strlen(kind) + 1); |
| 1817 | + if (block) |
| 1818 | + addattr32(&req.n, sizeof(req), TCA_INGRESS_BLOCK, 1); |
| 1819 | + |
| 1820 | + err = rtnl_talk(&rth, &req.n, NULL); |
| 1821 | + ASSERT_OK(err, "talk_rtnetlink"); |
| 1822 | + rtnl_close(&rth); |
| 1823 | + return err; |
| 1824 | +} |
| 1825 | + |
| 1826 | +void serial_test_tc_links_dev_chain0(void) |
| 1827 | +{ |
| 1828 | + int err, ifindex; |
| 1829 | + |
| 1830 | + ASSERT_OK(system("ip link add dev foo type veth peer name bar"), "add veth"); |
| 1831 | + ifindex = if_nametoindex("foo"); |
| 1832 | + ASSERT_NEQ(ifindex, 0, "non_zero_ifindex"); |
| 1833 | + err = qdisc_replace(ifindex, "ingress", true); |
| 1834 | + if (!ASSERT_OK(err, "attaching ingress")) |
| 1835 | + goto cleanup; |
| 1836 | + ASSERT_OK(system("tc filter add block 1 matchall action skbmod swap mac"), "add block"); |
| 1837 | + err = qdisc_replace(ifindex, "clsact", false); |
| 1838 | + if (!ASSERT_OK(err, "attaching clsact")) |
| 1839 | + goto cleanup; |
| 1840 | + /* Heuristic: kern_sync_rcu() alone does not work; a wait-time of ~5s |
| 1841 | + * triggered the issue without the fix reliably 100% of the time. |
| 1842 | + */ |
| 1843 | + sleep(5); |
| 1844 | + ASSERT_OK(system("tc filter add dev foo ingress matchall action skbmod swap mac"), "add filter"); |
| 1845 | +cleanup: |
| 1846 | + ASSERT_OK(system("ip link del dev foo"), "del veth"); |
| 1847 | + ASSERT_EQ(if_nametoindex("foo"), 0, "foo removed"); |
| 1848 | + ASSERT_EQ(if_nametoindex("bar"), 0, "bar removed"); |
| 1849 | +} |
| 1850 | + |
1790 | 1851 | static void test_tc_links_dev_mixed(int target)
|
1791 | 1852 | {
|
1792 | 1853 | LIBBPF_OPTS(bpf_tc_opts, tc_opts, .handle = 1, .priority = 1);
|
|
0 commit comments