1*beb3c672SD. Wythe // SPDX-License-Identifier: GPL-2.0 2*beb3c672SD. Wythe #include <test_progs.h> 3*beb3c672SD. Wythe #include <linux/genetlink.h> 4*beb3c672SD. Wythe #include "network_helpers.h" 5*beb3c672SD. Wythe #include "bpf_smc.skel.h" 6*beb3c672SD. Wythe 7*beb3c672SD. Wythe #ifndef IPPROTO_SMC 8*beb3c672SD. Wythe #define IPPROTO_SMC 256 9*beb3c672SD. Wythe #endif 10*beb3c672SD. Wythe 11*beb3c672SD. Wythe #define CLIENT_IP "127.0.0.1" 12*beb3c672SD. Wythe #define SERVER_IP "127.0.1.0" 13*beb3c672SD. Wythe #define SERVER_IP_VIA_RISK_PATH "127.0.2.0" 14*beb3c672SD. Wythe 15*beb3c672SD. Wythe #define SERVICE_1 80 16*beb3c672SD. Wythe #define SERVICE_2 443 17*beb3c672SD. Wythe #define SERVICE_3 8443 18*beb3c672SD. Wythe 19*beb3c672SD. Wythe #define TEST_NS "bpf_smc_netns" 20*beb3c672SD. Wythe 21*beb3c672SD. Wythe static struct netns_obj *test_netns; 22*beb3c672SD. Wythe 23*beb3c672SD. Wythe struct smc_policy_ip_key { 24*beb3c672SD. Wythe __u32 sip; 25*beb3c672SD. Wythe __u32 dip; 26*beb3c672SD. Wythe }; 27*beb3c672SD. Wythe 28*beb3c672SD. Wythe struct smc_policy_ip_value { 29*beb3c672SD. Wythe __u8 mode; 30*beb3c672SD. Wythe }; 31*beb3c672SD. Wythe 32*beb3c672SD. Wythe #if defined(__s390x__) 33*beb3c672SD. Wythe /* s390x has default seid */ 34*beb3c672SD. Wythe static bool setup_ueid(void) { return true; } 35*beb3c672SD. Wythe static void cleanup_ueid(void) {} 36*beb3c672SD. Wythe #else 37*beb3c672SD. Wythe enum { 38*beb3c672SD. Wythe SMC_NETLINK_ADD_UEID = 10, 39*beb3c672SD. Wythe SMC_NETLINK_REMOVE_UEID 40*beb3c672SD. Wythe }; 41*beb3c672SD. Wythe 42*beb3c672SD. Wythe enum { 43*beb3c672SD. Wythe SMC_NLA_EID_TABLE_UNSPEC, 44*beb3c672SD. Wythe SMC_NLA_EID_TABLE_ENTRY, /* string */ 45*beb3c672SD. Wythe }; 46*beb3c672SD. Wythe 47*beb3c672SD. Wythe struct msgtemplate { 48*beb3c672SD. Wythe struct nlmsghdr n; 49*beb3c672SD. Wythe struct genlmsghdr g; 50*beb3c672SD. Wythe char buf[1024]; 51*beb3c672SD. Wythe }; 52*beb3c672SD. Wythe 53*beb3c672SD. Wythe #define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN)) 54*beb3c672SD. Wythe #define GENLMSG_PAYLOAD(glh) (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN) 55*beb3c672SD. Wythe #define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN)) 56*beb3c672SD. Wythe #define NLA_PAYLOAD(len) ((len) - NLA_HDRLEN) 57*beb3c672SD. Wythe 58*beb3c672SD. Wythe #define SMC_GENL_FAMILY_NAME "SMC_GEN_NETLINK" 59*beb3c672SD. Wythe #define SMC_BPFTEST_UEID "SMC-BPFTEST-UEID" 60*beb3c672SD. Wythe 61*beb3c672SD. Wythe static uint16_t smc_nl_family_id = -1; 62*beb3c672SD. Wythe 63*beb3c672SD. Wythe static int send_cmd(int fd, __u16 nlmsg_type, __u32 nlmsg_pid, 64*beb3c672SD. Wythe __u16 nlmsg_flags, __u8 genl_cmd, __u16 nla_type, 65*beb3c672SD. Wythe void *nla_data, int nla_len) 66*beb3c672SD. Wythe { 67*beb3c672SD. Wythe struct nlattr *na; 68*beb3c672SD. Wythe struct sockaddr_nl nladdr; 69*beb3c672SD. Wythe int r, buflen; 70*beb3c672SD. Wythe char *buf; 71*beb3c672SD. Wythe 72*beb3c672SD. Wythe struct msgtemplate msg = {0}; 73*beb3c672SD. Wythe 74*beb3c672SD. Wythe msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); 75*beb3c672SD. Wythe msg.n.nlmsg_type = nlmsg_type; 76*beb3c672SD. Wythe msg.n.nlmsg_flags = nlmsg_flags; 77*beb3c672SD. Wythe msg.n.nlmsg_seq = 0; 78*beb3c672SD. Wythe msg.n.nlmsg_pid = nlmsg_pid; 79*beb3c672SD. Wythe msg.g.cmd = genl_cmd; 80*beb3c672SD. Wythe msg.g.version = 1; 81*beb3c672SD. Wythe na = (struct nlattr *)GENLMSG_DATA(&msg); 82*beb3c672SD. Wythe na->nla_type = nla_type; 83*beb3c672SD. Wythe na->nla_len = nla_len + 1 + NLA_HDRLEN; 84*beb3c672SD. Wythe memcpy(NLA_DATA(na), nla_data, nla_len); 85*beb3c672SD. Wythe msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len); 86*beb3c672SD. Wythe 87*beb3c672SD. Wythe buf = (char *)&msg; 88*beb3c672SD. Wythe buflen = msg.n.nlmsg_len; 89*beb3c672SD. Wythe memset(&nladdr, 0, sizeof(nladdr)); 90*beb3c672SD. Wythe nladdr.nl_family = AF_NETLINK; 91*beb3c672SD. Wythe 92*beb3c672SD. Wythe while ((r = sendto(fd, buf, buflen, 0, (struct sockaddr *)&nladdr, 93*beb3c672SD. Wythe sizeof(nladdr))) < buflen) { 94*beb3c672SD. Wythe if (r > 0) { 95*beb3c672SD. Wythe buf += r; 96*beb3c672SD. Wythe buflen -= r; 97*beb3c672SD. Wythe } else if (errno != EAGAIN) { 98*beb3c672SD. Wythe return -1; 99*beb3c672SD. Wythe } 100*beb3c672SD. Wythe } 101*beb3c672SD. Wythe return 0; 102*beb3c672SD. Wythe } 103*beb3c672SD. Wythe 104*beb3c672SD. Wythe static bool get_smc_nl_family_id(void) 105*beb3c672SD. Wythe { 106*beb3c672SD. Wythe struct sockaddr_nl nl_src; 107*beb3c672SD. Wythe struct msgtemplate msg; 108*beb3c672SD. Wythe struct nlattr *nl; 109*beb3c672SD. Wythe int fd, ret; 110*beb3c672SD. Wythe pid_t pid; 111*beb3c672SD. Wythe 112*beb3c672SD. Wythe fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); 113*beb3c672SD. Wythe if (!ASSERT_OK_FD(fd, "nl_family socket")) 114*beb3c672SD. Wythe return false; 115*beb3c672SD. Wythe 116*beb3c672SD. Wythe pid = getpid(); 117*beb3c672SD. Wythe 118*beb3c672SD. Wythe memset(&nl_src, 0, sizeof(nl_src)); 119*beb3c672SD. Wythe nl_src.nl_family = AF_NETLINK; 120*beb3c672SD. Wythe nl_src.nl_pid = pid; 121*beb3c672SD. Wythe 122*beb3c672SD. Wythe ret = bind(fd, (struct sockaddr *)&nl_src, sizeof(nl_src)); 123*beb3c672SD. Wythe if (!ASSERT_OK(ret, "nl_family bind")) 124*beb3c672SD. Wythe goto fail; 125*beb3c672SD. Wythe 126*beb3c672SD. Wythe ret = send_cmd(fd, GENL_ID_CTRL, pid, 127*beb3c672SD. Wythe NLM_F_REQUEST, CTRL_CMD_GETFAMILY, 128*beb3c672SD. Wythe CTRL_ATTR_FAMILY_NAME, (void *)SMC_GENL_FAMILY_NAME, 129*beb3c672SD. Wythe strlen(SMC_GENL_FAMILY_NAME)); 130*beb3c672SD. Wythe if (!ASSERT_OK(ret, "nl_family query")) 131*beb3c672SD. Wythe goto fail; 132*beb3c672SD. Wythe 133*beb3c672SD. Wythe ret = recv(fd, &msg, sizeof(msg), 0); 134*beb3c672SD. Wythe if (!ASSERT_FALSE(msg.n.nlmsg_type == NLMSG_ERROR || ret < 0 || 135*beb3c672SD. Wythe !NLMSG_OK(&msg.n, ret), "nl_family response")) 136*beb3c672SD. Wythe goto fail; 137*beb3c672SD. Wythe 138*beb3c672SD. Wythe nl = (struct nlattr *)GENLMSG_DATA(&msg); 139*beb3c672SD. Wythe nl = (struct nlattr *)((char *)nl + NLA_ALIGN(nl->nla_len)); 140*beb3c672SD. Wythe if (!ASSERT_EQ(nl->nla_type, CTRL_ATTR_FAMILY_ID, "nl_family nla type")) 141*beb3c672SD. Wythe goto fail; 142*beb3c672SD. Wythe 143*beb3c672SD. Wythe smc_nl_family_id = *(uint16_t *)NLA_DATA(nl); 144*beb3c672SD. Wythe close(fd); 145*beb3c672SD. Wythe return true; 146*beb3c672SD. Wythe fail: 147*beb3c672SD. Wythe close(fd); 148*beb3c672SD. Wythe return false; 149*beb3c672SD. Wythe } 150*beb3c672SD. Wythe 151*beb3c672SD. Wythe static bool smc_ueid(int op) 152*beb3c672SD. Wythe { 153*beb3c672SD. Wythe struct sockaddr_nl nl_src; 154*beb3c672SD. Wythe struct msgtemplate msg; 155*beb3c672SD. Wythe struct nlmsgerr *err; 156*beb3c672SD. Wythe char test_ueid[32]; 157*beb3c672SD. Wythe int fd, ret; 158*beb3c672SD. Wythe pid_t pid; 159*beb3c672SD. Wythe 160*beb3c672SD. Wythe /* UEID required */ 161*beb3c672SD. Wythe memset(test_ueid, '\x20', sizeof(test_ueid)); 162*beb3c672SD. Wythe memcpy(test_ueid, SMC_BPFTEST_UEID, strlen(SMC_BPFTEST_UEID)); 163*beb3c672SD. Wythe fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); 164*beb3c672SD. Wythe if (!ASSERT_OK_FD(fd, "ueid socket")) 165*beb3c672SD. Wythe return false; 166*beb3c672SD. Wythe 167*beb3c672SD. Wythe pid = getpid(); 168*beb3c672SD. Wythe memset(&nl_src, 0, sizeof(nl_src)); 169*beb3c672SD. Wythe nl_src.nl_family = AF_NETLINK; 170*beb3c672SD. Wythe nl_src.nl_pid = pid; 171*beb3c672SD. Wythe 172*beb3c672SD. Wythe ret = bind(fd, (struct sockaddr *)&nl_src, sizeof(nl_src)); 173*beb3c672SD. Wythe if (!ASSERT_OK(ret, "ueid bind")) 174*beb3c672SD. Wythe goto fail; 175*beb3c672SD. Wythe 176*beb3c672SD. Wythe ret = send_cmd(fd, smc_nl_family_id, pid, 177*beb3c672SD. Wythe NLM_F_REQUEST | NLM_F_ACK, op, SMC_NLA_EID_TABLE_ENTRY, 178*beb3c672SD. Wythe (void *)test_ueid, sizeof(test_ueid)); 179*beb3c672SD. Wythe if (!ASSERT_OK(ret, "ueid cmd")) 180*beb3c672SD. Wythe goto fail; 181*beb3c672SD. Wythe 182*beb3c672SD. Wythe ret = recv(fd, &msg, sizeof(msg), 0); 183*beb3c672SD. Wythe if (!ASSERT_FALSE(ret < 0 || 184*beb3c672SD. Wythe !NLMSG_OK(&msg.n, ret), "ueid response")) 185*beb3c672SD. Wythe goto fail; 186*beb3c672SD. Wythe 187*beb3c672SD. Wythe if (msg.n.nlmsg_type == NLMSG_ERROR) { 188*beb3c672SD. Wythe err = NLMSG_DATA(&msg); 189*beb3c672SD. Wythe switch (op) { 190*beb3c672SD. Wythe case SMC_NETLINK_REMOVE_UEID: 191*beb3c672SD. Wythe if (!ASSERT_FALSE((err->error && err->error != -ENOENT), 192*beb3c672SD. Wythe "ueid remove")) 193*beb3c672SD. Wythe goto fail; 194*beb3c672SD. Wythe break; 195*beb3c672SD. Wythe case SMC_NETLINK_ADD_UEID: 196*beb3c672SD. Wythe if (!ASSERT_OK(err->error, "ueid add")) 197*beb3c672SD. Wythe goto fail; 198*beb3c672SD. Wythe break; 199*beb3c672SD. Wythe default: 200*beb3c672SD. Wythe break; 201*beb3c672SD. Wythe } 202*beb3c672SD. Wythe } 203*beb3c672SD. Wythe close(fd); 204*beb3c672SD. Wythe return true; 205*beb3c672SD. Wythe fail: 206*beb3c672SD. Wythe close(fd); 207*beb3c672SD. Wythe return false; 208*beb3c672SD. Wythe } 209*beb3c672SD. Wythe 210*beb3c672SD. Wythe static bool setup_ueid(void) 211*beb3c672SD. Wythe { 212*beb3c672SD. Wythe /* get smc nl id */ 213*beb3c672SD. Wythe if (!get_smc_nl_family_id()) 214*beb3c672SD. Wythe return false; 215*beb3c672SD. Wythe /* clear old ueid for bpftest */ 216*beb3c672SD. Wythe smc_ueid(SMC_NETLINK_REMOVE_UEID); 217*beb3c672SD. Wythe /* smc-loopback required ueid */ 218*beb3c672SD. Wythe return smc_ueid(SMC_NETLINK_ADD_UEID); 219*beb3c672SD. Wythe } 220*beb3c672SD. Wythe 221*beb3c672SD. Wythe static void cleanup_ueid(void) 222*beb3c672SD. Wythe { 223*beb3c672SD. Wythe smc_ueid(SMC_NETLINK_REMOVE_UEID); 224*beb3c672SD. Wythe } 225*beb3c672SD. Wythe #endif /* __s390x__ */ 226*beb3c672SD. Wythe 227*beb3c672SD. Wythe static bool setup_netns(void) 228*beb3c672SD. Wythe { 229*beb3c672SD. Wythe test_netns = netns_new(TEST_NS, true); 230*beb3c672SD. Wythe if (!ASSERT_OK_PTR(test_netns, "open net namespace")) 231*beb3c672SD. Wythe goto fail_netns; 232*beb3c672SD. Wythe 233*beb3c672SD. Wythe SYS(fail_ip, "ip addr add 127.0.1.0/8 dev lo"); 234*beb3c672SD. Wythe SYS(fail_ip, "ip addr add 127.0.2.0/8 dev lo"); 235*beb3c672SD. Wythe 236*beb3c672SD. Wythe return true; 237*beb3c672SD. Wythe fail_ip: 238*beb3c672SD. Wythe netns_free(test_netns); 239*beb3c672SD. Wythe fail_netns: 240*beb3c672SD. Wythe return false; 241*beb3c672SD. Wythe } 242*beb3c672SD. Wythe 243*beb3c672SD. Wythe static void cleanup_netns(void) 244*beb3c672SD. Wythe { 245*beb3c672SD. Wythe netns_free(test_netns); 246*beb3c672SD. Wythe } 247*beb3c672SD. Wythe 248*beb3c672SD. Wythe static bool setup_smc(void) 249*beb3c672SD. Wythe { 250*beb3c672SD. Wythe if (!setup_ueid()) 251*beb3c672SD. Wythe return false; 252*beb3c672SD. Wythe 253*beb3c672SD. Wythe if (!setup_netns()) 254*beb3c672SD. Wythe goto fail_netns; 255*beb3c672SD. Wythe 256*beb3c672SD. Wythe return true; 257*beb3c672SD. Wythe fail_netns: 258*beb3c672SD. Wythe cleanup_ueid(); 259*beb3c672SD. Wythe return false; 260*beb3c672SD. Wythe } 261*beb3c672SD. Wythe 262*beb3c672SD. Wythe static int set_client_addr_cb(int fd, void *opts) 263*beb3c672SD. Wythe { 264*beb3c672SD. Wythe const char *src = (const char *)opts; 265*beb3c672SD. Wythe struct sockaddr_in localaddr; 266*beb3c672SD. Wythe 267*beb3c672SD. Wythe localaddr.sin_family = AF_INET; 268*beb3c672SD. Wythe localaddr.sin_port = htons(0); 269*beb3c672SD. Wythe localaddr.sin_addr.s_addr = inet_addr(src); 270*beb3c672SD. Wythe return !ASSERT_OK(bind(fd, &localaddr, sizeof(localaddr)), "client bind"); 271*beb3c672SD. Wythe } 272*beb3c672SD. Wythe 273*beb3c672SD. Wythe static void run_link(const char *src, const char *dst, int port) 274*beb3c672SD. Wythe { 275*beb3c672SD. Wythe struct network_helper_opts opts = {0}; 276*beb3c672SD. Wythe int server, client; 277*beb3c672SD. Wythe 278*beb3c672SD. Wythe server = start_server_str(AF_INET, SOCK_STREAM, dst, port, NULL); 279*beb3c672SD. Wythe if (!ASSERT_OK_FD(server, "start service_1")) 280*beb3c672SD. Wythe return; 281*beb3c672SD. Wythe 282*beb3c672SD. Wythe opts.proto = IPPROTO_TCP; 283*beb3c672SD. Wythe opts.post_socket_cb = set_client_addr_cb; 284*beb3c672SD. Wythe opts.cb_opts = (void *)src; 285*beb3c672SD. Wythe 286*beb3c672SD. Wythe client = connect_to_fd_opts(server, &opts); 287*beb3c672SD. Wythe if (!ASSERT_OK_FD(client, "start connect")) 288*beb3c672SD. Wythe goto fail_client; 289*beb3c672SD. Wythe 290*beb3c672SD. Wythe close(client); 291*beb3c672SD. Wythe fail_client: 292*beb3c672SD. Wythe close(server); 293*beb3c672SD. Wythe } 294*beb3c672SD. Wythe 295*beb3c672SD. Wythe static void block_link(int map_fd, const char *src, const char *dst) 296*beb3c672SD. Wythe { 297*beb3c672SD. Wythe struct smc_policy_ip_value val = { .mode = /* block */ 0 }; 298*beb3c672SD. Wythe struct smc_policy_ip_key key = { 299*beb3c672SD. Wythe .sip = inet_addr(src), 300*beb3c672SD. Wythe .dip = inet_addr(dst), 301*beb3c672SD. Wythe }; 302*beb3c672SD. Wythe 303*beb3c672SD. Wythe bpf_map_update_elem(map_fd, &key, &val, BPF_ANY); 304*beb3c672SD. Wythe } 305*beb3c672SD. Wythe 306*beb3c672SD. Wythe /* 307*beb3c672SD. Wythe * This test describes a real-life service topology as follows: 308*beb3c672SD. Wythe * 309*beb3c672SD. Wythe * +-------------> service_1 310*beb3c672SD. Wythe * link 1 | | 311*beb3c672SD. Wythe * +--------------------> server | link 2 312*beb3c672SD. Wythe * | | V 313*beb3c672SD. Wythe * | +-------------> service_2 314*beb3c672SD. Wythe * | link 3 315*beb3c672SD. Wythe * client -------------------> server_via_unsafe_path -> service_3 316*beb3c672SD. Wythe * 317*beb3c672SD. Wythe * Among them, 318*beb3c672SD. Wythe * 1. link-1 is very suitable for using SMC. 319*beb3c672SD. Wythe * 2. link-2 is not suitable for using SMC, because the mode of this link is 320*beb3c672SD. Wythe * kind of short-link services. 321*beb3c672SD. Wythe * 3. link-3 is also not suitable for using SMC, because the RDMA link is 322*beb3c672SD. Wythe * unavailable and needs to go through a long timeout before it can fallback 323*beb3c672SD. Wythe * to TCP. 324*beb3c672SD. Wythe * To achieve this goal, we use a customized SMC ip strategy via smc_hs_ctrl. 325*beb3c672SD. Wythe */ 326*beb3c672SD. Wythe static void test_topo(void) 327*beb3c672SD. Wythe { 328*beb3c672SD. Wythe struct bpf_smc *skel; 329*beb3c672SD. Wythe int rc, map_fd; 330*beb3c672SD. Wythe 331*beb3c672SD. Wythe skel = bpf_smc__open_and_load(); 332*beb3c672SD. Wythe if (!ASSERT_OK_PTR(skel, "bpf_smc__open_and_load")) 333*beb3c672SD. Wythe return; 334*beb3c672SD. Wythe 335*beb3c672SD. Wythe rc = bpf_smc__attach(skel); 336*beb3c672SD. Wythe if (!ASSERT_OK(rc, "bpf_smc__attach")) 337*beb3c672SD. Wythe goto fail; 338*beb3c672SD. Wythe 339*beb3c672SD. Wythe map_fd = bpf_map__fd(skel->maps.smc_policy_ip); 340*beb3c672SD. Wythe if (!ASSERT_OK_FD(map_fd, "bpf_map__fd")) 341*beb3c672SD. Wythe goto fail; 342*beb3c672SD. Wythe 343*beb3c672SD. Wythe /* Mock the process of transparent replacement, since we will modify 344*beb3c672SD. Wythe * protocol to ipproto_smc accropding to it via 345*beb3c672SD. Wythe * fmod_ret/update_socket_protocol. 346*beb3c672SD. Wythe */ 347*beb3c672SD. Wythe write_sysctl("/proc/sys/net/smc/hs_ctrl", "linkcheck"); 348*beb3c672SD. Wythe 349*beb3c672SD. Wythe /* Configure ip strat */ 350*beb3c672SD. Wythe block_link(map_fd, CLIENT_IP, SERVER_IP_VIA_RISK_PATH); 351*beb3c672SD. Wythe block_link(map_fd, SERVER_IP, SERVER_IP); 352*beb3c672SD. Wythe 353*beb3c672SD. Wythe /* should go with smc */ 354*beb3c672SD. Wythe run_link(CLIENT_IP, SERVER_IP, SERVICE_1); 355*beb3c672SD. Wythe /* should go with smc fallback */ 356*beb3c672SD. Wythe run_link(SERVER_IP, SERVER_IP, SERVICE_2); 357*beb3c672SD. Wythe 358*beb3c672SD. Wythe ASSERT_EQ(skel->bss->smc_cnt, 2, "smc count"); 359*beb3c672SD. Wythe ASSERT_EQ(skel->bss->fallback_cnt, 1, "fallback count"); 360*beb3c672SD. Wythe 361*beb3c672SD. Wythe /* should go with smc */ 362*beb3c672SD. Wythe run_link(CLIENT_IP, SERVER_IP, SERVICE_2); 363*beb3c672SD. Wythe 364*beb3c672SD. Wythe ASSERT_EQ(skel->bss->smc_cnt, 3, "smc count"); 365*beb3c672SD. Wythe ASSERT_EQ(skel->bss->fallback_cnt, 1, "fallback count"); 366*beb3c672SD. Wythe 367*beb3c672SD. Wythe /* should go with smc fallback */ 368*beb3c672SD. Wythe run_link(CLIENT_IP, SERVER_IP_VIA_RISK_PATH, SERVICE_3); 369*beb3c672SD. Wythe 370*beb3c672SD. Wythe ASSERT_EQ(skel->bss->smc_cnt, 4, "smc count"); 371*beb3c672SD. Wythe ASSERT_EQ(skel->bss->fallback_cnt, 2, "fallback count"); 372*beb3c672SD. Wythe 373*beb3c672SD. Wythe fail: 374*beb3c672SD. Wythe bpf_smc__destroy(skel); 375*beb3c672SD. Wythe } 376*beb3c672SD. Wythe 377*beb3c672SD. Wythe void test_bpf_smc(void) 378*beb3c672SD. Wythe { 379*beb3c672SD. Wythe if (!setup_smc()) { 380*beb3c672SD. Wythe printf("setup for smc test failed, test SKIP:\n"); 381*beb3c672SD. Wythe test__skip(); 382*beb3c672SD. Wythe return; 383*beb3c672SD. Wythe } 384*beb3c672SD. Wythe 385*beb3c672SD. Wythe if (test__start_subtest("topo")) 386*beb3c672SD. Wythe test_topo(); 387*beb3c672SD. Wythe 388*beb3c672SD. Wythe cleanup_ueid(); 389*beb3c672SD. Wythe cleanup_netns(); 390*beb3c672SD. Wythe } 391